From c442239a9d2bb98eb73794a5e168624e55bb6649 Mon Sep 17 00:00:00 2001 From: zhangbin <460190368@qq.com> Date: Wed, 13 Nov 2024 09:19:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CodeSmith/CSharp/ApiGenerate.cst | 226 + CodeSmith/CSharp/ApiGenerate/Application.cst | 157 + CodeSmith/CSharp/ApiGenerate/Controller.cst | 128 + CodeSmith/CSharp/ApiGenerate/ModifyReq.cst | 66 + CodeSmith/CSharp/ApiGenerate/Request.cst | 17 + .../CSharp/Internal/Context.Generated.cst | 81 + .../CSharp/Internal/Entity.Generated.cst | 75 + CodeSmith/CSharp/Internal/Extensions.cs | 187 + CodeSmith/CSharp/Internal/Generator.cs | 837 + CodeSmith/CSharp/Internal/Model.cs | 370 + CodeSmith/CSharp/Internal/Parser.cs | 639 + CodeSmith/CSharp/Web/Controller.cst | 105 + CodeSmith/CSharp/Web/Index.cshtml.cst | 98 + CodeSmith/CSharp/Web/Util.cs | 39 + CodeSmith/CSharp/Web/index.js.cst | 186 + CodeSmith/CSharp/WebGenerate.cst | 130 + .../Common/ICSharpCode.NRefactory.CSharp.dll | Bin 0 -> 2179072 bytes CodeSmith/Common/ICSharpCode.NRefactory.dll | Bin 0 -> 311296 bytes CodeSmith/Common/Mono.Cecil.dll | Bin 0 -> 275968 bytes Dockerfile | 36 + Infrastructure/AppSetting.cs | 55 + Infrastructure/AutoMapperExt.cs | 74 + Infrastructure/Cache/CacheContext.cs | 88 + Infrastructure/Cache/EnyimMemcachedContext.cs | 55 + Infrastructure/Cache/ICacheContext.cs | 36 + Infrastructure/Cache/RedisCacheContext.cs | 63 + Infrastructure/CommonException.cs | 22 + Infrastructure/Const/FlowInstanceStatus.cs | 30 + Infrastructure/Const/HtmlElementType.cs | 26 + Infrastructure/Const/JobStatus.cs | 17 + Infrastructure/Const/LinqExpressionType.cs | 15 + Infrastructure/Const/QueryOrderBy.cs | 8 + Infrastructure/Const/ResponseType.cs | 27 + Infrastructure/Const/SqlDbTypeName.cs | 24 + .../Database/DbDataConvertExtensions.cs | 412 + Infrastructure/Define.cs | 38 + Infrastructure/DynamicLinq.cs | 306 + Infrastructure/DynamicQueryable.cs | 2079 ++ Infrastructure/Encryption.cs | 59 + .../AutofacManager/AutofacContainerModule.cs | 22 + .../Extensions/AutofacManager/IDependency.cs | 9 + .../Extensions/ConvertJsonExtension.cs | 377 + .../Extensions/DateTimeExtension.cs | 52 + Infrastructure/Extensions/EntityProperties.cs | 1349 + .../Extensions/EnumTypeExtention.cs | 65 + Infrastructure/Extensions/ExtensionsJson.cs | 22 + Infrastructure/Extensions/GenericExtension.cs | 105 + Infrastructure/Extensions/LambdaExtensions.cs | 504 + Infrastructure/Extensions/ObjectExtension.cs | 1490 + .../Extensions/SecurityEncDecryptExtension.cs | 86 + Infrastructure/Extensions/ServerExtension.cs | 28 + Infrastructure/Extensions/StringExtension.cs | 867 + Infrastructure/Filter.cs | 25 + Infrastructure/GenerateId.cs | 126 + Infrastructure/Helpers/AESHelper.cs | 97 + Infrastructure/Helpers/CommonHelper.cs | 122 + Infrastructure/Helpers/ConfigHelper.cs | 23 + Infrastructure/Helpers/DateTimeHelper.cs | 42 + Infrastructure/Helpers/Excel/ExcelConfig.cs | 122 + Infrastructure/Helpers/Excel/ExcelHelper.cs | 505 + .../Helpers/Excel/Model/ColumnModel.cs | 55 + Infrastructure/Helpers/FileHelper.cs | 407 + Infrastructure/Helpers/GenericHelper.cs | 76 + Infrastructure/Helpers/HIKOpenAPI.cs | 478 + Infrastructure/Helpers/HttpHelper.cs | 175 + Infrastructure/Helpers/HttpMethods.cs | 103 + Infrastructure/Helpers/ImageHelper.cs | 34 + Infrastructure/Helpers/ImgHelper.cs | 50 + Infrastructure/Helpers/Md5.cs | 31 + Infrastructure/Helpers/Md5Helper.cs | 58 + Infrastructure/Helpers/ObjectHelper.cs | 65 + Infrastructure/Helpers/WordHelper.cs | 347 + Infrastructure/Helpers/XmlHelper.cs | 710 + Infrastructure/Infrastructure.csproj | 39 + Infrastructure/Json.cs | 83 + Infrastructure/JsonConverter.cs | 61 + Infrastructure/JsonHelper.cs | 55 + Infrastructure/KeyDescription.cs | 24 + .../IApplicationBuilderExtension.cs | 20 + .../RequestResponseLoggingMiddleware.cs | 172 + Infrastructure/PredicateBuilder.cs | 28 + Infrastructure/Provider/PathProvider.cs | 52 + Infrastructure/Response.cs | 45 + .../Snowflake/Contract/IIdGenerator.cs | 29 + .../Snowflake/Contract/ISnowWorker.cs | 22 + .../Snowflake/Contract/IdGeneratorOptions.cs | 92 + .../Snowflake/Contract/OverCostActionArg.cs | 57 + Infrastructure/Snowflake/Core/SnowWorkerM1.cs | 379 + Infrastructure/Snowflake/Core/SnowWorkerM2.cs | 58 + Infrastructure/Snowflake/Core/SnowWorkerM3.cs | 83 + .../Snowflake/DefaultIdGenerator.cs | 130 + Infrastructure/Snowflake/YitIdHelper.cs | 53 + Infrastructure/Test/TestAutoMapper.cs | 50 + Infrastructure/Test/TestDynamicLinq.cs | 54 + Infrastructure/Test/TestSnowflake.cs | 29 + Infrastructure/TreeItem.cs | 10 + Infrastructure/Utilities/DESEncrypt.cs | 104 + .../Utilities/DynamicPropertyBag .cs | 43 + Infrastructure/Utilities/HttpContextUtil.cs | 40 + Infrastructure/Utilities/HttpManager.cs | 70 + Infrastructure/Utilities/ProjectPath.cs | 64 + Infrastructure/Utilities/ResponseMsg.cs | 59 + Infrastructure/Utilities/UriUtil.cs | 62 + .../Utilities/WebResponseContent.cs | 81 + Infrastructure/log4net.config | 57 + OpenAuth.App/AuthContextFactory.cs | 48 + OpenAuth.App/AutofacExt.cs | 104 + OpenAuth.App/BaseApp/AppManager/AppManager.cs | 57 + .../AppManager/Request/QueryAppListReq.cs | 7 + .../AuthStrategies/AuthStrategyContext.cs | 56 + .../AuthStrategies/NormalAuthStrategy.cs | 123 + .../AuthStrategies/SystemAuthStrategy.cs | 83 + OpenAuth.App/BaseApp/Base/IdRequest.cs | 14 + OpenAuth.App/BaseApp/Base/PageReq.cs | 24 + OpenAuth.App/BaseApp/Base/SqlSugarBaseApp.cs | 122 + OpenAuth.App/BaseApp/Base/TableData.cs | 33 + OpenAuth.App/BaseApp/Base/TableResp.cs | 42 + OpenAuth.App/BaseApp/Base/Tree/LongTreeApp.cs | 31 + .../BaseApp/Base/Tree/StringTreeApp.cs | 35 + OpenAuth.App/BaseApp/Base/Tree/TreeApp.cs | 146 + .../BaseApp/Base/Tree/TreeExtensions.cs | 53 + .../BasicQueryService/CommonDataManager.cs | 365 + .../BasicQueryService/PositionManager.cs | 187 + .../Request/QueryGeoJsonCommonReq.cs | 28 + .../Request/QueryVectorTileByTableReq.cs | 21 + .../Request/VectorTileSearchModel.cs | 29 + .../BaseApp/BasicQueryService/UserManager.cs | 162 + .../BasicQueryService/WorkFlowMangaer.cs | 83 + OpenAuth.App/BaseApp/Category/CategoryApp.cs | 117 + .../BaseApp/Category/CategoryTypeApp.cs | 73 + .../Request/AddOrUpdateCategoryReq.cs | 51 + .../Request/AddOrUpdateCategoryTypeReq.cs | 31 + .../Category/Request/QueryCategoryListReq.cs | 11 + .../Request/QueryCategoryTypeListReq.cs | 7 + .../Category/Response/CategoryTypeResp.cs | 10 + .../BaseApp/CodeTable/CodeColumnsApp.cs | 74 + .../BaseApp/CodeTable/CodeTableApp.cs | 277 + .../BaseApp/CodeTable/Request/CodeTableReq.cs | 27 + .../Response/CodeTableColumnsResp.cs | 19 + .../BaseApp/CreateTable/BasicTableService.cs | 211 + .../BaseApp/CreateTable/CreateTableReq.cs | 20 + .../BaseApp/CreateTable/CreateViewReq.cs | 19 + OpenAuth.App/BaseApp/CreateTable/TableInfo.cs | 44 + .../BaseApp/CreateTable/TableRecordApp.cs | 41 + .../BaseApp/CreateTable/UploadExcelReq.cs | 17 + .../BaseApp/DataCodeRule/CodeRuleApp.cs | 245 + .../Response/CodeRuleFormatModel.cs | 42 + .../BaseApp/DataSource/DataSourceApp.cs | 173 + OpenAuth.App/BaseApp/DbTable/DbTableApp.cs | 99 + .../BaseApp/DbTable/Request/DbColumnInput.cs | 29 + .../BaseApp/DbTable/Request/DbTableReq.cs | 17 + OpenAuth.App/BaseApp/Extensions/OpenJobExt.cs | 55 + OpenAuth.App/BaseApp/Files/FileApp.cs | 215 + .../BaseApp/Files/Request/QueryFileListReq.cs | 7 + .../BaseApp/FormModule/FormModuleApp.cs | 703 + .../FormModule/Request/FormModuleReq.cs | 38 + .../FormModule/Request/FormModuleSchemeReq.cs | 21 + .../FormScheme/FormHelpers/DBCommonHelper.cs | 312 + .../FormScheme/FormHelpers/FormHelper.cs | 1444 + .../BaseApp/FormScheme/FormSchemeApp.cs | 1776 + .../BaseApp/FormScheme/Request/FormDataReq.cs | 37 + .../FormScheme/Request/FormQueryReq.cs | 30 + .../FormScheme/Request/FormSchemeReq.cs | 24 + .../Response/ComponentPropsModel.cs | 20 + .../FormScheme/Response/ExecuteType.cs | 28 + .../FormScheme/Response/FormComponentModel.cs | 52 + .../Response/FormComponentNewModel.cs | 53 + .../FormScheme/Response/FormDbTable.cs | 41 + .../FormScheme/Response/FormDbTableInfo.cs | 57 + .../FormScheme/Response/FormInfoModel.cs | 21 + .../FormScheme/Response/FormInfoNewModel.cs | 17 + .../FormScheme/Response/FormSchemeModel.cs | 31 + .../FormScheme/Response/FormSchemeNewModel.cs | 28 + .../FormScheme/Response/FormTabModel.cs | 19 + .../FormScheme/Response/FormTabNewModel.cs | 16 + .../FormScheme/Response/PaginationInputDto.cs | 31 + .../BaseApp/HostedService/QuartzService.cs | 49 + OpenAuth.App/BaseApp/ImMsgManager/ChatsHub.cs | 79 + OpenAuth.App/BaseApp/ImMsgManager/ImMsgApp.cs | 303 + .../BaseApp/ImMsgManager/Request/ImMsgReq.cs | 62 + OpenAuth.App/BaseApp/ImMsgManager/SendHubs.cs | 42 + OpenAuth.App/BaseApp/Import/ImportApp.cs | 337 + .../BaseApp/Import/Response/ExcelImportDto.cs | 24 + OpenAuth.App/BaseApp/Interface/IAuth.cs | 45 + .../BaseApp/Interface/IAuthStrategy.cs | 28 + .../BaseApp/Interface/ICustomerForm.cs | 23 + OpenAuth.App/BaseApp/Jobs/OpenJobApp.cs | 241 + .../Jobs/Request/AddOrUpdateOpenJobReq.cs | 59 + .../Jobs/Request/ChangeJobStatusReq.cs | 16 + .../Jobs/Request/QueryOpenJobListReq.cs | 7 + OpenAuth.App/BaseApp/Jobs/SysLogJob.cs | 26 + OpenAuth.App/BaseApp/Jobs/TaskOverTimeJob.cs | 78 + OpenAuth.App/BaseApp/Jobs/TaskTimeoutJob.cs | 80 + .../BaseApp/ModuleManager/ModuleManagerApp.cs | 286 + .../Request/QueryElementListReq.cs | 14 + .../ModuleManager/Response/ModuleElementVM.cs | 49 + .../ModuleManager/Response/ModuleView.cs | 84 + .../Response/ModulesWithElements.cs | 15 + .../BaseApp/OrgManager/OrgManagerApp.cs | 633 + .../OrgManager/Request/AssignOrgPosGroup.cs | 15 + .../BaseApp/OrgManager/Request/OrgForm.cs | 19 + .../BaseApp/OrgManager/Request/OrgPos.cs | 17 + .../OrgManager/Request/QueryOrgListReq.cs | 14 + .../Permission/BaseDataAuthorizeApp.cs | 507 + .../Permission/Request/BaseDataAuthListReq.cs | 16 + .../Permission/Request/BaseDataAuthReq.cs | 53 + .../BaseApp/Permission/Request/Condition.cs | 77 + .../Permission/Request/FormulaObject.cs | 28 + .../BaseApp/Permission/Request/Group.cs | 9 + .../Relevance/Request/AssignDataReq.cs | 21 + .../Relevance/Request/AssignOrgUsers.cs | 17 + .../BaseApp/Relevance/Request/AssignReq.cs | 18 + .../Relevance/Request/AssignRoleUsers.cs | 17 + .../BaseApp/Relevance/RevelanceManagerApp.cs | 240 + .../Resources/Request/AddOrUpdateResReq.cs | 64 + .../Resources/Request/QueryResourcesReq.cs | 11 + OpenAuth.App/BaseApp/Resources/ResourceApp.cs | 74 + .../Request/ModuleElementWithRole.cs | 15 + .../RoleManager/Request/QueryRoleListReq.cs | 6 + .../BaseApp/RoleManager/Response/RoleView.cs | 60 + OpenAuth.App/BaseApp/RoleManager/RoleApp.cs | 179 + OpenAuth.App/BaseApp/SSO/LocalAuth.cs | 242 + OpenAuth.App/BaseApp/SSO/LoginParse.cs | 104 + OpenAuth.App/BaseApp/SSO/LoginResult.cs | 17 + .../BaseApp/SSO/PassportLoginRequest.cs | 37 + OpenAuth.App/BaseApp/SSO/UserAuthSession.cs | 30 + .../BaseApp/SysAppFiles/SysAppFilesApp.cs | 105 + .../BaseApp/SysDataItem/SysDataItemApp.cs | 84 + .../SysDataItemDetail/SysDataItemDetailApp.cs | 109 + .../SysDatabaseLink/Response/TreeModel.cs | 71 + .../SysDatabaseLink/SysDatabaseLinkApp.cs | 241 + .../SysLogs/Request/QuerySysLogListReq.cs | 7 + OpenAuth.App/BaseApp/SysLogs/SysLogApp.cs | 61 + .../Request/QuerySysMessageListReq.cs | 10 + .../BaseApp/SysMessage/SysMessageApp.cs | 130 + .../SysPosGroup/Request/PosGroupForm.cs | 13 + .../BaseApp/SysPosGroup/SysPosGroupApp.cs | 54 + .../Request/QueryPositonListReq.cs | 14 + .../BaseApp/SysPosition/SysPositionApp.cs | 137 + .../UserManager/Request/AssignUserOrgs.cs | 14 + .../UserManager/Request/AssignUserRoles.cs | 15 + .../UserManager/Request/ChangePasswordReq.cs | 8 + .../UserManager/Request/ChangeProfileReq.cs | 16 + .../Request/QueryUserListByOrgReq.cs | 7 + .../Request/QueryUserListByRoleReq.cs | 7 + .../UserManager/Request/QueryUserListReq.cs | 7 + .../UserManager/Request/UpdateUserReq.cs | 67 + .../BaseApp/UserManager/Response/UserView.cs | 85 + .../BaseApp/UserManager/UserManagerApp.cs | 669 + .../WFDelegate/Request/WFDelegateDto.cs | 22 + .../BaseApp/WFDelegate/WFDelegateApp.cs | 203 + .../BaseApp/WFProcess/Config/WFDelegate.cs | 54 + .../WFProcess/Config/WFEngineConfig.cs | 42 + .../BaseApp/WFProcess/Config/WFParams.cs | 83 + .../BaseApp/WFProcess/Config/WFUserInfo.cs | 66 + OpenAuth.App/BaseApp/WFProcess/IWFEngine.cs | 59 + .../BaseApp/WFProcess/IWorkFlowMethod.cs | 18 + .../BaseApp/WFProcess/NodeTypeEnum.cs | 29 + .../BaseApp/WFProcess/Request/WFProcessDto.cs | 81 + .../WFProcess/Request/WFProcessPointDto.cs | 25 + .../WFProcess/Request/WFProcessSearchDto.cs | 71 + .../WFProcess/Response/BPMNWFTaskDto.cs | 48 + OpenAuth.App/BaseApp/WFProcess/WFAuditor.cs | 47 + OpenAuth.App/BaseApp/WFProcess/WFCondition.cs | 55 + OpenAuth.App/BaseApp/WFProcess/WFEngine.cs | 1106 + .../BaseApp/WFProcess/WFProcessApp.cs | 3161 ++ .../BaseApp/WFProcess/WFProcessApp1.cs | 239 + OpenAuth.App/BaseApp/WFProcess/WFScheme.cs | 82 + OpenAuth.App/BaseApp/WFProcess/WFTask.cs | 113 + OpenAuth.App/BaseApp/WFProcess/WFUnit.cs | 170 + .../BaseApp/WFProcess/WfMethodParameter.cs | 49 + .../WFSchemeInfo/Response/WFSchemeDto.cs | 25 + .../BaseApp/WFSchemeInfo/WFSchemeApp.cs | 57 + .../BaseApp/WFSchemeInfo/WFSchemeInfoApp.cs | 292 + OpenAuth.App/BaseApp/WFStamp/WFStampApp.cs | 170 + .../BaseApp/WFTask/Request/WFTaskDto.cs | 33 + .../BaseApp/WFTask/Response/ExtendInfo.cs | 9 + .../BaseApp/WFTask/Response/RetractRes.cs | 14 + OpenAuth.App/BaseApp/WFTask/WFTaskApp.cs | 935 + OpenAuth.App/Common/CommonData.cs | 45 + OpenAuth.App/Const/TubanZhuanTi.cs | 15 + OpenAuth.App/DbExtension.cs | 53 + OpenAuth.App/OpenAuth.App.csproj | 54 + OpenAuth.Identity/Config.cs | 69 + OpenAuth.Identity/CustomProfileService.cs | 101 + .../OpenAuth.IdentityServer.csproj | 34 + OpenAuth.Identity/Program.cs | 43 + .../Properties/launchSettings.json | 13 + .../Quickstart/Account/AccountController.cs | 384 + .../Quickstart/Account/AccountOptions.cs | 25 + .../Quickstart/Account/ExternalController.cs | 251 + .../Quickstart/Account/ExternalProvider.cs | 12 + .../Quickstart/Account/LoggedOutViewModel.cs | 19 + .../Quickstart/Account/LoginInputModel.cs | 18 + .../Quickstart/Account/LoginViewModel.cs | 22 + .../Quickstart/Account/LogoutInputModel.cs | 11 + .../Quickstart/Account/LogoutViewModel.cs | 11 + .../Quickstart/Account/RedirectViewModel.cs | 12 + .../Quickstart/Consent/ConsentController.cs | 266 + .../Quickstart/Consent/ConsentInputModel.cs | 16 + .../Quickstart/Consent/ConsentOptions.cs | 16 + .../Quickstart/Consent/ConsentViewModel.cs | 19 + .../Consent/ProcessConsentResult.cs | 19 + .../Quickstart/Consent/ScopeViewModel.cs | 16 + .../Device/DeviceAuthorizationInputModel.cs | 13 + .../Device/DeviceAuthorizationViewModel.cs | 14 + .../Quickstart/Device/DeviceController.cs | 243 + .../Diagnostics/DiagnosticsController.cs | 29 + .../Diagnostics/DiagnosticsViewModel.cs | 32 + OpenAuth.Identity/Quickstart/Extensions.cs | 25 + .../Quickstart/Grants/GrantsController.cs | 96 + .../Quickstart/Grants/GrantsViewModel.cs | 26 + .../Quickstart/Home/ErrorViewModel.cs | 22 + .../Quickstart/Home/HomeController.cs | 64 + .../Quickstart/SecurityHeadersAttribute.cs | 56 + OpenAuth.Identity/Quickstart/TestUsers.cs | 27 + ...eSiteCookiesServiceCollectionExtensions.cs | 136 + OpenAuth.Identity/Startup.cs | 81 + .../Views/Account/AccessDenied.cshtml | 8 + .../Views/Account/LoggedOut.cshtml | 34 + OpenAuth.Identity/Views/Account/Login.cshtml | 92 + OpenAuth.Identity/Views/Account/Logout.cshtml | 21 + OpenAuth.Identity/Views/Consent/Index.cshtml | 82 + OpenAuth.Identity/Views/Device/Success.cshtml | 6 + .../Views/Device/UserCodeCapture.cshtml | 14 + .../Views/Device/UserCodeConfirmation.cshtml | 93 + .../Views/Diagnostics/Index.cshtml | 32 + OpenAuth.Identity/Views/Grants/Index.cshtml | 79 + OpenAuth.Identity/Views/Home/Index.cshtml | 39 + OpenAuth.Identity/Views/Shared/Error.cshtml | 40 + .../Views/Shared/Redirect.cshtml | 7 + OpenAuth.Identity/Views/Shared/_Layout.cshtml | 72 + .../Views/Shared/_ScopeListItem.cshtml | 34 + .../Views/Shared/_ValidationSummary.cshtml | 7 + OpenAuth.Identity/Views/_ViewImports.cshtml | 1 + OpenAuth.Identity/Views/_ViewStart.cshtml | 3 + .../appsettings.Development.json | 9 + OpenAuth.Identity/appsettings.Production.json | 16 + OpenAuth.Identity/appsettings.json | 11 + OpenAuth.Identity/tempkey.jwk | 1 + OpenAuth.Identity/tempkey.rsa | 1 + OpenAuth.Identity/wwwroot/css/site.css | 82 + OpenAuth.Identity/wwwroot/css/site.less | 116 + OpenAuth.Identity/wwwroot/css/site.min.css | 1 + OpenAuth.Identity/wwwroot/favicon.ico | Bin 0 -> 1150 bytes OpenAuth.Identity/wwwroot/icon.jpg | Bin 0 -> 19482 bytes OpenAuth.Identity/wwwroot/icon.png | Bin 0 -> 20796 bytes .../wwwroot/js/signin-redirect.js | 1 + .../wwwroot/js/signout-redirect.js | 6 + .../lib/bootstrap/css/bootstrap-ie6.css | 5773 +++ .../lib/bootstrap/css/bootstrap-ie6.min.css | 1 + .../bootstrap/css/bootstrap-responsive.css | 1109 + .../css/bootstrap-responsive.min.css | 9 + .../lib/bootstrap/css/bootstrap-theme.css | 587 + .../lib/bootstrap/css/bootstrap-theme.css.map | 1 + .../lib/bootstrap/css/bootstrap-theme.min.css | 6 + .../bootstrap/css/bootstrap-theme.min.css.map | 1 + .../wwwroot/lib/bootstrap/css/bootstrap.css | 6800 ++++ .../lib/bootstrap/css/bootstrap.css.map | 1 + .../lib/bootstrap/css/bootstrap.min.css | 5 + .../lib/bootstrap/css/bootstrap.min.css.map | 1 + .../wwwroot/lib/bootstrap/css/ie.css | 59 + .../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 .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../bootstrap/img/glyphicons-halflings.png | Bin 0 -> 12799 bytes .../wwwroot/lib/bootstrap/js/bootstrap.js | 2363 ++ .../wwwroot/lib/bootstrap/js/bootstrap.min.js | 7 + .../wwwroot/lib/bootstrap/js/npm.js | 13 + .../wwwroot/lib/jquery/jquery.js | 9210 +++++ .../wwwroot/lib/jquery/jquery.min.js | 5 + .../wwwroot/lib/jquery/jquery.min.map | 1 + .../Controllers/AccessObjsController.cs | 144 + .../Controllers/ApplicationsController.cs | 87 + OpenAuth.Mvc/Controllers/BaseController.cs | 33 + .../Controllers/CategoriesController.cs | 99 + OpenAuth.Mvc/Controllers/ErrorController.cs | 41 + OpenAuth.Mvc/Controllers/FilesController.cs | 47 + OpenAuth.Mvc/Controllers/HomeController.cs | 30 + OpenAuth.Mvc/Controllers/LoginController.cs | 69 + .../Controllers/ModuleManagerController.cs | 231 + .../Controllers/OpenJobsController.cs | 132 + .../Controllers/OrgManagerController.cs | 90 + .../Controllers/RedirectsController.cs | 20 + .../Controllers/ResourcesController.cs | 107 + .../Controllers/RoleManagerController.cs | 130 + OpenAuth.Mvc/Controllers/SysConfController.cs | 36 + OpenAuth.Mvc/Controllers/SysLogsController.cs | 86 + .../Controllers/SysMessagesController.cs | 92 + .../Controllers/UserManagerController.cs | 152 + .../Controllers/UserSessionController.cs | 150 + OpenAuth.Mvc/Models/JobjectModelBinder.cs | 39 + OpenAuth.Mvc/Models/JsonBinderProvider.cs | 26 + OpenAuth.Mvc/Models/OpenAuthFilter.cs | 91 + OpenAuth.Mvc/OpenAuth.Mvc.csproj | 505 + OpenAuth.Mvc/Program.cs | 33 + OpenAuth.Mvc/Properties/launchSettings.json | 12 + OpenAuth.Mvc/Startup.cs | 168 + OpenAuth.Mvc/Views/Categories/Index.cshtml | 66 + OpenAuth.Mvc/Views/Error/Auth.cshtml | 13 + OpenAuth.Mvc/Views/Home/Index.cshtml | 114 + OpenAuth.Mvc/Views/Home/Main.cshtml | 10 + OpenAuth.Mvc/Views/Login/Index.cshtml | 67 + .../Views/ModuleManager/Assign.cshtml | 44 + OpenAuth.Mvc/Views/ModuleManager/Index.cshtml | 216 + OpenAuth.Mvc/Views/OpenJobs/index.cshtml | 97 + OpenAuth.Mvc/Views/OrgManager/Index.cshtml | 79 + .../Views/Redirects/IdentityAuth.cshtml | 1 + OpenAuth.Mvc/Views/Resources/Assign.cshtml | 33 + OpenAuth.Mvc/Views/Resources/Index.cshtml | 73 + OpenAuth.Mvc/Views/RoleManager/Assign.cshtml | 23 + OpenAuth.Mvc/Views/RoleManager/Index.cshtml | 69 + OpenAuth.Mvc/Views/Shared/_Layout.cshtml | 74 + OpenAuth.Mvc/Views/SysLogs/index.cshtml | 28 + OpenAuth.Mvc/Views/SysMessages/index.cshtml | 33 + .../Views/UserManager/ChangePassword.cshtml | 42 + OpenAuth.Mvc/Views/UserManager/Index.cshtml | 121 + OpenAuth.Mvc/Views/UserManager/Profile.cshtml | 67 + OpenAuth.Mvc/Views/_ViewStart.cshtml | 3 + OpenAuth.Mvc/appsettings.Development.json | 10 + OpenAuth.Mvc/appsettings.Production.json | 23 + OpenAuth.Mvc/appsettings.json | 27 + ...y-0833ae4d-c4cc-464d-870e-4870f64321db.xml | 16 + ...y-628839e2-4f54-416f-9b66-23fafd007ab0.xml | 16 + ...y-7cb331d1-fe1a-426a-978c-b5026a8b3695.xml | 16 + ...y-9859d811-905a-4d9d-895d-1a2467a10a4d.xml | 16 + ...y-dbe172a1-9e7b-4886-a94e-de8124a4bd0d.xml | 16 + ...y-e3154dd2-bdca-48fc-ab68-8d4d8019070c.xml | 16 + OpenAuth.Mvc/wwwroot/css/formpreview.css | 65 + OpenAuth.Mvc/wwwroot/css/images.css | 21 + OpenAuth.Mvc/wwwroot/css/login.css | 92 + OpenAuth.Mvc/wwwroot/css/main.css | 788 + .../wwwroot/css/metroStyle/img/line_conn.png | Bin 0 -> 933 bytes .../wwwroot/css/metroStyle/img/loading.gif | Bin 0 -> 381 bytes .../wwwroot/css/metroStyle/img/metro.gif | Bin 0 -> 4679 bytes .../wwwroot/css/metroStyle/img/metro.png | Bin 0 -> 5283 bytes .../wwwroot/css/metroStyle/metroStyle.css | 96 + OpenAuth.Mvc/wwwroot/css/treetable.css | 16 + OpenAuth.Mvc/wwwroot/favicon.ico | Bin 0 -> 4158 bytes OpenAuth.Mvc/wwwroot/images/alipay.jpg | Bin 0 -> 6056 bytes OpenAuth.Mvc/wwwroot/images/code.jpg | Bin 0 -> 13216 bytes OpenAuth.Mvc/wwwroot/images/face.jpg | Bin 0 -> 4989 bytes .../wwwroot/images/login/buttonbg.png | Bin 0 -> 3000 bytes OpenAuth.Mvc/wwwroot/images/login/cloud.png | Bin 0 -> 35150 bytes OpenAuth.Mvc/wwwroot/images/login/hand.png | Bin 0 -> 1061 bytes .../wwwroot/images/login/left_hand.png | Bin 0 -> 1469 bytes OpenAuth.Mvc/wwwroot/images/login/light.png | Bin 0 -> 132156 bytes .../wwwroot/images/login/loginbg1.png | Bin 0 -> 2834 bytes .../wwwroot/images/login/loginbg2.png | Bin 0 -> 2829 bytes .../wwwroot/images/login/loginbg3.png | Bin 0 -> 153525 bytes .../wwwroot/images/login/logininfo.png | Bin 0 -> 67202 bytes .../wwwroot/images/login/loginpassword.png | Bin 0 -> 3453 bytes OpenAuth.Mvc/wwwroot/images/login/loginsj.png | 9 + .../wwwroot/images/login/loginuser.png | Bin 0 -> 3425 bytes OpenAuth.Mvc/wwwroot/images/login/logo.png | 9 + .../wwwroot/images/login/right_hand.png | Bin 0 -> 1370 bytes OpenAuth.Mvc/wwwroot/images/login/tou.png | Bin 0 -> 9217 bytes OpenAuth.Mvc/wwwroot/images/logo.png | Bin 0 -> 39959 bytes OpenAuth.Mvc/wwwroot/images/userface1.jpg | Bin 0 -> 6372 bytes OpenAuth.Mvc/wwwroot/images/userface2.jpg | Bin 0 -> 6196 bytes OpenAuth.Mvc/wwwroot/images/userface3.jpg | Bin 0 -> 13408 bytes OpenAuth.Mvc/wwwroot/images/userface4.jpg | Bin 0 -> 6414 bytes OpenAuth.Mvc/wwwroot/images/userface5.jpg | Bin 0 -> 8162 bytes OpenAuth.Mvc/wwwroot/images/wechat.jpg | Bin 0 -> 38687 bytes OpenAuth.Mvc/wwwroot/js/bodyTab.js | 266 + OpenAuth.Mvc/wwwroot/js/bootstrap.js | 2286 ++ OpenAuth.Mvc/wwwroot/js/cookie.js | 127 + OpenAuth.Mvc/wwwroot/js/droptree.js | 157 + OpenAuth.Mvc/wwwroot/js/dtree.js | 2808 ++ OpenAuth.Mvc/wwwroot/js/dtree/dtree.css | 73 + .../wwwroot/js/dtree/font/dtreefont.css | 229 + .../wwwroot/js/dtree/font/dtreefont.eot | Bin 0 -> 19508 bytes .../wwwroot/js/dtree/font/dtreefont.svg | 80 + .../wwwroot/js/dtree/font/dtreefont.ttf | Bin 0 -> 19344 bytes .../wwwroot/js/dtree/font/dtreefont.woff | Bin 0 -> 19420 bytes OpenAuth.Mvc/wwwroot/js/dtree/font/icons.json | 283 + OpenAuth.Mvc/wwwroot/js/dtree/开发者日志.txt | 141 + .../wwwroot/js/flow-ui/img/wallbg.png | Bin 0 -> 2860 bytes OpenAuth.Mvc/wwwroot/js/flow/GooFlow.css | 195 + .../wwwroot/js/flow/GooFlow.export.js | 427 + OpenAuth.Mvc/wwwroot/js/flow/GooFlow.print.js | 207 + OpenAuth.Mvc/wwwroot/js/flow/GooFunc.js | 117 + OpenAuth.Mvc/wwwroot/js/flow/config.js | 48 + OpenAuth.Mvc/wwwroot/js/flow/fonts/demo.css | 370 + .../wwwroot/js/flow/fonts/demo_fontclass.html | 256 + .../wwwroot/js/flow/fonts/demo_symbol.html | 351 + .../wwwroot/js/flow/fonts/demo_unicode.html | 294 + .../wwwroot/js/flow/fonts/iconflow.eot | Bin 0 -> 8612 bytes .../wwwroot/js/flow/fonts/iconflow.svg | 141 + .../wwwroot/js/flow/fonts/iconflow.ttf | Bin 0 -> 8444 bytes .../wwwroot/js/flow/fonts/iconflow.woff | Bin 0 -> 5592 bytes .../wwwroot/js/flow/fonts/iconfont.css | 89 + .../wwwroot/js/flow/fonts/iconfont.js | 1 + OpenAuth.Mvc/wwwroot/js/flow/gooflow.js | 2522 ++ .../wwwroot/js/flow/img/gooflow_icon.png | Bin 0 -> 6111 bytes OpenAuth.Mvc/wwwroot/js/flowlayout.js | 355 + .../wwwroot/js/formSelects/formSelects.css | 153 + .../wwwroot/js/formSelects/formSelects.js | 1495 + OpenAuth.Mvc/wwwroot/js/iconPicker.js | 402 + OpenAuth.Mvc/wwwroot/js/index.js | 231 + OpenAuth.Mvc/wwwroot/js/leftNav.js | 83 + OpenAuth.Mvc/wwwroot/js/openauth.js | 52 + OpenAuth.Mvc/wwwroot/js/slimscroll.js | 482 + .../js/ueditor/dialogs/anchor/anchor.html | 40 + .../ueditor/dialogs/attachment/attachment.css | 681 + .../dialogs/attachment/attachment.html | 60 + .../ueditor/dialogs/attachment/attachment.js | 754 + .../attachment/fileTypeImages/icon_chm.gif | Bin 0 -> 923 bytes .../fileTypeImages/icon_default.png | Bin 0 -> 841 bytes .../attachment/fileTypeImages/icon_doc.gif | Bin 0 -> 1012 bytes .../attachment/fileTypeImages/icon_exe.gif | Bin 0 -> 949 bytes .../attachment/fileTypeImages/icon_jpg.gif | Bin 0 -> 950 bytes .../attachment/fileTypeImages/icon_mp3.gif | Bin 0 -> 986 bytes .../attachment/fileTypeImages/icon_mv.gif | Bin 0 -> 1001 bytes .../attachment/fileTypeImages/icon_pdf.gif | Bin 0 -> 996 bytes .../attachment/fileTypeImages/icon_ppt.gif | Bin 0 -> 1001 bytes .../attachment/fileTypeImages/icon_psd.gif | Bin 0 -> 1009 bytes .../attachment/fileTypeImages/icon_rar.gif | Bin 0 -> 1007 bytes .../attachment/fileTypeImages/icon_txt.gif | Bin 0 -> 970 bytes .../attachment/fileTypeImages/icon_xls.gif | Bin 0 -> 1005 bytes .../dialogs/attachment/images/alignicon.gif | Bin 0 -> 1051 bytes .../dialogs/attachment/images/alignicon.png | Bin 0 -> 3714 bytes .../ueditor/dialogs/attachment/images/bg.png | Bin 0 -> 2810 bytes .../dialogs/attachment/images/file-icons.gif | Bin 0 -> 20097 bytes .../dialogs/attachment/images/file-icons.png | Bin 0 -> 44070 bytes .../dialogs/attachment/images/icons.gif | Bin 0 -> 453 bytes .../dialogs/attachment/images/icons.png | Bin 0 -> 2678 bytes .../dialogs/attachment/images/image.png | Bin 0 -> 1672 bytes .../dialogs/attachment/images/progress.png | Bin 0 -> 1269 bytes .../dialogs/attachment/images/success.gif | Bin 0 -> 445 bytes .../dialogs/attachment/images/success.png | Bin 0 -> 1621 bytes .../ueditor/dialogs/background/background.css | 94 + .../dialogs/background/background.html | 56 + .../ueditor/dialogs/background/background.js | 376 + .../ueditor/dialogs/background/images/bg.png | Bin 0 -> 2810 bytes .../dialogs/background/images/success.png | Bin 0 -> 1621 bytes .../js/ueditor/dialogs/charts/chart.config.js | 65 + .../js/ueditor/dialogs/charts/charts.css | 165 + .../js/ueditor/dialogs/charts/charts.html | 89 + .../js/ueditor/dialogs/charts/charts.js | 519 + .../ueditor/dialogs/charts/images/charts0.png | Bin 0 -> 25306 bytes .../ueditor/dialogs/charts/images/charts1.png | Bin 0 -> 19263 bytes .../ueditor/dialogs/charts/images/charts2.png | Bin 0 -> 23016 bytes .../ueditor/dialogs/charts/images/charts3.png | Bin 0 -> 7823 bytes .../ueditor/dialogs/charts/images/charts4.png | Bin 0 -> 8344 bytes .../ueditor/dialogs/charts/images/charts5.png | Bin 0 -> 47084 bytes .../js/ueditor/dialogs/emotion/emotion.css | 43 + .../js/ueditor/dialogs/emotion/emotion.html | 54 + .../js/ueditor/dialogs/emotion/emotion.js | 186 + .../js/ueditor/dialogs/emotion/images/0.gif | Bin 0 -> 43 bytes .../ueditor/dialogs/emotion/images/bface.gif | Bin 0 -> 27167 bytes .../ueditor/dialogs/emotion/images/cface.gif | Bin 0 -> 8603 bytes .../ueditor/dialogs/emotion/images/fface.gif | Bin 0 -> 18479 bytes .../dialogs/emotion/images/jxface2.gif | Bin 0 -> 40706 bytes .../emotion/images/neweditor-tab-bg.png | Bin 0 -> 216 bytes .../ueditor/dialogs/emotion/images/tface.gif | Bin 0 -> 19805 bytes .../ueditor/dialogs/emotion/images/wface.gif | Bin 0 -> 49850 bytes .../ueditor/dialogs/emotion/images/yface.gif | Bin 0 -> 28409 bytes .../wwwroot/js/ueditor/dialogs/gmap/gmap.html | 89 + .../wwwroot/js/ueditor/dialogs/help/help.css | 7 + .../wwwroot/js/ueditor/dialogs/help/help.html | 82 + .../wwwroot/js/ueditor/dialogs/help/help.js | 56 + .../js/ueditor/dialogs/image/image.css | 894 + .../js/ueditor/dialogs/image/image.html | 120 + .../wwwroot/js/ueditor/dialogs/image/image.js | 1139 + .../dialogs/image/images/alignicon.jpg | Bin 0 -> 16101 bytes .../js/ueditor/dialogs/image/images/bg.png | Bin 0 -> 2810 bytes .../js/ueditor/dialogs/image/images/icons.gif | Bin 0 -> 453 bytes .../js/ueditor/dialogs/image/images/icons.png | Bin 0 -> 2678 bytes .../js/ueditor/dialogs/image/images/image.png | Bin 0 -> 1672 bytes .../ueditor/dialogs/image/images/progress.png | Bin 0 -> 1269 bytes .../ueditor/dialogs/image/images/success.gif | Bin 0 -> 445 bytes .../ueditor/dialogs/image/images/success.png | Bin 0 -> 1621 bytes .../dialogs/insertframe/insertframe.html | 98 + .../wwwroot/js/ueditor/dialogs/internal.js | 81 + .../wwwroot/js/ueditor/dialogs/link/link.html | 126 + .../wwwroot/js/ueditor/dialogs/map/map.html | 135 + .../wwwroot/js/ueditor/dialogs/map/show.html | 118 + .../js/ueditor/dialogs/music/music.css | 30 + .../js/ueditor/dialogs/music/music.html | 32 + .../wwwroot/js/ueditor/dialogs/music/music.js | 192 + .../js/ueditor/dialogs/preview/preview.html | 40 + .../ueditor/dialogs/scrawl/images/addimg.png | Bin 0 -> 628 bytes .../ueditor/dialogs/scrawl/images/brush.png | Bin 0 -> 608 bytes .../ueditor/dialogs/scrawl/images/delimg.png | Bin 0 -> 516 bytes .../ueditor/dialogs/scrawl/images/delimgH.png | Bin 0 -> 578 bytes .../ueditor/dialogs/scrawl/images/empty.png | Bin 0 -> 519 bytes .../ueditor/dialogs/scrawl/images/emptyH.png | Bin 0 -> 657 bytes .../ueditor/dialogs/scrawl/images/eraser.png | Bin 0 -> 43271 bytes .../js/ueditor/dialogs/scrawl/images/redo.png | Bin 0 -> 454 bytes .../ueditor/dialogs/scrawl/images/redoH.png | Bin 0 -> 536 bytes .../ueditor/dialogs/scrawl/images/scale.png | Bin 0 -> 435 bytes .../ueditor/dialogs/scrawl/images/scaleH.png | Bin 0 -> 330 bytes .../js/ueditor/dialogs/scrawl/images/size.png | Bin 0 -> 775 bytes .../js/ueditor/dialogs/scrawl/images/undo.png | Bin 0 -> 444 bytes .../ueditor/dialogs/scrawl/images/undoH.png | Bin 0 -> 511 bytes .../js/ueditor/dialogs/scrawl/scrawl.css | 72 + .../js/ueditor/dialogs/scrawl/scrawl.html | 95 + .../js/ueditor/dialogs/scrawl/scrawl.js | 671 + .../dialogs/searchreplace/searchreplace.html | 102 + .../dialogs/searchreplace/searchreplace.js | 164 + .../dialogs/snapscreen/snapscreen.html | 58 + .../js/ueditor/dialogs/spechars/spechars.html | 21 + .../js/ueditor/dialogs/spechars/spechars.js | 57 + .../js/ueditor/dialogs/table/dragicon.png | Bin 0 -> 304 bytes .../js/ueditor/dialogs/table/edittable.css | 84 + .../js/ueditor/dialogs/table/edittable.html | 64 + .../js/ueditor/dialogs/table/edittable.js | 237 + .../js/ueditor/dialogs/table/edittd.html | 61 + .../js/ueditor/dialogs/table/edittip.html | 33 + .../js/ueditor/dialogs/template/config.js | 42 + .../js/ueditor/dialogs/template/images/bg.gif | Bin 0 -> 84 bytes .../ueditor/dialogs/template/images/pre0.png | Bin 0 -> 250 bytes .../ueditor/dialogs/template/images/pre1.png | Bin 0 -> 291 bytes .../ueditor/dialogs/template/images/pre2.png | Bin 0 -> 394 bytes .../ueditor/dialogs/template/images/pre3.png | Bin 0 -> 485 bytes .../ueditor/dialogs/template/images/pre4.png | Bin 0 -> 393 bytes .../js/ueditor/dialogs/template/template.css | 18 + .../js/ueditor/dialogs/template/template.html | 26 + .../js/ueditor/dialogs/template/template.js | 53 + .../js/ueditor/dialogs/video/images/bg.png | Bin 0 -> 2810 bytes .../dialogs/video/images/center_focus.jpg | Bin 0 -> 11795 bytes .../dialogs/video/images/file-icons.gif | Bin 0 -> 20097 bytes .../dialogs/video/images/file-icons.png | Bin 0 -> 44070 bytes .../js/ueditor/dialogs/video/images/icons.gif | Bin 0 -> 453 bytes .../js/ueditor/dialogs/video/images/icons.png | Bin 0 -> 2678 bytes .../js/ueditor/dialogs/video/images/image.png | Bin 0 -> 1672 bytes .../dialogs/video/images/left_focus.jpg | Bin 0 -> 11423 bytes .../dialogs/video/images/none_focus.jpg | Bin 0 -> 11546 bytes .../ueditor/dialogs/video/images/progress.png | Bin 0 -> 1269 bytes .../dialogs/video/images/right_focus.jpg | Bin 0 -> 11334 bytes .../ueditor/dialogs/video/images/success.gif | Bin 0 -> 445 bytes .../ueditor/dialogs/video/images/success.png | Bin 0 -> 1621 bytes .../js/ueditor/dialogs/video/video.css | 635 + .../js/ueditor/dialogs/video/video.html | 86 + .../wwwroot/js/ueditor/dialogs/video/video.js | 789 + .../js/ueditor/dialogs/webapp/webapp.html | 53 + .../dialogs/wordimage/fClipboard_ueditor.swf | Bin 0 -> 1908 bytes .../dialogs/wordimage/imageUploader.swf | Bin 0 -> 62857 bytes .../js/ueditor/dialogs/wordimage/tangram.js | 1495 + .../ueditor/dialogs/wordimage/wordimage.html | 111 + .../js/ueditor/dialogs/wordimage/wordimage.js | 157 + .../wwwroot/js/ueditor/formdesign/Readme.txt | 6 + .../js/ueditor/formdesign/bootstrap-ie.js | 416 + .../bootstrap/css/bootstrap-ie6.css | 5773 +++ .../bootstrap/css/bootstrap-ie6.min.css | 1 + .../bootstrap/css/bootstrap-responsive.css | 1109 + .../css/bootstrap-responsive.min.css | 9 + .../formdesign/bootstrap/css/bootstrap.css | 6167 ++++ .../bootstrap/css/bootstrap.min.css | 9 + .../ueditor/formdesign/bootstrap/css/ie.css | 59 + .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../bootstrap/img/glyphicons-halflings.png | Bin 0 -> 12799 bytes .../formdesign/bootstrap/js/bootstrap.js | 2280 ++ .../formdesign/bootstrap/js/bootstrap.min.js | 6 + .../js/ueditor/formdesign/checkbox.html | 104 + .../js/ueditor/formdesign/checkboxs.html | 268 + .../wwwroot/js/ueditor/formdesign/error.html | 30 + .../formdesign/images/leipi_formdesign.png | Bin 0 -> 6540 bytes .../ueditor/formdesign/images/progressbar.gif | Bin 0 -> 2280 bytes .../js/ueditor/formdesign/images/qrcode.gif | Bin 0 -> 2020 bytes .../ueditor/formdesign/images/template/bg.gif | Bin 0 -> 84 bytes .../formdesign/images/template/pre0.png | Bin 0 -> 250 bytes .../formdesign/images/template/pre1.png | Bin 0 -> 291 bytes .../js/ueditor/formdesign/jquery-1.7.2.min.js | 4 + .../ueditor/formdesign/leipi.formdesign.v4.js | 1079 + .../wwwroot/js/ueditor/formdesign/leipi.html | 51 + .../js/ueditor/formdesign/leipi.style.css | 105 + .../js/ueditor/formdesign/listctrl.html | 335 + .../wwwroot/js/ueditor/formdesign/macros.html | 197 + .../wwwroot/js/ueditor/formdesign/more.html | 32 + .../js/ueditor/formdesign/progressbar.html | 149 + .../wwwroot/js/ueditor/formdesign/qrcode.html | 147 + .../wwwroot/js/ueditor/formdesign/radio.html | 290 + .../wwwroot/js/ueditor/formdesign/radios.html | 275 + .../wwwroot/js/ueditor/formdesign/select.html | 318 + .../js/ueditor/formdesign/template.html | 119 + .../wwwroot/js/ueditor/formdesign/text.html | 216 + .../js/ueditor/formdesign/textarea.html | 162 + .../formdesign/textfield.html.ajax.bak | 155 + OpenAuth.Mvc/wwwroot/js/ueditor/index.html | 175 + OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/en.js | 684 + .../js/ueditor/lang/en/images/addimage.png | Bin 0 -> 3373 bytes .../lang/en/images/alldeletebtnhoverskin.png | Bin 0 -> 743 bytes .../lang/en/images/alldeletebtnupskin.png | Bin 0 -> 743 bytes .../js/ueditor/lang/en/images/background.png | Bin 0 -> 3854 bytes .../js/ueditor/lang/en/images/button.png | Bin 0 -> 4929 bytes .../js/ueditor/lang/en/images/copy.png | Bin 0 -> 1222 bytes .../ueditor/lang/en/images/deletedisable.png | Bin 0 -> 649 bytes .../ueditor/lang/en/images/deleteenable.png | Bin 0 -> 664 bytes .../ueditor/lang/en/images/listbackground.png | Bin 0 -> 3750 bytes .../js/ueditor/lang/en/images/localimage.png | Bin 0 -> 3083 bytes .../js/ueditor/lang/en/images/music.png | Bin 0 -> 91561 bytes .../lang/en/images/rotateleftdisable.png | Bin 0 -> 719 bytes .../lang/en/images/rotateleftenable.png | Bin 0 -> 952 bytes .../lang/en/images/rotaterightdisable.png | Bin 0 -> 754 bytes .../lang/en/images/rotaterightenable.png | Bin 0 -> 1007 bytes .../js/ueditor/lang/en/images/upload.png | Bin 0 -> 3941 bytes .../js/ueditor/lang/zh-cn/images/copy.png | Bin 0 -> 4319 bytes .../ueditor/lang/zh-cn/images/localimage.png | Bin 0 -> 6979 bytes .../js/ueditor/lang/zh-cn/images/music.png | Bin 0 -> 23106 bytes .../js/ueditor/lang/zh-cn/images/upload.png | Bin 0 -> 6608 bytes .../wwwroot/js/ueditor/lang/zh-cn/zh-cn.js | 669 + .../js/ueditor/themes/default/css/ueditor.css | 1903 + .../themes/default/css/ueditor.min.css | 8 + .../js/ueditor/themes/default/dialogbase.css | 100 + .../ueditor/themes/default/images/anchor.gif | Bin 0 -> 184 bytes .../ueditor/themes/default/images/arrow.png | Bin 0 -> 1173 bytes .../themes/default/images/arrow_down.png | Bin 0 -> 1610 bytes .../themes/default/images/arrow_up.png | Bin 0 -> 1649 bytes .../themes/default/images/button-bg.gif | Bin 0 -> 1114 bytes .../themes/default/images/cancelbutton.gif | Bin 0 -> 1227 bytes .../ueditor/themes/default/images/charts.png | Bin 0 -> 518 bytes .../themes/default/images/cursor_h.gif | Bin 0 -> 253 bytes .../themes/default/images/cursor_h.png | Bin 0 -> 175 bytes .../themes/default/images/cursor_v.gif | Bin 0 -> 370 bytes .../themes/default/images/cursor_v.png | Bin 0 -> 177 bytes .../themes/default/images/dialog-title-bg.png | Bin 0 -> 938 bytes .../themes/default/images/filescan.png | Bin 0 -> 4282 bytes .../themes/default/images/highlighted.gif | Bin 0 -> 111 bytes .../themes/default/images/icons-all.gif | Bin 0 -> 3750 bytes .../ueditor/themes/default/images/icons.gif | Bin 0 -> 20947 bytes .../ueditor/themes/default/images/icons.png | Bin 0 -> 19694 bytes .../themes/default/images/loaderror.png | Bin 0 -> 3209 bytes .../ueditor/themes/default/images/loading.gif | Bin 0 -> 734 bytes .../js/ueditor/themes/default/images/lock.gif | Bin 0 -> 1062 bytes .../default/images/neweditor-tab-bg.png | Bin 0 -> 216 bytes .../themes/default/images/pagebreak.gif | Bin 0 -> 54 bytes .../ueditor/themes/default/images/scale.png | Bin 0 -> 167 bytes .../themes/default/images/sortable.png | Bin 0 -> 2851 bytes .../ueditor/themes/default/images/spacer.gif | Bin 0 -> 43 bytes .../themes/default/images/sparator_v.png | Bin 0 -> 122 bytes .../default/images/table-cell-align.png | Bin 0 -> 1847 bytes .../default/images/tangram-colorpicker.png | Bin 0 -> 17355 bytes .../themes/default/images/toolbar_bg.png | Bin 0 -> 170 bytes .../themes/default/images/unhighlighted.gif | Bin 0 -> 111 bytes .../ueditor/themes/default/images/upload.png | Bin 0 -> 6608 bytes .../themes/default/images/videologo.gif | Bin 0 -> 1604 bytes .../js/ueditor/themes/default/images/word.gif | Bin 0 -> 1019 bytes .../themes/default/images/wordpaste.png | Bin 0 -> 6467 bytes .../wwwroot/js/ueditor/themes/iframe.css | 1 + .../third-party/codemirror/codemirror.css | 104 + .../third-party/codemirror/codemirror.js | 3581 ++ .../third-party/webuploader/Uploader.swf | Bin 0 -> 49382 bytes .../third-party/webuploader/webuploader.css | 28 + .../webuploader/webuploader.custom.js | 5670 +++ .../webuploader/webuploader.custom.min.js | 2 + .../webuploader/webuploader.flashonly.js | 4176 +++ .../webuploader/webuploader.flashonly.min.js | 2 + .../webuploader/webuploader.html5only.js | 5559 +++ .../webuploader/webuploader.html5only.min.js | 2 + .../third-party/webuploader/webuploader.js | 6733 ++++ .../webuploader/webuploader.min.js | 2 + .../webuploader/webuploader.withoutimage.js | 4593 +++ .../webuploader.withoutimage.min.js | 2 + .../zeroclipboard/ZeroClipboard.js | 1256 + .../zeroclipboard/ZeroClipboard.min.js | 9 + .../zeroclipboard/ZeroClipboard.swf | Bin 0 -> 3933 bytes .../wwwroot/js/ueditor/ueditor.all.js | 29403 ++++++++++++++++ .../wwwroot/js/ueditor/ueditor.all.min.js | 709 + .../wwwroot/js/ueditor/ueditor.config.js | 413 + .../wwwroot/js/ueditor/ueditor.parse.js | 1022 + .../wwwroot/js/ueditor/ueditor.parse.min.js | 28 + OpenAuth.Mvc/wwwroot/js/utils.js | 59 + OpenAuth.Mvc/wwwroot/js/vue.js | 11949 +++++++ OpenAuth.Mvc/wwwroot/js/vue2.6.10.js | 11945 +++++++ OpenAuth.Mvc/wwwroot/js/ztree.js | 475 + OpenAuth.Mvc/wwwroot/layui/css/layui.css | 2 + .../wwwroot/layui/css/layui.mobile.css | 2 + .../wwwroot/layui/css/modules/code.css | 2 + .../css/modules/laydate/default/font.css | 16 + .../css/modules/laydate/default/laydate.css | 2 + .../layui/css/modules/laydate/icon.png | Bin 0 -> 314 bytes .../layui/css/modules/laydate/laydate.css | 2 + .../css/modules/layer/default/icon-ext.png | Bin 0 -> 5911 bytes .../layui/css/modules/layer/default/icon.png | Bin 0 -> 11493 bytes .../layui/css/modules/layer/default/layer.css | 2 + .../css/modules/layer/default/loading-0.gif | Bin 0 -> 5793 bytes .../css/modules/layer/default/loading-1.gif | Bin 0 -> 701 bytes .../css/modules/layer/default/loading-2.gif | Bin 0 -> 1787 bytes OpenAuth.Mvc/wwwroot/layui/font/iconfont.eot | Bin 0 -> 46684 bytes OpenAuth.Mvc/wwwroot/layui/font/iconfont.svg | 554 + OpenAuth.Mvc/wwwroot/layui/font/iconfont.ttf | Bin 0 -> 46508 bytes OpenAuth.Mvc/wwwroot/layui/font/iconfont.woff | Bin 0 -> 30628 bytes .../wwwroot/layui/font/iconfont.woff2 | Bin 0 -> 25964 bytes OpenAuth.Mvc/wwwroot/layui/images/face/0.gif | Bin 0 -> 2689 bytes OpenAuth.Mvc/wwwroot/layui/images/face/1.gif | Bin 0 -> 5514 bytes OpenAuth.Mvc/wwwroot/layui/images/face/10.gif | Bin 0 -> 2797 bytes OpenAuth.Mvc/wwwroot/layui/images/face/11.gif | Bin 0 -> 4121 bytes OpenAuth.Mvc/wwwroot/layui/images/face/12.gif | Bin 0 -> 3361 bytes OpenAuth.Mvc/wwwroot/layui/images/face/13.gif | Bin 0 -> 7425 bytes OpenAuth.Mvc/wwwroot/layui/images/face/14.gif | Bin 0 -> 2375 bytes OpenAuth.Mvc/wwwroot/layui/images/face/15.gif | Bin 0 -> 1793 bytes OpenAuth.Mvc/wwwroot/layui/images/face/16.gif | Bin 0 -> 6721 bytes OpenAuth.Mvc/wwwroot/layui/images/face/17.gif | Bin 0 -> 4439 bytes OpenAuth.Mvc/wwwroot/layui/images/face/18.gif | Bin 0 -> 3017 bytes OpenAuth.Mvc/wwwroot/layui/images/face/19.gif | Bin 0 -> 3040 bytes OpenAuth.Mvc/wwwroot/layui/images/face/2.gif | Bin 0 -> 3222 bytes OpenAuth.Mvc/wwwroot/layui/images/face/20.gif | Bin 0 -> 5144 bytes OpenAuth.Mvc/wwwroot/layui/images/face/21.gif | Bin 0 -> 5191 bytes OpenAuth.Mvc/wwwroot/layui/images/face/22.gif | Bin 0 -> 9823 bytes OpenAuth.Mvc/wwwroot/layui/images/face/23.gif | Bin 0 -> 3792 bytes OpenAuth.Mvc/wwwroot/layui/images/face/24.gif | Bin 0 -> 8096 bytes OpenAuth.Mvc/wwwroot/layui/images/face/25.gif | Bin 0 -> 3127 bytes OpenAuth.Mvc/wwwroot/layui/images/face/26.gif | Bin 0 -> 3291 bytes OpenAuth.Mvc/wwwroot/layui/images/face/27.gif | Bin 0 -> 4377 bytes OpenAuth.Mvc/wwwroot/layui/images/face/28.gif | Bin 0 -> 2793 bytes OpenAuth.Mvc/wwwroot/layui/images/face/29.gif | Bin 0 -> 4854 bytes OpenAuth.Mvc/wwwroot/layui/images/face/3.gif | Bin 0 -> 4017 bytes OpenAuth.Mvc/wwwroot/layui/images/face/30.gif | Bin 0 -> 2555 bytes OpenAuth.Mvc/wwwroot/layui/images/face/31.gif | Bin 0 -> 2002 bytes OpenAuth.Mvc/wwwroot/layui/images/face/32.gif | Bin 0 -> 3481 bytes OpenAuth.Mvc/wwwroot/layui/images/face/33.gif | Bin 0 -> 2454 bytes OpenAuth.Mvc/wwwroot/layui/images/face/34.gif | Bin 0 -> 3700 bytes OpenAuth.Mvc/wwwroot/layui/images/face/35.gif | Bin 0 -> 1800 bytes OpenAuth.Mvc/wwwroot/layui/images/face/36.gif | Bin 0 -> 2331 bytes OpenAuth.Mvc/wwwroot/layui/images/face/37.gif | Bin 0 -> 1513 bytes OpenAuth.Mvc/wwwroot/layui/images/face/38.gif | Bin 0 -> 3615 bytes OpenAuth.Mvc/wwwroot/layui/images/face/39.gif | Bin 0 -> 6495 bytes OpenAuth.Mvc/wwwroot/layui/images/face/4.gif | Bin 0 -> 5689 bytes OpenAuth.Mvc/wwwroot/layui/images/face/40.gif | Bin 0 -> 3154 bytes OpenAuth.Mvc/wwwroot/layui/images/face/41.gif | Bin 0 -> 3644 bytes OpenAuth.Mvc/wwwroot/layui/images/face/42.gif | Bin 0 -> 5305 bytes OpenAuth.Mvc/wwwroot/layui/images/face/43.gif | Bin 0 -> 2674 bytes OpenAuth.Mvc/wwwroot/layui/images/face/44.gif | Bin 0 -> 4126 bytes OpenAuth.Mvc/wwwroot/layui/images/face/45.gif | Bin 0 -> 3417 bytes OpenAuth.Mvc/wwwroot/layui/images/face/46.gif | Bin 0 -> 3007 bytes OpenAuth.Mvc/wwwroot/layui/images/face/47.gif | Bin 0 -> 2333 bytes OpenAuth.Mvc/wwwroot/layui/images/face/48.gif | Bin 0 -> 2689 bytes OpenAuth.Mvc/wwwroot/layui/images/face/49.gif | Bin 0 -> 2315 bytes OpenAuth.Mvc/wwwroot/layui/images/face/5.gif | Bin 0 -> 4567 bytes OpenAuth.Mvc/wwwroot/layui/images/face/50.gif | Bin 0 -> 5866 bytes OpenAuth.Mvc/wwwroot/layui/images/face/51.gif | Bin 0 -> 2785 bytes OpenAuth.Mvc/wwwroot/layui/images/face/52.gif | Bin 0 -> 777 bytes OpenAuth.Mvc/wwwroot/layui/images/face/53.gif | Bin 0 -> 2127 bytes OpenAuth.Mvc/wwwroot/layui/images/face/54.gif | Bin 0 -> 2196 bytes OpenAuth.Mvc/wwwroot/layui/images/face/55.gif | Bin 0 -> 1971 bytes OpenAuth.Mvc/wwwroot/layui/images/face/56.gif | Bin 0 -> 2034 bytes OpenAuth.Mvc/wwwroot/layui/images/face/57.gif | Bin 0 -> 2705 bytes OpenAuth.Mvc/wwwroot/layui/images/face/58.gif | Bin 0 -> 2258 bytes OpenAuth.Mvc/wwwroot/layui/images/face/59.gif | Bin 0 -> 10311 bytes OpenAuth.Mvc/wwwroot/layui/images/face/6.gif | Bin 0 -> 2213 bytes OpenAuth.Mvc/wwwroot/layui/images/face/60.gif | Bin 0 -> 3245 bytes OpenAuth.Mvc/wwwroot/layui/images/face/61.gif | Bin 0 -> 2495 bytes OpenAuth.Mvc/wwwroot/layui/images/face/62.gif | Bin 0 -> 2017 bytes OpenAuth.Mvc/wwwroot/layui/images/face/63.gif | Bin 0 -> 5871 bytes OpenAuth.Mvc/wwwroot/layui/images/face/64.gif | Bin 0 -> 6448 bytes OpenAuth.Mvc/wwwroot/layui/images/face/65.gif | Bin 0 -> 3576 bytes OpenAuth.Mvc/wwwroot/layui/images/face/66.gif | Bin 0 -> 3029 bytes OpenAuth.Mvc/wwwroot/layui/images/face/67.gif | Bin 0 -> 2701 bytes OpenAuth.Mvc/wwwroot/layui/images/face/68.gif | Bin 0 -> 1424 bytes OpenAuth.Mvc/wwwroot/layui/images/face/69.gif | Bin 0 -> 2431 bytes OpenAuth.Mvc/wwwroot/layui/images/face/7.gif | Bin 0 -> 3398 bytes OpenAuth.Mvc/wwwroot/layui/images/face/70.gif | Bin 0 -> 4590 bytes OpenAuth.Mvc/wwwroot/layui/images/face/71.gif | Bin 0 -> 5304 bytes OpenAuth.Mvc/wwwroot/layui/images/face/8.gif | Bin 0 -> 4050 bytes OpenAuth.Mvc/wwwroot/layui/images/face/9.gif | Bin 0 -> 4221 bytes .../wwwroot/layui/lay/dest/layui.all.js | 5 + .../wwwroot/layui/lay/modules/carousel.js | 2 + .../wwwroot/layui/lay/modules/code.js | 2 + .../wwwroot/layui/lay/modules/colorpicker.js | 2 + .../wwwroot/layui/lay/modules/element.js | 2 + .../wwwroot/layui/lay/modules/flow.js | 2 + .../wwwroot/layui/lay/modules/form.js | 2 + .../wwwroot/layui/lay/modules/jquery.js | 5 + .../wwwroot/layui/lay/modules/laydate.js | 2 + .../wwwroot/layui/lay/modules/layedit.js | 2 + .../wwwroot/layui/lay/modules/layer.js | 2 + .../wwwroot/layui/lay/modules/layim.js | 3 + .../wwwroot/layui/lay/modules/laypage.js | 2 + .../wwwroot/layui/lay/modules/laytpl.js | 2 + .../wwwroot/layui/lay/modules/mobile.js | 2 + .../wwwroot/layui/lay/modules/rate.js | 2 + .../wwwroot/layui/lay/modules/slider.js | 2 + .../wwwroot/layui/lay/modules/table.js | 2 + .../wwwroot/layui/lay/modules/transfer.js | 2 + .../wwwroot/layui/lay/modules/tree.js | 2 + .../wwwroot/layui/lay/modules/upload.js | 2 + .../wwwroot/layui/lay/modules/util.js | 2 + OpenAuth.Mvc/wwwroot/layui/layui.all.js | 5 + OpenAuth.Mvc/wwwroot/layui/layui.js | 2 + OpenAuth.Mvc/wwwroot/userJs/assignModule.js | 262 + OpenAuth.Mvc/wwwroot/userJs/assignResource.js | 96 + OpenAuth.Mvc/wwwroot/userJs/assignRole.js | 84 + OpenAuth.Mvc/wwwroot/userJs/categories.js | 169 + OpenAuth.Mvc/wwwroot/userJs/changePwd.js | 45 + .../wwwroot/userJs/dataprivilegerules.js | 173 + .../wwwroot/userJs/flowInstanceDisposed.js | 115 + .../wwwroot/userJs/flowInstanceEdit.js | 165 + .../wwwroot/userJs/flowInstanceWait.js | 151 + OpenAuth.Mvc/wwwroot/userJs/flowInstances.js | 181 + .../wwwroot/userJs/flowSchemeDesign.js | 144 + .../wwwroot/userJs/flowSchemePreview.js | 78 + OpenAuth.Mvc/wwwroot/userJs/flowSchemes.js | 174 + .../wwwroot/userJs/flowinstanceDetail.js | 66 + OpenAuth.Mvc/wwwroot/userJs/formEdit.js | 333 + OpenAuth.Mvc/wwwroot/userJs/forms.js | 170 + OpenAuth.Mvc/wwwroot/userJs/login.js | 125 + OpenAuth.Mvc/wwwroot/userJs/main.js | 18 + OpenAuth.Mvc/wwwroot/userJs/modules.js | 326 + OpenAuth.Mvc/wwwroot/userJs/nodeInfo.js | 250 + OpenAuth.Mvc/wwwroot/userJs/openjobs.js | 161 + OpenAuth.Mvc/wwwroot/userJs/orgs.js | 211 + OpenAuth.Mvc/wwwroot/userJs/preview.js | 17 + OpenAuth.Mvc/wwwroot/userJs/profile.js | 142 + OpenAuth.Mvc/wwwroot/userJs/resources.js | 173 + OpenAuth.Mvc/wwwroot/userJs/roles.js | 199 + OpenAuth.Mvc/wwwroot/userJs/syslogs.js | 89 + OpenAuth.Mvc/wwwroot/userJs/sysmessages.js | 98 + OpenAuth.Mvc/wwwroot/userJs/users.js | 249 + OpenAuth.Mvc/wwwroot/userJs/verification.js | 62 + .../wwwroot/userJs/wmsinboundordertbls.js | 174 + OpenAuth.Net.sln | 49 + OpenAuth.Repository/Core/BaseEntity.cs | 24 + OpenAuth.Repository/Core/Entity.cs | 35 + OpenAuth.Repository/Core/StringEntity.cs | 33 + OpenAuth.Repository/Core/TreeEntity.cs | 38 + OpenAuth.Repository/Core/TreeItemLong.cs | 24 + OpenAuth.Repository/Core/TreeItemString.cs | 21 + OpenAuth.Repository/Domain/DataSource.cs | 83 + OpenAuth.Repository/Domain/DbCodeColumns.cs | 75 + OpenAuth.Repository/Domain/DbCodeTable.cs | 64 + OpenAuth.Repository/Domain/ExcelImport.cs | 82 + .../Domain/ExcelImportFileds.cs | 64 + OpenAuth.Repository/Domain/FormDataHistory.cs | 84 + .../Domain/FormModuleEntity.cs | 116 + OpenAuth.Repository/Domain/FormScheme.cs | 58 + OpenAuth.Repository/Domain/FormSchemeInfo.cs | 80 + OpenAuth.Repository/Domain/ImMsg.cs | 90 + .../Domain/Permission/BaseDataAuth.cs | 106 + OpenAuth.Repository/Domain/SysAppFiles.cs | 75 + OpenAuth.Repository/Domain/SysApplication.cs | 54 + OpenAuth.Repository/Domain/SysAreaOrg.cs | 24 + OpenAuth.Repository/Domain/SysCategory.cs | 85 + OpenAuth.Repository/Domain/SysCategoryType.cs | 28 + OpenAuth.Repository/Domain/SysCodeRule.cs | 94 + OpenAuth.Repository/Domain/SysCodeRuleSeed.cs | 70 + OpenAuth.Repository/Domain/SysDataItem.cs | 88 + .../Domain/SysDataItemDetail.cs | 99 + OpenAuth.Repository/Domain/SysDatabaseLink.cs | 160 + OpenAuth.Repository/Domain/SysLog.cs | 67 + OpenAuth.Repository/Domain/SysMessage.cs | 85 + OpenAuth.Repository/Domain/SysModule.cs | 64 + OpenAuth.Repository/Domain/SysModuleColumn.cs | 64 + .../Domain/SysModuleElement.cs | 69 + OpenAuth.Repository/Domain/SysModuleForm.cs | 64 + OpenAuth.Repository/Domain/SysOpenJob.cs | 119 + OpenAuth.Repository/Domain/SysOrg.cs | 65 + OpenAuth.Repository/Domain/SysPosGroup.cs | 20 + OpenAuth.Repository/Domain/SysPosition.cs | 26 + OpenAuth.Repository/Domain/SysRelevance.cs | 75 + OpenAuth.Repository/Domain/SysResource.cs | 85 + OpenAuth.Repository/Domain/SysRole.cs | 39 + OpenAuth.Repository/Domain/SysRoleElement.cs | 18 + OpenAuth.Repository/Domain/SysRoleModule.cs | 18 + OpenAuth.Repository/Domain/SysRoleResource.cs | 18 + OpenAuth.Repository/Domain/SysUploadFile.cs | 82 + OpenAuth.Repository/Domain/SysUser.cs | 61 + OpenAuth.Repository/Domain/SysUserOrg.cs | 22 + OpenAuth.Repository/Domain/SysUserRole.cs | 18 + OpenAuth.Repository/Domain/TableRecord.cs | 22 + OpenAuth.Repository/Domain/UserExt.cs | 19 + .../Domain/WFDelegateRelation.cs | 30 + OpenAuth.Repository/Domain/WFDelegateRule.cs | 63 + OpenAuth.Repository/Domain/WFInstanceInfo.cs | 10 + OpenAuth.Repository/Domain/WFProcess.cs | 138 + OpenAuth.Repository/Domain/WFScheme.cs | 53 + OpenAuth.Repository/Domain/WFSchemeAuth.cs | 36 + OpenAuth.Repository/Domain/WFSchemeInfo.cs | 91 + OpenAuth.Repository/Domain/WFStamp.cs | 60 + OpenAuth.Repository/Domain/WFTask.cs | 274 + OpenAuth.Repository/Domain/WFTaskLog.cs | 94 + OpenAuth.Repository/Domain/WFTaskUser.cs | 24 + OpenAuth.Repository/ISugarRepositiry.cs | 13 + .../OpenAuth.Repository.csproj | 36 + OpenAuth.Repository/SugarDbContext.cs | 62 + OpenAuth.Repository/SugarRepositiry.cs | 25 + OpenAuth.WebApi/.config/dotnet-tools.json | 12 + .../BaseControllers/ApplicationsController.cs | 39 + .../CategoryTypesController.cs | 94 + .../BaseControllers/CategorysController.cs | 130 + .../BaseControllers/CheckController.cs | 348 + .../BaseControllers/CodeTableController.cs | 138 + .../BaseControllers/CreateTableController.cs | 125 + .../BaseControllers/DataSourceController.cs | 99 + .../BaseControllers/DbTableController.cs | 69 + .../BaseControllers/FilesController.cs | 201 + .../BaseControllers/FormModuleController.cs | 314 + .../BaseControllers/FormSchemeController.cs | 513 + .../BaseControllers/ImMsgController.cs | 215 + .../BaseControllers/ImportController.cs | 217 + .../BaseControllers/ModulesController.cs | 269 + .../BaseControllers/OpenJobsController.cs | 166 + .../BaseControllers/OrgsController.cs | 287 + .../Permission/BaseDataAuthController.cs | 127 + .../BaseControllers/ResourcesController.cs | 104 + .../BaseControllers/RolesController.cs | 186 + .../BaseControllers/SysAppFilesController.cs | 95 + .../BaseControllers/SysConfController.cs | 38 + .../BaseControllers/SysDataItemController.cs | 131 + .../SysDataItemDetailController.cs | 124 + .../SysDatabaseLinkController.cs | 147 + .../BaseControllers/SysLogsController.cs | 117 + .../BaseControllers/SysMessagesController.cs | 102 + .../BaseControllers/SysPosGroupController.cs | 46 + .../BaseControllers/SysPositionController.cs | 91 + .../BaseControllers/UsersController.cs | 295 + .../BaseControllers/WFDelegateController.cs | 180 + .../BaseControllers/WFProcessController.cs | 672 + .../BaseControllers/WFSchemeController.cs | 64 + .../BaseControllers/WFSchemeInfoController.cs | 394 + .../BaseControllers/WFStampController.cs | 197 + .../BaseControllers/WFTaskController.cs | 235 + OpenAuth.WebApi/Dockerfile | 26 + .../Model/AuthResponsesOperationFilter.cs | 58 + .../Model/CustomAttribute/AllDataAttribute.cs | 13 + OpenAuth.WebApi/Model/CustomBadRequest.cs | 50 + .../Model/GlobalExceptionFilter.cs | 15 + .../Model/GlobalHttpHeaderOperationFilter.cs | 55 + OpenAuth.WebApi/Model/OpenAuthFilter.cs | 83 + ...TagByApiExplorerSettingsOperationFilter.cs | 32 + OpenAuth.WebApi/Model/TransactionFilter.cs | 31 + OpenAuth.WebApi/OpenAuth.WebApi.csproj | 85 + OpenAuth.WebApi/Program.cs | 17 + .../Properties/launchSettings.json | 19 + OpenAuth.WebApi/Startup.cs | 443 + .../Template/BuildControllerApi.html | 113 + OpenAuth.WebApi/Template/BuildEntity.html | 24 + OpenAuth.WebApi/Template/BuildQueryReq.html | 7 + OpenAuth.WebApi/Template/BuildUpdateReq.html | 20 + OpenAuth.WebApi/Template/BuildVueApi.html | 34 + .../Template/MultiTable/BuildVue.html | 415 + .../Template/MultiTable/BuildVue3.html | 473 + .../BuildVue3WithDynamicHeader.html | 478 + .../MultiTable/BuildVueWithDynamicHeader.html | 416 + .../Template/SingleTable/BuildApp.html | 69 + .../BuildAppWithDynamicHeader.html | 76 + .../Template/SingleTable/BuildVue.html | 236 + .../Template/SingleTable/BuildVue3.html | 257 + .../BuildVue3WithDynamicHeader.html | 260 + .../BuildVueWithDynamicHeader.html | 237 + OpenAuth.WebApi/appsettings.Development.json | 10 + OpenAuth.WebApi/appsettings.Production.json | 32 + OpenAuth.WebApi/appsettings.json | 71 + OpenAuth.WebApi/dev_run.bat | 1 + OpenAuth.WebApi/index.html | 99 + ...y-0a973b95-633f-45ab-a49a-f343d72ffb73.xml | 16 + ...y-267d23aa-8099-45e2-9d0b-039faaea38b4.xml | 16 + ...y-2ddf99b6-7de3-4478-9a18-c8a6eeba1237.xml | 16 + ...y-5afe1848-73e8-48e3-ac95-2337e57ea148.xml | 16 + ...y-8e9d695c-6220-4f9c-803d-4d5698b2cc38.xml | 16 + ...y-a8a17770-53af-43cb-8ff9-ab1db745877d.xml | 16 + ...y-db096406-87a5-4967-8ab0-1203a03f7f55.xml | 16 + ...y-e8aef8d6-eb3c-4683-b62d-45e09de6b65f.xml | 16 + README.md | 134 +- global.json | 5 + 1059 files changed, 232665 insertions(+), 2 deletions(-) create mode 100644 CodeSmith/CSharp/ApiGenerate.cst create mode 100644 CodeSmith/CSharp/ApiGenerate/Application.cst create mode 100644 CodeSmith/CSharp/ApiGenerate/Controller.cst create mode 100644 CodeSmith/CSharp/ApiGenerate/ModifyReq.cst create mode 100644 CodeSmith/CSharp/ApiGenerate/Request.cst create mode 100644 CodeSmith/CSharp/Internal/Context.Generated.cst create mode 100644 CodeSmith/CSharp/Internal/Entity.Generated.cst create mode 100644 CodeSmith/CSharp/Internal/Extensions.cs create mode 100644 CodeSmith/CSharp/Internal/Generator.cs create mode 100644 CodeSmith/CSharp/Internal/Model.cs create mode 100644 CodeSmith/CSharp/Internal/Parser.cs create mode 100644 CodeSmith/CSharp/Web/Controller.cst create mode 100644 CodeSmith/CSharp/Web/Index.cshtml.cst create mode 100644 CodeSmith/CSharp/Web/Util.cs create mode 100644 CodeSmith/CSharp/Web/index.js.cst create mode 100644 CodeSmith/CSharp/WebGenerate.cst create mode 100644 CodeSmith/Common/ICSharpCode.NRefactory.CSharp.dll create mode 100644 CodeSmith/Common/ICSharpCode.NRefactory.dll create mode 100644 CodeSmith/Common/Mono.Cecil.dll create mode 100644 Dockerfile create mode 100644 Infrastructure/AppSetting.cs create mode 100644 Infrastructure/AutoMapperExt.cs create mode 100644 Infrastructure/Cache/CacheContext.cs create mode 100644 Infrastructure/Cache/EnyimMemcachedContext.cs create mode 100644 Infrastructure/Cache/ICacheContext.cs create mode 100644 Infrastructure/Cache/RedisCacheContext.cs create mode 100644 Infrastructure/CommonException.cs create mode 100644 Infrastructure/Const/FlowInstanceStatus.cs create mode 100644 Infrastructure/Const/HtmlElementType.cs create mode 100644 Infrastructure/Const/JobStatus.cs create mode 100644 Infrastructure/Const/LinqExpressionType.cs create mode 100644 Infrastructure/Const/QueryOrderBy.cs create mode 100644 Infrastructure/Const/ResponseType.cs create mode 100644 Infrastructure/Const/SqlDbTypeName.cs create mode 100644 Infrastructure/Database/DbDataConvertExtensions.cs create mode 100644 Infrastructure/Define.cs create mode 100644 Infrastructure/DynamicLinq.cs create mode 100644 Infrastructure/DynamicQueryable.cs create mode 100644 Infrastructure/Encryption.cs create mode 100644 Infrastructure/Extensions/AutofacManager/AutofacContainerModule.cs create mode 100644 Infrastructure/Extensions/AutofacManager/IDependency.cs create mode 100644 Infrastructure/Extensions/ConvertJsonExtension.cs create mode 100644 Infrastructure/Extensions/DateTimeExtension.cs create mode 100644 Infrastructure/Extensions/EntityProperties.cs create mode 100644 Infrastructure/Extensions/EnumTypeExtention.cs create mode 100644 Infrastructure/Extensions/ExtensionsJson.cs create mode 100644 Infrastructure/Extensions/GenericExtension.cs create mode 100644 Infrastructure/Extensions/LambdaExtensions.cs create mode 100644 Infrastructure/Extensions/ObjectExtension.cs create mode 100644 Infrastructure/Extensions/SecurityEncDecryptExtension.cs create mode 100644 Infrastructure/Extensions/ServerExtension.cs create mode 100644 Infrastructure/Extensions/StringExtension.cs create mode 100644 Infrastructure/Filter.cs create mode 100644 Infrastructure/GenerateId.cs create mode 100644 Infrastructure/Helpers/AESHelper.cs create mode 100644 Infrastructure/Helpers/CommonHelper.cs create mode 100644 Infrastructure/Helpers/ConfigHelper.cs create mode 100644 Infrastructure/Helpers/DateTimeHelper.cs create mode 100644 Infrastructure/Helpers/Excel/ExcelConfig.cs create mode 100644 Infrastructure/Helpers/Excel/ExcelHelper.cs create mode 100644 Infrastructure/Helpers/Excel/Model/ColumnModel.cs create mode 100644 Infrastructure/Helpers/FileHelper.cs create mode 100644 Infrastructure/Helpers/GenericHelper.cs create mode 100644 Infrastructure/Helpers/HIKOpenAPI.cs create mode 100644 Infrastructure/Helpers/HttpHelper.cs create mode 100644 Infrastructure/Helpers/HttpMethods.cs create mode 100644 Infrastructure/Helpers/ImageHelper.cs create mode 100644 Infrastructure/Helpers/ImgHelper.cs create mode 100644 Infrastructure/Helpers/Md5.cs create mode 100644 Infrastructure/Helpers/Md5Helper.cs create mode 100644 Infrastructure/Helpers/ObjectHelper.cs create mode 100644 Infrastructure/Helpers/WordHelper.cs create mode 100644 Infrastructure/Helpers/XmlHelper.cs create mode 100644 Infrastructure/Infrastructure.csproj create mode 100644 Infrastructure/Json.cs create mode 100644 Infrastructure/JsonConverter.cs create mode 100644 Infrastructure/JsonHelper.cs create mode 100644 Infrastructure/KeyDescription.cs create mode 100644 Infrastructure/Middleware/IApplicationBuilderExtension.cs create mode 100644 Infrastructure/Middleware/RequestResponseLoggingMiddleware.cs create mode 100644 Infrastructure/PredicateBuilder.cs create mode 100644 Infrastructure/Provider/PathProvider.cs create mode 100644 Infrastructure/Response.cs create mode 100644 Infrastructure/Snowflake/Contract/IIdGenerator.cs create mode 100644 Infrastructure/Snowflake/Contract/ISnowWorker.cs create mode 100644 Infrastructure/Snowflake/Contract/IdGeneratorOptions.cs create mode 100644 Infrastructure/Snowflake/Contract/OverCostActionArg.cs create mode 100644 Infrastructure/Snowflake/Core/SnowWorkerM1.cs create mode 100644 Infrastructure/Snowflake/Core/SnowWorkerM2.cs create mode 100644 Infrastructure/Snowflake/Core/SnowWorkerM3.cs create mode 100644 Infrastructure/Snowflake/DefaultIdGenerator.cs create mode 100644 Infrastructure/Snowflake/YitIdHelper.cs create mode 100644 Infrastructure/Test/TestAutoMapper.cs create mode 100644 Infrastructure/Test/TestDynamicLinq.cs create mode 100644 Infrastructure/Test/TestSnowflake.cs create mode 100644 Infrastructure/TreeItem.cs create mode 100644 Infrastructure/Utilities/DESEncrypt.cs create mode 100644 Infrastructure/Utilities/DynamicPropertyBag .cs create mode 100644 Infrastructure/Utilities/HttpContextUtil.cs create mode 100644 Infrastructure/Utilities/HttpManager.cs create mode 100644 Infrastructure/Utilities/ProjectPath.cs create mode 100644 Infrastructure/Utilities/ResponseMsg.cs create mode 100644 Infrastructure/Utilities/UriUtil.cs create mode 100644 Infrastructure/Utilities/WebResponseContent.cs create mode 100644 Infrastructure/log4net.config create mode 100644 OpenAuth.App/AuthContextFactory.cs create mode 100644 OpenAuth.App/AutofacExt.cs create mode 100644 OpenAuth.App/BaseApp/AppManager/AppManager.cs create mode 100644 OpenAuth.App/BaseApp/AppManager/Request/QueryAppListReq.cs create mode 100644 OpenAuth.App/BaseApp/AuthStrategies/AuthStrategyContext.cs create mode 100644 OpenAuth.App/BaseApp/AuthStrategies/NormalAuthStrategy.cs create mode 100644 OpenAuth.App/BaseApp/AuthStrategies/SystemAuthStrategy.cs create mode 100644 OpenAuth.App/BaseApp/Base/IdRequest.cs create mode 100644 OpenAuth.App/BaseApp/Base/PageReq.cs create mode 100644 OpenAuth.App/BaseApp/Base/SqlSugarBaseApp.cs create mode 100644 OpenAuth.App/BaseApp/Base/TableData.cs create mode 100644 OpenAuth.App/BaseApp/Base/TableResp.cs create mode 100644 OpenAuth.App/BaseApp/Base/Tree/LongTreeApp.cs create mode 100644 OpenAuth.App/BaseApp/Base/Tree/StringTreeApp.cs create mode 100644 OpenAuth.App/BaseApp/Base/Tree/TreeApp.cs create mode 100644 OpenAuth.App/BaseApp/Base/Tree/TreeExtensions.cs create mode 100644 OpenAuth.App/BaseApp/BasicQueryService/CommonDataManager.cs create mode 100644 OpenAuth.App/BaseApp/BasicQueryService/PositionManager.cs create mode 100644 OpenAuth.App/BaseApp/BasicQueryService/Request/QueryGeoJsonCommonReq.cs create mode 100644 OpenAuth.App/BaseApp/BasicQueryService/Request/QueryVectorTileByTableReq.cs create mode 100644 OpenAuth.App/BaseApp/BasicQueryService/Request/VectorTileSearchModel.cs create mode 100644 OpenAuth.App/BaseApp/BasicQueryService/UserManager.cs create mode 100644 OpenAuth.App/BaseApp/BasicQueryService/WorkFlowMangaer.cs create mode 100644 OpenAuth.App/BaseApp/Category/CategoryApp.cs create mode 100644 OpenAuth.App/BaseApp/Category/CategoryTypeApp.cs create mode 100644 OpenAuth.App/BaseApp/Category/Request/AddOrUpdateCategoryReq.cs create mode 100644 OpenAuth.App/BaseApp/Category/Request/AddOrUpdateCategoryTypeReq.cs create mode 100644 OpenAuth.App/BaseApp/Category/Request/QueryCategoryListReq.cs create mode 100644 OpenAuth.App/BaseApp/Category/Request/QueryCategoryTypeListReq.cs create mode 100644 OpenAuth.App/BaseApp/Category/Response/CategoryTypeResp.cs create mode 100644 OpenAuth.App/BaseApp/CodeTable/CodeColumnsApp.cs create mode 100644 OpenAuth.App/BaseApp/CodeTable/CodeTableApp.cs create mode 100644 OpenAuth.App/BaseApp/CodeTable/Request/CodeTableReq.cs create mode 100644 OpenAuth.App/BaseApp/CodeTable/Response/CodeTableColumnsResp.cs create mode 100644 OpenAuth.App/BaseApp/CreateTable/BasicTableService.cs create mode 100644 OpenAuth.App/BaseApp/CreateTable/CreateTableReq.cs create mode 100644 OpenAuth.App/BaseApp/CreateTable/CreateViewReq.cs create mode 100644 OpenAuth.App/BaseApp/CreateTable/TableInfo.cs create mode 100644 OpenAuth.App/BaseApp/CreateTable/TableRecordApp.cs create mode 100644 OpenAuth.App/BaseApp/CreateTable/UploadExcelReq.cs create mode 100644 OpenAuth.App/BaseApp/DataCodeRule/CodeRuleApp.cs create mode 100644 OpenAuth.App/BaseApp/DataCodeRule/Response/CodeRuleFormatModel.cs create mode 100644 OpenAuth.App/BaseApp/DataSource/DataSourceApp.cs create mode 100644 OpenAuth.App/BaseApp/DbTable/DbTableApp.cs create mode 100644 OpenAuth.App/BaseApp/DbTable/Request/DbColumnInput.cs create mode 100644 OpenAuth.App/BaseApp/DbTable/Request/DbTableReq.cs create mode 100644 OpenAuth.App/BaseApp/Extensions/OpenJobExt.cs create mode 100644 OpenAuth.App/BaseApp/Files/FileApp.cs create mode 100644 OpenAuth.App/BaseApp/Files/Request/QueryFileListReq.cs create mode 100644 OpenAuth.App/BaseApp/FormModule/FormModuleApp.cs create mode 100644 OpenAuth.App/BaseApp/FormModule/Request/FormModuleReq.cs create mode 100644 OpenAuth.App/BaseApp/FormModule/Request/FormModuleSchemeReq.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/FormHelpers/DBCommonHelper.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/FormHelpers/FormHelper.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/FormSchemeApp.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Request/FormDataReq.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Request/FormQueryReq.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Request/FormSchemeReq.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/ComponentPropsModel.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/ExecuteType.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormComponentModel.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormComponentNewModel.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormDbTable.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormDbTableInfo.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormInfoModel.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormInfoNewModel.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormSchemeModel.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormSchemeNewModel.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormTabModel.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/FormTabNewModel.cs create mode 100644 OpenAuth.App/BaseApp/FormScheme/Response/PaginationInputDto.cs create mode 100644 OpenAuth.App/BaseApp/HostedService/QuartzService.cs create mode 100644 OpenAuth.App/BaseApp/ImMsgManager/ChatsHub.cs create mode 100644 OpenAuth.App/BaseApp/ImMsgManager/ImMsgApp.cs create mode 100644 OpenAuth.App/BaseApp/ImMsgManager/Request/ImMsgReq.cs create mode 100644 OpenAuth.App/BaseApp/ImMsgManager/SendHubs.cs create mode 100644 OpenAuth.App/BaseApp/Import/ImportApp.cs create mode 100644 OpenAuth.App/BaseApp/Import/Response/ExcelImportDto.cs create mode 100644 OpenAuth.App/BaseApp/Interface/IAuth.cs create mode 100644 OpenAuth.App/BaseApp/Interface/IAuthStrategy.cs create mode 100644 OpenAuth.App/BaseApp/Interface/ICustomerForm.cs create mode 100644 OpenAuth.App/BaseApp/Jobs/OpenJobApp.cs create mode 100644 OpenAuth.App/BaseApp/Jobs/Request/AddOrUpdateOpenJobReq.cs create mode 100644 OpenAuth.App/BaseApp/Jobs/Request/ChangeJobStatusReq.cs create mode 100644 OpenAuth.App/BaseApp/Jobs/Request/QueryOpenJobListReq.cs create mode 100644 OpenAuth.App/BaseApp/Jobs/SysLogJob.cs create mode 100644 OpenAuth.App/BaseApp/Jobs/TaskOverTimeJob.cs create mode 100644 OpenAuth.App/BaseApp/Jobs/TaskTimeoutJob.cs create mode 100644 OpenAuth.App/BaseApp/ModuleManager/ModuleManagerApp.cs create mode 100644 OpenAuth.App/BaseApp/ModuleManager/Request/QueryElementListReq.cs create mode 100644 OpenAuth.App/BaseApp/ModuleManager/Response/ModuleElementVM.cs create mode 100644 OpenAuth.App/BaseApp/ModuleManager/Response/ModuleView.cs create mode 100644 OpenAuth.App/BaseApp/ModuleManager/Response/ModulesWithElements.cs create mode 100644 OpenAuth.App/BaseApp/OrgManager/OrgManagerApp.cs create mode 100644 OpenAuth.App/BaseApp/OrgManager/Request/AssignOrgPosGroup.cs create mode 100644 OpenAuth.App/BaseApp/OrgManager/Request/OrgForm.cs create mode 100644 OpenAuth.App/BaseApp/OrgManager/Request/OrgPos.cs create mode 100644 OpenAuth.App/BaseApp/OrgManager/Request/QueryOrgListReq.cs create mode 100644 OpenAuth.App/BaseApp/Permission/BaseDataAuthorizeApp.cs create mode 100644 OpenAuth.App/BaseApp/Permission/Request/BaseDataAuthListReq.cs create mode 100644 OpenAuth.App/BaseApp/Permission/Request/BaseDataAuthReq.cs create mode 100644 OpenAuth.App/BaseApp/Permission/Request/Condition.cs create mode 100644 OpenAuth.App/BaseApp/Permission/Request/FormulaObject.cs create mode 100644 OpenAuth.App/BaseApp/Permission/Request/Group.cs create mode 100644 OpenAuth.App/BaseApp/Relevance/Request/AssignDataReq.cs create mode 100644 OpenAuth.App/BaseApp/Relevance/Request/AssignOrgUsers.cs create mode 100644 OpenAuth.App/BaseApp/Relevance/Request/AssignReq.cs create mode 100644 OpenAuth.App/BaseApp/Relevance/Request/AssignRoleUsers.cs create mode 100644 OpenAuth.App/BaseApp/Relevance/RevelanceManagerApp.cs create mode 100644 OpenAuth.App/BaseApp/Resources/Request/AddOrUpdateResReq.cs create mode 100644 OpenAuth.App/BaseApp/Resources/Request/QueryResourcesReq.cs create mode 100644 OpenAuth.App/BaseApp/Resources/ResourceApp.cs create mode 100644 OpenAuth.App/BaseApp/RoleManager/Request/ModuleElementWithRole.cs create mode 100644 OpenAuth.App/BaseApp/RoleManager/Request/QueryRoleListReq.cs create mode 100644 OpenAuth.App/BaseApp/RoleManager/Response/RoleView.cs create mode 100644 OpenAuth.App/BaseApp/RoleManager/RoleApp.cs create mode 100644 OpenAuth.App/BaseApp/SSO/LocalAuth.cs create mode 100644 OpenAuth.App/BaseApp/SSO/LoginParse.cs create mode 100644 OpenAuth.App/BaseApp/SSO/LoginResult.cs create mode 100644 OpenAuth.App/BaseApp/SSO/PassportLoginRequest.cs create mode 100644 OpenAuth.App/BaseApp/SSO/UserAuthSession.cs create mode 100644 OpenAuth.App/BaseApp/SysAppFiles/SysAppFilesApp.cs create mode 100644 OpenAuth.App/BaseApp/SysDataItem/SysDataItemApp.cs create mode 100644 OpenAuth.App/BaseApp/SysDataItemDetail/SysDataItemDetailApp.cs create mode 100644 OpenAuth.App/BaseApp/SysDatabaseLink/Response/TreeModel.cs create mode 100644 OpenAuth.App/BaseApp/SysDatabaseLink/SysDatabaseLinkApp.cs create mode 100644 OpenAuth.App/BaseApp/SysLogs/Request/QuerySysLogListReq.cs create mode 100644 OpenAuth.App/BaseApp/SysLogs/SysLogApp.cs create mode 100644 OpenAuth.App/BaseApp/SysMessage/Request/QuerySysMessageListReq.cs create mode 100644 OpenAuth.App/BaseApp/SysMessage/SysMessageApp.cs create mode 100644 OpenAuth.App/BaseApp/SysPosGroup/Request/PosGroupForm.cs create mode 100644 OpenAuth.App/BaseApp/SysPosGroup/SysPosGroupApp.cs create mode 100644 OpenAuth.App/BaseApp/SysPosition/Request/QueryPositonListReq.cs create mode 100644 OpenAuth.App/BaseApp/SysPosition/SysPositionApp.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/Request/AssignUserOrgs.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/Request/AssignUserRoles.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/Request/ChangePasswordReq.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/Request/ChangeProfileReq.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/Request/QueryUserListByOrgReq.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/Request/QueryUserListByRoleReq.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/Request/QueryUserListReq.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/Request/UpdateUserReq.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/Response/UserView.cs create mode 100644 OpenAuth.App/BaseApp/UserManager/UserManagerApp.cs create mode 100644 OpenAuth.App/BaseApp/WFDelegate/Request/WFDelegateDto.cs create mode 100644 OpenAuth.App/BaseApp/WFDelegate/WFDelegateApp.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/Config/WFDelegate.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/Config/WFEngineConfig.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/Config/WFParams.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/Config/WFUserInfo.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/IWFEngine.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/IWorkFlowMethod.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/NodeTypeEnum.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/Request/WFProcessDto.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/Request/WFProcessPointDto.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/Request/WFProcessSearchDto.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/Response/BPMNWFTaskDto.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/WFAuditor.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/WFCondition.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/WFEngine.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/WFProcessApp.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/WFProcessApp1.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/WFScheme.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/WFTask.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/WFUnit.cs create mode 100644 OpenAuth.App/BaseApp/WFProcess/WfMethodParameter.cs create mode 100644 OpenAuth.App/BaseApp/WFSchemeInfo/Response/WFSchemeDto.cs create mode 100644 OpenAuth.App/BaseApp/WFSchemeInfo/WFSchemeApp.cs create mode 100644 OpenAuth.App/BaseApp/WFSchemeInfo/WFSchemeInfoApp.cs create mode 100644 OpenAuth.App/BaseApp/WFStamp/WFStampApp.cs create mode 100644 OpenAuth.App/BaseApp/WFTask/Request/WFTaskDto.cs create mode 100644 OpenAuth.App/BaseApp/WFTask/Response/ExtendInfo.cs create mode 100644 OpenAuth.App/BaseApp/WFTask/Response/RetractRes.cs create mode 100644 OpenAuth.App/BaseApp/WFTask/WFTaskApp.cs create mode 100644 OpenAuth.App/Common/CommonData.cs create mode 100644 OpenAuth.App/Const/TubanZhuanTi.cs create mode 100644 OpenAuth.App/DbExtension.cs create mode 100644 OpenAuth.App/OpenAuth.App.csproj create mode 100644 OpenAuth.Identity/Config.cs create mode 100644 OpenAuth.Identity/CustomProfileService.cs create mode 100644 OpenAuth.Identity/OpenAuth.IdentityServer.csproj create mode 100644 OpenAuth.Identity/Program.cs create mode 100644 OpenAuth.Identity/Properties/launchSettings.json create mode 100644 OpenAuth.Identity/Quickstart/Account/AccountController.cs create mode 100644 OpenAuth.Identity/Quickstart/Account/AccountOptions.cs create mode 100644 OpenAuth.Identity/Quickstart/Account/ExternalController.cs create mode 100644 OpenAuth.Identity/Quickstart/Account/ExternalProvider.cs create mode 100644 OpenAuth.Identity/Quickstart/Account/LoggedOutViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Account/LoginInputModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Account/LoginViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Account/LogoutInputModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Account/LogoutViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Account/RedirectViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Consent/ConsentController.cs create mode 100644 OpenAuth.Identity/Quickstart/Consent/ConsentInputModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Consent/ConsentOptions.cs create mode 100644 OpenAuth.Identity/Quickstart/Consent/ConsentViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Consent/ProcessConsentResult.cs create mode 100644 OpenAuth.Identity/Quickstart/Consent/ScopeViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Device/DeviceAuthorizationInputModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Device/DeviceAuthorizationViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Device/DeviceController.cs create mode 100644 OpenAuth.Identity/Quickstart/Diagnostics/DiagnosticsController.cs create mode 100644 OpenAuth.Identity/Quickstart/Diagnostics/DiagnosticsViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Extensions.cs create mode 100644 OpenAuth.Identity/Quickstart/Grants/GrantsController.cs create mode 100644 OpenAuth.Identity/Quickstart/Grants/GrantsViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Home/ErrorViewModel.cs create mode 100644 OpenAuth.Identity/Quickstart/Home/HomeController.cs create mode 100644 OpenAuth.Identity/Quickstart/SecurityHeadersAttribute.cs create mode 100644 OpenAuth.Identity/Quickstart/TestUsers.cs create mode 100644 OpenAuth.Identity/SameSiteCookiesServiceCollectionExtensions.cs create mode 100644 OpenAuth.Identity/Startup.cs create mode 100644 OpenAuth.Identity/Views/Account/AccessDenied.cshtml create mode 100644 OpenAuth.Identity/Views/Account/LoggedOut.cshtml create mode 100644 OpenAuth.Identity/Views/Account/Login.cshtml create mode 100644 OpenAuth.Identity/Views/Account/Logout.cshtml create mode 100644 OpenAuth.Identity/Views/Consent/Index.cshtml create mode 100644 OpenAuth.Identity/Views/Device/Success.cshtml create mode 100644 OpenAuth.Identity/Views/Device/UserCodeCapture.cshtml create mode 100644 OpenAuth.Identity/Views/Device/UserCodeConfirmation.cshtml create mode 100644 OpenAuth.Identity/Views/Diagnostics/Index.cshtml create mode 100644 OpenAuth.Identity/Views/Grants/Index.cshtml create mode 100644 OpenAuth.Identity/Views/Home/Index.cshtml create mode 100644 OpenAuth.Identity/Views/Shared/Error.cshtml create mode 100644 OpenAuth.Identity/Views/Shared/Redirect.cshtml create mode 100644 OpenAuth.Identity/Views/Shared/_Layout.cshtml create mode 100644 OpenAuth.Identity/Views/Shared/_ScopeListItem.cshtml create mode 100644 OpenAuth.Identity/Views/Shared/_ValidationSummary.cshtml create mode 100644 OpenAuth.Identity/Views/_ViewImports.cshtml create mode 100644 OpenAuth.Identity/Views/_ViewStart.cshtml create mode 100644 OpenAuth.Identity/appsettings.Development.json create mode 100644 OpenAuth.Identity/appsettings.Production.json create mode 100644 OpenAuth.Identity/appsettings.json create mode 100644 OpenAuth.Identity/tempkey.jwk create mode 100644 OpenAuth.Identity/tempkey.rsa create mode 100644 OpenAuth.Identity/wwwroot/css/site.css create mode 100644 OpenAuth.Identity/wwwroot/css/site.less create mode 100644 OpenAuth.Identity/wwwroot/css/site.min.css create mode 100644 OpenAuth.Identity/wwwroot/favicon.ico create mode 100644 OpenAuth.Identity/wwwroot/icon.jpg create mode 100644 OpenAuth.Identity/wwwroot/icon.png create mode 100644 OpenAuth.Identity/wwwroot/js/signin-redirect.js create mode 100644 OpenAuth.Identity/wwwroot/js/signout-redirect.js create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-ie6.css create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-ie6.min.css create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-responsive.css create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-responsive.min.css create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.css create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.css.map create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.min.css create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.min.css.map create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.css create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.css.map create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.min.css create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.min.css.map create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/css/ie.css create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.eot create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.svg create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/img/glyphicons-halflings-white.png create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/img/glyphicons-halflings.png create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/js/bootstrap.js create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/js/bootstrap.min.js create mode 100644 OpenAuth.Identity/wwwroot/lib/bootstrap/js/npm.js create mode 100644 OpenAuth.Identity/wwwroot/lib/jquery/jquery.js create mode 100644 OpenAuth.Identity/wwwroot/lib/jquery/jquery.min.js create mode 100644 OpenAuth.Identity/wwwroot/lib/jquery/jquery.min.map create mode 100644 OpenAuth.Mvc/Controllers/AccessObjsController.cs create mode 100644 OpenAuth.Mvc/Controllers/ApplicationsController.cs create mode 100644 OpenAuth.Mvc/Controllers/BaseController.cs create mode 100644 OpenAuth.Mvc/Controllers/CategoriesController.cs create mode 100644 OpenAuth.Mvc/Controllers/ErrorController.cs create mode 100644 OpenAuth.Mvc/Controllers/FilesController.cs create mode 100644 OpenAuth.Mvc/Controllers/HomeController.cs create mode 100644 OpenAuth.Mvc/Controllers/LoginController.cs create mode 100644 OpenAuth.Mvc/Controllers/ModuleManagerController.cs create mode 100644 OpenAuth.Mvc/Controllers/OpenJobsController.cs create mode 100644 OpenAuth.Mvc/Controllers/OrgManagerController.cs create mode 100644 OpenAuth.Mvc/Controllers/RedirectsController.cs create mode 100644 OpenAuth.Mvc/Controllers/ResourcesController.cs create mode 100644 OpenAuth.Mvc/Controllers/RoleManagerController.cs create mode 100644 OpenAuth.Mvc/Controllers/SysConfController.cs create mode 100644 OpenAuth.Mvc/Controllers/SysLogsController.cs create mode 100644 OpenAuth.Mvc/Controllers/SysMessagesController.cs create mode 100644 OpenAuth.Mvc/Controllers/UserManagerController.cs create mode 100644 OpenAuth.Mvc/Controllers/UserSessionController.cs create mode 100644 OpenAuth.Mvc/Models/JobjectModelBinder.cs create mode 100644 OpenAuth.Mvc/Models/JsonBinderProvider.cs create mode 100644 OpenAuth.Mvc/Models/OpenAuthFilter.cs create mode 100644 OpenAuth.Mvc/OpenAuth.Mvc.csproj create mode 100644 OpenAuth.Mvc/Program.cs create mode 100644 OpenAuth.Mvc/Properties/launchSettings.json create mode 100644 OpenAuth.Mvc/Startup.cs create mode 100644 OpenAuth.Mvc/Views/Categories/Index.cshtml create mode 100644 OpenAuth.Mvc/Views/Error/Auth.cshtml create mode 100644 OpenAuth.Mvc/Views/Home/Index.cshtml create mode 100644 OpenAuth.Mvc/Views/Home/Main.cshtml create mode 100644 OpenAuth.Mvc/Views/Login/Index.cshtml create mode 100644 OpenAuth.Mvc/Views/ModuleManager/Assign.cshtml create mode 100644 OpenAuth.Mvc/Views/ModuleManager/Index.cshtml create mode 100644 OpenAuth.Mvc/Views/OpenJobs/index.cshtml create mode 100644 OpenAuth.Mvc/Views/OrgManager/Index.cshtml create mode 100644 OpenAuth.Mvc/Views/Redirects/IdentityAuth.cshtml create mode 100644 OpenAuth.Mvc/Views/Resources/Assign.cshtml create mode 100644 OpenAuth.Mvc/Views/Resources/Index.cshtml create mode 100644 OpenAuth.Mvc/Views/RoleManager/Assign.cshtml create mode 100644 OpenAuth.Mvc/Views/RoleManager/Index.cshtml create mode 100644 OpenAuth.Mvc/Views/Shared/_Layout.cshtml create mode 100644 OpenAuth.Mvc/Views/SysLogs/index.cshtml create mode 100644 OpenAuth.Mvc/Views/SysMessages/index.cshtml create mode 100644 OpenAuth.Mvc/Views/UserManager/ChangePassword.cshtml create mode 100644 OpenAuth.Mvc/Views/UserManager/Index.cshtml create mode 100644 OpenAuth.Mvc/Views/UserManager/Profile.cshtml create mode 100644 OpenAuth.Mvc/Views/_ViewStart.cshtml create mode 100644 OpenAuth.Mvc/appsettings.Development.json create mode 100644 OpenAuth.Mvc/appsettings.Production.json create mode 100644 OpenAuth.Mvc/appsettings.json create mode 100644 OpenAuth.Mvc/temp-keys/key-0833ae4d-c4cc-464d-870e-4870f64321db.xml create mode 100644 OpenAuth.Mvc/temp-keys/key-628839e2-4f54-416f-9b66-23fafd007ab0.xml create mode 100644 OpenAuth.Mvc/temp-keys/key-7cb331d1-fe1a-426a-978c-b5026a8b3695.xml create mode 100644 OpenAuth.Mvc/temp-keys/key-9859d811-905a-4d9d-895d-1a2467a10a4d.xml create mode 100644 OpenAuth.Mvc/temp-keys/key-dbe172a1-9e7b-4886-a94e-de8124a4bd0d.xml create mode 100644 OpenAuth.Mvc/temp-keys/key-e3154dd2-bdca-48fc-ab68-8d4d8019070c.xml create mode 100644 OpenAuth.Mvc/wwwroot/css/formpreview.css create mode 100644 OpenAuth.Mvc/wwwroot/css/images.css create mode 100644 OpenAuth.Mvc/wwwroot/css/login.css create mode 100644 OpenAuth.Mvc/wwwroot/css/main.css create mode 100644 OpenAuth.Mvc/wwwroot/css/metroStyle/img/line_conn.png create mode 100644 OpenAuth.Mvc/wwwroot/css/metroStyle/img/loading.gif create mode 100644 OpenAuth.Mvc/wwwroot/css/metroStyle/img/metro.gif create mode 100644 OpenAuth.Mvc/wwwroot/css/metroStyle/img/metro.png create mode 100644 OpenAuth.Mvc/wwwroot/css/metroStyle/metroStyle.css create mode 100644 OpenAuth.Mvc/wwwroot/css/treetable.css create mode 100644 OpenAuth.Mvc/wwwroot/favicon.ico create mode 100644 OpenAuth.Mvc/wwwroot/images/alipay.jpg create mode 100644 OpenAuth.Mvc/wwwroot/images/code.jpg create mode 100644 OpenAuth.Mvc/wwwroot/images/face.jpg create mode 100644 OpenAuth.Mvc/wwwroot/images/login/buttonbg.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/cloud.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/hand.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/left_hand.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/light.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/loginbg1.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/loginbg2.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/loginbg3.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/logininfo.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/loginpassword.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/loginsj.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/loginuser.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/logo.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/right_hand.png create mode 100644 OpenAuth.Mvc/wwwroot/images/login/tou.png create mode 100644 OpenAuth.Mvc/wwwroot/images/logo.png create mode 100644 OpenAuth.Mvc/wwwroot/images/userface1.jpg create mode 100644 OpenAuth.Mvc/wwwroot/images/userface2.jpg create mode 100644 OpenAuth.Mvc/wwwroot/images/userface3.jpg create mode 100644 OpenAuth.Mvc/wwwroot/images/userface4.jpg create mode 100644 OpenAuth.Mvc/wwwroot/images/userface5.jpg create mode 100644 OpenAuth.Mvc/wwwroot/images/wechat.jpg create mode 100644 OpenAuth.Mvc/wwwroot/js/bodyTab.js create mode 100644 OpenAuth.Mvc/wwwroot/js/bootstrap.js create mode 100644 OpenAuth.Mvc/wwwroot/js/cookie.js create mode 100644 OpenAuth.Mvc/wwwroot/js/droptree.js create mode 100644 OpenAuth.Mvc/wwwroot/js/dtree.js create mode 100644 OpenAuth.Mvc/wwwroot/js/dtree/dtree.css create mode 100644 OpenAuth.Mvc/wwwroot/js/dtree/font/dtreefont.css create mode 100644 OpenAuth.Mvc/wwwroot/js/dtree/font/dtreefont.eot create mode 100644 OpenAuth.Mvc/wwwroot/js/dtree/font/dtreefont.svg create mode 100644 OpenAuth.Mvc/wwwroot/js/dtree/font/dtreefont.ttf create mode 100644 OpenAuth.Mvc/wwwroot/js/dtree/font/dtreefont.woff create mode 100644 OpenAuth.Mvc/wwwroot/js/dtree/font/icons.json create mode 100644 OpenAuth.Mvc/wwwroot/js/dtree/开发者日志.txt create mode 100644 OpenAuth.Mvc/wwwroot/js/flow-ui/img/wallbg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/GooFlow.css create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/GooFlow.export.js create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/GooFlow.print.js create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/GooFunc.js create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/config.js create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/demo.css create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/demo_fontclass.html create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/demo_symbol.html create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/demo_unicode.html create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/iconflow.eot create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/iconflow.svg create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/iconflow.ttf create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/iconflow.woff create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/iconfont.css create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/fonts/iconfont.js create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/gooflow.js create mode 100644 OpenAuth.Mvc/wwwroot/js/flow/img/gooflow_icon.png create mode 100644 OpenAuth.Mvc/wwwroot/js/flowlayout.js create mode 100644 OpenAuth.Mvc/wwwroot/js/formSelects/formSelects.css create mode 100644 OpenAuth.Mvc/wwwroot/js/formSelects/formSelects.js create mode 100644 OpenAuth.Mvc/wwwroot/js/iconPicker.js create mode 100644 OpenAuth.Mvc/wwwroot/js/index.js create mode 100644 OpenAuth.Mvc/wwwroot/js/leftNav.js create mode 100644 OpenAuth.Mvc/wwwroot/js/openauth.js create mode 100644 OpenAuth.Mvc/wwwroot/js/slimscroll.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/anchor/anchor.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/attachment.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/attachment.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/attachment.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_chm.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_default.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_doc.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_exe.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_jpg.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_mp3.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_mv.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_pdf.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_ppt.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_psd.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_rar.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_txt.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/fileTypeImages/icon_xls.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/alignicon.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/alignicon.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/bg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/file-icons.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/file-icons.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/icons.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/icons.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/image.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/progress.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/success.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/attachment/images/success.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/background/background.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/background/background.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/background/background.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/background/images/bg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/background/images/success.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/chart.config.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/charts.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/charts.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/charts.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/images/charts0.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/images/charts1.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/images/charts2.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/images/charts3.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/images/charts4.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/charts/images/charts5.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/emotion.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/emotion.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/emotion.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/images/0.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/images/bface.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/images/cface.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/images/fface.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/images/jxface2.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/images/neweditor-tab-bg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/images/tface.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/images/wface.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/emotion/images/yface.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/gmap/gmap.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/help/help.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/help/help.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/help/help.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/image.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/image.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/image.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/images/alignicon.jpg create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/images/bg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/images/icons.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/images/icons.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/images/image.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/images/progress.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/images/success.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/image/images/success.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/insertframe/insertframe.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/internal.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/link/link.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/map/map.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/map/show.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/music/music.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/music/music.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/music/music.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/preview/preview.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/addimg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/brush.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/delimg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/delimgH.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/empty.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/emptyH.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/eraser.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/redo.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/redoH.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/scale.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/scaleH.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/size.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/undo.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/images/undoH.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/scrawl.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/scrawl.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/scrawl/scrawl.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/searchreplace/searchreplace.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/searchreplace/searchreplace.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/snapscreen/snapscreen.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/spechars/spechars.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/spechars/spechars.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/table/dragicon.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/table/edittable.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/table/edittable.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/table/edittable.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/table/edittd.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/table/edittip.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/config.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/images/bg.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/images/pre0.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/images/pre1.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/images/pre2.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/images/pre3.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/images/pre4.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/template.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/template.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/template/template.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/bg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/center_focus.jpg create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/file-icons.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/file-icons.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/icons.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/icons.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/image.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/left_focus.jpg create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/none_focus.jpg create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/progress.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/right_focus.jpg create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/success.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/images/success.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/video.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/video.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/video/video.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/webapp/webapp.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/wordimage/fClipboard_ueditor.swf create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/wordimage/imageUploader.swf create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/wordimage/tangram.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/wordimage/wordimage.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/dialogs/wordimage/wordimage.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/Readme.txt create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap-ie.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/css/bootstrap-ie6.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/css/bootstrap-ie6.min.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/css/bootstrap-responsive.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/css/bootstrap-responsive.min.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/css/bootstrap.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/css/bootstrap.min.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/css/ie.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/img/glyphicons-halflings-white.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/img/glyphicons-halflings.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/js/bootstrap.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/bootstrap/js/bootstrap.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/checkbox.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/checkboxs.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/error.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/images/leipi_formdesign.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/images/progressbar.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/images/qrcode.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/images/template/bg.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/images/template/pre0.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/images/template/pre1.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/jquery-1.7.2.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/leipi.formdesign.v4.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/leipi.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/leipi.style.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/listctrl.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/macros.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/more.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/progressbar.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/qrcode.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/radio.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/radios.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/select.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/template.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/text.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/textarea.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/formdesign/textfield.html.ajax.bak create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/index.html create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/en.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/addimage.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/alldeletebtnhoverskin.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/alldeletebtnupskin.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/background.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/button.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/copy.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/deletedisable.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/deleteenable.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/listbackground.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/localimage.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/music.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/rotateleftdisable.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/rotateleftenable.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/rotaterightdisable.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/rotaterightenable.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/en/images/upload.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/zh-cn/images/copy.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/zh-cn/images/localimage.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/zh-cn/images/music.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/zh-cn/images/upload.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/lang/zh-cn/zh-cn.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/css/ueditor.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/css/ueditor.min.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/dialogbase.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/anchor.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/arrow.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/arrow_down.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/arrow_up.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/button-bg.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/cancelbutton.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/charts.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/cursor_h.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/cursor_h.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/cursor_v.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/cursor_v.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/dialog-title-bg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/filescan.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/highlighted.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/icons-all.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/icons.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/icons.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/loaderror.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/loading.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/lock.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/neweditor-tab-bg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/pagebreak.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/scale.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/sortable.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/spacer.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/sparator_v.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/table-cell-align.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/tangram-colorpicker.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/toolbar_bg.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/unhighlighted.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/upload.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/videologo.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/word.gif create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/default/images/wordpaste.png create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/themes/iframe.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/codemirror/codemirror.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/codemirror/codemirror.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/Uploader.swf create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.css create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.custom.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.custom.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.flashonly.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.flashonly.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.html5only.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.html5only.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.withoutimage.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/webuploader/webuploader.withoutimage.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/zeroclipboard/ZeroClipboard.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/zeroclipboard/ZeroClipboard.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/third-party/zeroclipboard/ZeroClipboard.swf create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/ueditor.all.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/ueditor.all.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/ueditor.config.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/ueditor.parse.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ueditor/ueditor.parse.min.js create mode 100644 OpenAuth.Mvc/wwwroot/js/utils.js create mode 100644 OpenAuth.Mvc/wwwroot/js/vue.js create mode 100644 OpenAuth.Mvc/wwwroot/js/vue2.6.10.js create mode 100644 OpenAuth.Mvc/wwwroot/js/ztree.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/layui.css create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/layui.mobile.css create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/code.css create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/laydate/default/font.css create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/laydate/default/laydate.css create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/laydate/icon.png create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/laydate/laydate.css create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/layer/default/icon-ext.png create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/layer/default/icon.png create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/layer/default/layer.css create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/layer/default/loading-0.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/layer/default/loading-1.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/css/modules/layer/default/loading-2.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/font/iconfont.eot create mode 100644 OpenAuth.Mvc/wwwroot/layui/font/iconfont.svg create mode 100644 OpenAuth.Mvc/wwwroot/layui/font/iconfont.ttf create mode 100644 OpenAuth.Mvc/wwwroot/layui/font/iconfont.woff create mode 100644 OpenAuth.Mvc/wwwroot/layui/font/iconfont.woff2 create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/0.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/1.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/10.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/11.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/12.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/13.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/14.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/15.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/16.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/17.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/18.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/19.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/2.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/20.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/21.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/22.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/23.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/24.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/25.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/26.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/27.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/28.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/29.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/3.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/30.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/31.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/32.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/33.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/34.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/35.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/36.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/37.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/38.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/39.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/4.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/40.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/41.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/42.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/43.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/44.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/45.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/46.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/47.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/48.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/49.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/5.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/50.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/51.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/52.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/53.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/54.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/55.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/56.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/57.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/58.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/59.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/6.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/60.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/61.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/62.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/63.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/64.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/65.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/66.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/67.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/68.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/69.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/7.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/70.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/71.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/8.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/images/face/9.gif create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/dest/layui.all.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/carousel.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/code.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/colorpicker.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/element.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/flow.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/form.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/jquery.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/laydate.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/layedit.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/layer.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/layim.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/laypage.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/laytpl.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/mobile.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/rate.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/slider.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/table.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/transfer.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/tree.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/upload.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/lay/modules/util.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/layui.all.js create mode 100644 OpenAuth.Mvc/wwwroot/layui/layui.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/assignModule.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/assignResource.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/assignRole.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/categories.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/changePwd.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/dataprivilegerules.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/flowInstanceDisposed.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/flowInstanceEdit.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/flowInstanceWait.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/flowInstances.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/flowSchemeDesign.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/flowSchemePreview.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/flowSchemes.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/flowinstanceDetail.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/formEdit.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/forms.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/login.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/main.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/modules.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/nodeInfo.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/openjobs.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/orgs.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/preview.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/profile.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/resources.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/roles.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/syslogs.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/sysmessages.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/users.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/verification.js create mode 100644 OpenAuth.Mvc/wwwroot/userJs/wmsinboundordertbls.js create mode 100644 OpenAuth.Net.sln create mode 100644 OpenAuth.Repository/Core/BaseEntity.cs create mode 100644 OpenAuth.Repository/Core/Entity.cs create mode 100644 OpenAuth.Repository/Core/StringEntity.cs create mode 100644 OpenAuth.Repository/Core/TreeEntity.cs create mode 100644 OpenAuth.Repository/Core/TreeItemLong.cs create mode 100644 OpenAuth.Repository/Core/TreeItemString.cs create mode 100644 OpenAuth.Repository/Domain/DataSource.cs create mode 100644 OpenAuth.Repository/Domain/DbCodeColumns.cs create mode 100644 OpenAuth.Repository/Domain/DbCodeTable.cs create mode 100644 OpenAuth.Repository/Domain/ExcelImport.cs create mode 100644 OpenAuth.Repository/Domain/ExcelImportFileds.cs create mode 100644 OpenAuth.Repository/Domain/FormDataHistory.cs create mode 100644 OpenAuth.Repository/Domain/FormModuleEntity.cs create mode 100644 OpenAuth.Repository/Domain/FormScheme.cs create mode 100644 OpenAuth.Repository/Domain/FormSchemeInfo.cs create mode 100644 OpenAuth.Repository/Domain/ImMsg.cs create mode 100644 OpenAuth.Repository/Domain/Permission/BaseDataAuth.cs create mode 100644 OpenAuth.Repository/Domain/SysAppFiles.cs create mode 100644 OpenAuth.Repository/Domain/SysApplication.cs create mode 100644 OpenAuth.Repository/Domain/SysAreaOrg.cs create mode 100644 OpenAuth.Repository/Domain/SysCategory.cs create mode 100644 OpenAuth.Repository/Domain/SysCategoryType.cs create mode 100644 OpenAuth.Repository/Domain/SysCodeRule.cs create mode 100644 OpenAuth.Repository/Domain/SysCodeRuleSeed.cs create mode 100644 OpenAuth.Repository/Domain/SysDataItem.cs create mode 100644 OpenAuth.Repository/Domain/SysDataItemDetail.cs create mode 100644 OpenAuth.Repository/Domain/SysDatabaseLink.cs create mode 100644 OpenAuth.Repository/Domain/SysLog.cs create mode 100644 OpenAuth.Repository/Domain/SysMessage.cs create mode 100644 OpenAuth.Repository/Domain/SysModule.cs create mode 100644 OpenAuth.Repository/Domain/SysModuleColumn.cs create mode 100644 OpenAuth.Repository/Domain/SysModuleElement.cs create mode 100644 OpenAuth.Repository/Domain/SysModuleForm.cs create mode 100644 OpenAuth.Repository/Domain/SysOpenJob.cs create mode 100644 OpenAuth.Repository/Domain/SysOrg.cs create mode 100644 OpenAuth.Repository/Domain/SysPosGroup.cs create mode 100644 OpenAuth.Repository/Domain/SysPosition.cs create mode 100644 OpenAuth.Repository/Domain/SysRelevance.cs create mode 100644 OpenAuth.Repository/Domain/SysResource.cs create mode 100644 OpenAuth.Repository/Domain/SysRole.cs create mode 100644 OpenAuth.Repository/Domain/SysRoleElement.cs create mode 100644 OpenAuth.Repository/Domain/SysRoleModule.cs create mode 100644 OpenAuth.Repository/Domain/SysRoleResource.cs create mode 100644 OpenAuth.Repository/Domain/SysUploadFile.cs create mode 100644 OpenAuth.Repository/Domain/SysUser.cs create mode 100644 OpenAuth.Repository/Domain/SysUserOrg.cs create mode 100644 OpenAuth.Repository/Domain/SysUserRole.cs create mode 100644 OpenAuth.Repository/Domain/TableRecord.cs create mode 100644 OpenAuth.Repository/Domain/UserExt.cs create mode 100644 OpenAuth.Repository/Domain/WFDelegateRelation.cs create mode 100644 OpenAuth.Repository/Domain/WFDelegateRule.cs create mode 100644 OpenAuth.Repository/Domain/WFInstanceInfo.cs create mode 100644 OpenAuth.Repository/Domain/WFProcess.cs create mode 100644 OpenAuth.Repository/Domain/WFScheme.cs create mode 100644 OpenAuth.Repository/Domain/WFSchemeAuth.cs create mode 100644 OpenAuth.Repository/Domain/WFSchemeInfo.cs create mode 100644 OpenAuth.Repository/Domain/WFStamp.cs create mode 100644 OpenAuth.Repository/Domain/WFTask.cs create mode 100644 OpenAuth.Repository/Domain/WFTaskLog.cs create mode 100644 OpenAuth.Repository/Domain/WFTaskUser.cs create mode 100644 OpenAuth.Repository/ISugarRepositiry.cs create mode 100644 OpenAuth.Repository/OpenAuth.Repository.csproj create mode 100644 OpenAuth.Repository/SugarDbContext.cs create mode 100644 OpenAuth.Repository/SugarRepositiry.cs create mode 100644 OpenAuth.WebApi/.config/dotnet-tools.json create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/ApplicationsController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/CategoryTypesController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/CategorysController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/CheckController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/CodeTableController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/CreateTableController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/DataSourceController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/DbTableController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/FilesController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/FormModuleController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/FormSchemeController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/ImMsgController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/ImportController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/ModulesController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/OpenJobsController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/OrgsController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/Permission/BaseDataAuthController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/ResourcesController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/RolesController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/SysAppFilesController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/SysConfController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/SysDataItemController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/SysDataItemDetailController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/SysDatabaseLinkController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/SysLogsController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/SysMessagesController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/SysPosGroupController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/SysPositionController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/UsersController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/WFDelegateController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/WFProcessController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/WFSchemeController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/WFSchemeInfoController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/WFStampController.cs create mode 100644 OpenAuth.WebApi/Controllers/BaseControllers/WFTaskController.cs create mode 100644 OpenAuth.WebApi/Dockerfile create mode 100644 OpenAuth.WebApi/Model/AuthResponsesOperationFilter.cs create mode 100644 OpenAuth.WebApi/Model/CustomAttribute/AllDataAttribute.cs create mode 100644 OpenAuth.WebApi/Model/CustomBadRequest.cs create mode 100644 OpenAuth.WebApi/Model/GlobalExceptionFilter.cs create mode 100644 OpenAuth.WebApi/Model/GlobalHttpHeaderOperationFilter.cs create mode 100644 OpenAuth.WebApi/Model/OpenAuthFilter.cs create mode 100644 OpenAuth.WebApi/Model/TagByApiExplorerSettingsOperationFilter.cs create mode 100644 OpenAuth.WebApi/Model/TransactionFilter.cs create mode 100644 OpenAuth.WebApi/OpenAuth.WebApi.csproj create mode 100644 OpenAuth.WebApi/Program.cs create mode 100644 OpenAuth.WebApi/Properties/launchSettings.json create mode 100644 OpenAuth.WebApi/Startup.cs create mode 100644 OpenAuth.WebApi/Template/BuildControllerApi.html create mode 100644 OpenAuth.WebApi/Template/BuildEntity.html create mode 100644 OpenAuth.WebApi/Template/BuildQueryReq.html create mode 100644 OpenAuth.WebApi/Template/BuildUpdateReq.html create mode 100644 OpenAuth.WebApi/Template/BuildVueApi.html create mode 100644 OpenAuth.WebApi/Template/MultiTable/BuildVue.html create mode 100644 OpenAuth.WebApi/Template/MultiTable/BuildVue3.html create mode 100644 OpenAuth.WebApi/Template/MultiTable/BuildVue3WithDynamicHeader.html create mode 100644 OpenAuth.WebApi/Template/MultiTable/BuildVueWithDynamicHeader.html create mode 100644 OpenAuth.WebApi/Template/SingleTable/BuildApp.html create mode 100644 OpenAuth.WebApi/Template/SingleTable/BuildAppWithDynamicHeader.html create mode 100644 OpenAuth.WebApi/Template/SingleTable/BuildVue.html create mode 100644 OpenAuth.WebApi/Template/SingleTable/BuildVue3.html create mode 100644 OpenAuth.WebApi/Template/SingleTable/BuildVue3WithDynamicHeader.html create mode 100644 OpenAuth.WebApi/Template/SingleTable/BuildVueWithDynamicHeader.html create mode 100644 OpenAuth.WebApi/appsettings.Development.json create mode 100644 OpenAuth.WebApi/appsettings.Production.json create mode 100644 OpenAuth.WebApi/appsettings.json create mode 100644 OpenAuth.WebApi/dev_run.bat create mode 100644 OpenAuth.WebApi/index.html create mode 100644 OpenAuth.WebApi/temp-keys/key-0a973b95-633f-45ab-a49a-f343d72ffb73.xml create mode 100644 OpenAuth.WebApi/temp-keys/key-267d23aa-8099-45e2-9d0b-039faaea38b4.xml create mode 100644 OpenAuth.WebApi/temp-keys/key-2ddf99b6-7de3-4478-9a18-c8a6eeba1237.xml create mode 100644 OpenAuth.WebApi/temp-keys/key-5afe1848-73e8-48e3-ac95-2337e57ea148.xml create mode 100644 OpenAuth.WebApi/temp-keys/key-8e9d695c-6220-4f9c-803d-4d5698b2cc38.xml create mode 100644 OpenAuth.WebApi/temp-keys/key-a8a17770-53af-43cb-8ff9-ab1db745877d.xml create mode 100644 OpenAuth.WebApi/temp-keys/key-db096406-87a5-4967-8ab0-1203a03f7f55.xml create mode 100644 OpenAuth.WebApi/temp-keys/key-e8aef8d6-eb3c-4683-b62d-45e09de6b65f.xml create mode 100644 global.json diff --git a/CodeSmith/CSharp/ApiGenerate.cst b/CodeSmith/CSharp/ApiGenerate.cst new file mode 100644 index 0000000..cc7834e --- /dev/null +++ b/CodeSmith/CSharp/ApiGenerate.cst @@ -0,0 +1,226 @@ +<%-- +Author: yubaolee +Description: 用于生成OpenAuth.WebApi接口相关代码,包括controller/app/实体/dbcontext +--%> +<%@ Template Language="C#" TargetLanguage="Text" Debug="True" OutputType="Normal" %> + +<%@ Assembly Name="SchemaExplorer" %> +<%@ Assembly Name="CodeSmith.CustomProperties" %> + +<%@ Assembly Name="Mono.Cecil" Path="..\Common" %> +<%@ Assembly Name="ICSharpCode.NRefactory" Path="..\Common" %> +<%@ Assembly Name="ICSharpCode.NRefactory.CSharp" Path="..\Common" %> + +<%@ Assembly Src="Internal\Model.cs" %> +<%@ Assembly Src="Internal\Extensions.cs" %> +<%@ Assembly Src="Internal\Generator.cs" %> +<%@ Assembly Src="Internal\Parser.cs" %> + +<%@ Import Namespace="System.Collections.Generic" %> +<%@ Import Namespace="System.IO" %> +<%@ Import Namespace="System.Linq" %> +<%@ Import Namespace="System.Text" %> +<%@ Import Namespace="System.Text.RegularExpressions" %> +<%@ Import Namespace="System.Diagnostics" %> + +<%@ Import Namespace="SchemaMapper" %> + +<%@ Property Name="WholeDb" +Type="System.Boolean" +Category="1.Database" +Default="true" +Description="是否直接生成选定数据库中的所有表" %> + +<%@ Property Name="HeaderModel" +Type="System.Boolean" +Category="1.Database" +Default="true" +Description="是否为启用头表模式,即类似‘入库订单’界面" %> + +<%@ Property Name="SourceDatabase" + Type="SchemaExplorer.DatabaseSchema" + Category="1.Database" + Description="The source database." %> + +<%@ Property Name="SourceTables" +Type="SchemaExplorer.TableSchemaCollection" +Category="1.Database" Description="可以选择一个或多个表(使用Ctrl键)" %> + +<%@ Property Name="directory" + Type="System.String" + Default=".\" + Optional="True" + Description="代码生成路径" + Editor="System.Windows.Forms.Design.FolderNameEditor, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %> + +<%@ Property Name="ContextNamespace" + Type="System.String" + Category="2.Class" + Default="OpenAuth.Repository" + OnChanged="OnContextNamespaceChanged" + Description="DbContext默认命名空间,尽量不要更改"%> +<%@ Property Name="EntityNamespace" + Type="System.String" + Default="OpenAuth.Repository.Domain" + Category="2.Class" + Description="实体默认命名空间,尽量不要更改"%> + + +<%@ Register Name="EntityGeneratedClass" + Template="Internal\Entity.Generated.cst" + MergeProperties="False" %> + +<%@ Register Name="ContextGeneratedClass" + Template="Internal\Context.Generated.cst" + MergeProperties="True" %> + +<%@ Register Name="ApplicationGenerateClass" + Template="ApiGenerate\Application.cst" + MergeProperties="False" %> +<%@ Register Name="RequestGenerateClass" + Template="ApiGenerate\Request.cst" + MergeProperties="False" %> +<%@ Register Name="ModifyReqGenerateClass" + Template="ApiGenerate\ModifyReq.cst" + MergeProperties="False" %> +<%@ Register Name="ControllerGenerateClass" + Template="ApiGenerate\Controller.cst" + MergeProperties="False" %> + +开始创建OpenAuth.Core WebApi相关代码 ... +<% Generate(); %> + + \ No newline at end of file diff --git a/CodeSmith/CSharp/ApiGenerate/Application.cst b/CodeSmith/CSharp/ApiGenerate/Application.cst new file mode 100644 index 0000000..9bcc9ed --- /dev/null +++ b/CodeSmith/CSharp/ApiGenerate/Application.cst @@ -0,0 +1,157 @@ +<%-- +Name: Database Table Properties +Author: yubaolee +Description: Create a list of properties from a database table +--%> +<%@ CodeTemplate Language="C#" Encoding="utf-8" TargetLanguage="C#" Debug="True" Description="应用层" %> +<%@ Map Name="CSharpAlias" Src="System-CSharpAlias" Description="System to C# Type Map" %> +<%@ Assembly Name="SchemaExplorer" %> +<%@ Import Namespace="SchemaExplorer" %> +<%@ Property Name="Table" + Type="SchemaExplorer.TableSchema" %> +<%@ Property Name="HeaderModel" +Type="System.Boolean" +Category="1.Database" +Default="true" +Description="是否为启用头表模式,即类似‘入库订单’界面" %> +<%@ Assembly Src="../Web/Util.cs" %> +<%@ Import Namespace="Util" %> +using System; +using System.Linq; +using Infrastructure; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using OpenAuth.Repository.Interface; +namespace OpenAuth.App +{ + public class <%=Table.Name%>App : BaseStringApp<<%=Table.Name%>, OpenAuthDBContext> + { + private RevelanceManagerApp _revelanceApp; + /// + /// 加载列表 + /// + public TableData Load(Query<%=Table.Name%>ListReq request) + { + var loginContext = _auth.GetCurrentUser(); + if (loginContext == null) + { + throw new CommonException("登录已过期", Define.INVALID_TOKEN); + } + //如果是WebAPI,请务必改为loginContext.GetTableColumns("<%=Table.Name%>"); + var columnFields = loginContext.GetTableColumnsFromDb("<%=Table.Name%>"); + if (columnFields == null || columnFields.Count == 0) + { + throw new Exception("请在代码生成界面配置Category表的字段属性"); + } + var result = new TableData(); + var objs = UnitWork.Find<<%=Table.Name%>>(null); + if (!string.IsNullOrEmpty(request.key)) + { + objs = objs.Where(u => u.Id.Contains(request.key)); + } + var propertyStr = string.Join(',', columnFields.Select(u =>u.ColumnName)); + result.columnFields = columnFields; + result.data = objs.OrderBy(u => u.Id) + .Skip((request.page - 1) * request.limit) + .Take(request.limit).Select($"new ({propertyStr})"); + result.count = objs.Count(); + return result; + } + <% + if(Table.Name.Contains("Tbl") && (!Table.Name.Contains("Dtbl")) && this.HeaderModel){ + var dtblName = Table.Name.Replace("Tbl","Dtbl"); //明细表的表名 + %> + public void Add(AddOrUpdate<%=Table.Name%>Req req) + { + var obj = req.MapTo<<%=Table.Name%>>(); + //todo:根据自己的业务场景,补充或调整字段 + obj.CreateTime = DateTime.Now; + var user = _auth.GetCurrentUser().User; + obj.CreateUserId = user.Id; + obj.CreateUserName = user.Name; + UnitWork.Add(obj); + if (req.<%=dtblName%>Reqs != null && req.<%=dtblName%>Reqs.Any()) + { + foreach (var detail in req.<%=dtblName%>Reqs) + { + detail.ForeignKeyId = obj.Id; //todo:调整自己的明细表外键 + _<%=dtblName%>App.AddNoSave(detail); + } + } + UnitWork.Save(); + } + public void Update(AddOrUpdate<%=Table.Name%>Req obj) + { + var user = _auth.GetCurrentUser().User; + if (obj.<%=dtblName%>Reqs != null && obj.<%=dtblName%>Reqs.Any()) + { + //id为空的添加 + foreach (var detail in obj.<%=dtblName%>Reqs.Where(u =>string.IsNullOrEmpty(u.Id))) + { + detail.ForeignKeyId = obj.Id; //todo:调整自己的明细表外键 + _<%=dtblName%>App.AddNoSave(detail); + } + //id比数据库少的,删除 + var containids = obj.<%=dtblName%>Reqs.Select(u => u.Id) + .Where(u =>!string.IsNullOrEmpty(u)).ToList(); + if (containids.Any()) + { + UnitWork.Delete<<%=dtblName%>>(u =>(!containids.Contains(u.Id)) && u.ForeignKeyId == obj.Id); //todo:调整自己的明细表外键 + } + //更新id相同的 + foreach (var detail in obj.<%=dtblName%>Reqs.Where(u =>!string.IsNullOrEmpty(u.Id))) + { + _<%=dtblName%>App.Update(detail); + } + } + <%CreateUpdate();%> + UnitWork.Save(); + } + <% + }else{ %> + public void Add(AddOrUpdate<%=Table.Name%>Req req) + { + var obj = req.MapTo<<%=Table.Name%>>(); + //todo:根据自己的业务场景,补充或调整字段 + //比如:obj.CreateTime = DateTime.Now; + // var user = _auth.GetCurrentUser().User; + // obj.CreateUserId = user.Id; + // obj.CreateUserName = user.Name; + Repository.Add(obj); + } + public void Update(AddOrUpdate<%=Table.Name%>Req obj) + { + <%CreateUpdate();%> + } + <% + } + %> + public <%=Table.Name%>App(IUnitWork unitWork, IRepository<<%=Table.Name%>, OpenAuthDBContext> repository, + RevelanceManagerApp app, IAuth auth) : base(unitWork, repository,auth) + { + _revelanceApp = app; + } + } +} + \ No newline at end of file diff --git a/CodeSmith/CSharp/ApiGenerate/Controller.cst b/CodeSmith/CSharp/ApiGenerate/Controller.cst new file mode 100644 index 0000000..30119a0 --- /dev/null +++ b/CodeSmith/CSharp/ApiGenerate/Controller.cst @@ -0,0 +1,128 @@ +<%-- +Name: Database Table Properties +Author: yubaolee +Description: Create a list of properties from a database table +--%> +<%@ CodeTemplate Language="C#" Encoding="utf-8" TargetLanguage="C#" Debug="True" Description="控制器" %> +<%@ Property Name="ModuleName" Type="String" Category="Context" Description="模块名称" %> +<%@ Map Name="CSharpAlias" Src="System-CSharpAlias" Description="System to C# Type Map" %> +<%@ Assembly Name="SchemaExplorer" %> +<%@ Import Namespace="SchemaExplorer" %> + +using System; +using Infrastructure; +using Microsoft.AspNetCore.Mvc; +using OpenAuth.App; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.WebApi.Controllers +{ + /// + /// <%=ModuleName%>操作 + /// + [Route("api/[controller]/[action]")] + [ApiController] + public class <%=ModuleName%>sController : ControllerBase + { + private readonly <%=ModuleName%>App _app; + + /// + /// //获取详情 + /// + [HttpGet] + public Response<<%=ModuleName%>> Get(string id) + { + var result = new Response<<%=ModuleName%>>(); + try + { + result.Result = _app.Get(id); + } + catch (Exception ex) + { + result.Code = 500; + result.Message = ex.InnerException?.Message ?? ex.Message; + } + + return result; + } + + /// + /// 添加 + /// + [HttpPost] + public Response Add(AddOrUpdate<%=ModuleName%>Req obj) + { + var result = new Response(); + try + { + _app.Add(obj); + + } + catch (Exception ex) + { + result.Code = 500; + result.Message = ex.InnerException?.Message ?? ex.Message; + } + + return result; + } + + /// + /// 修改 + /// + [HttpPost] + public Response Update(AddOrUpdate<%=ModuleName%>Req obj) + { + var result = new Response(); + try + { + _app.Update(obj); + + } + catch (Exception ex) + { + result.Code = 500; + result.Message = ex.InnerException?.Message ?? ex.Message; + } + + return result; + } + + /// + /// 加载列表 + /// + [HttpGet] + public TableData Load([FromQuery]Query<%=ModuleName%>ListReq request) + { + return _app.Load(request); + } + + /// + /// 批量删除 + /// + [HttpPost] + public Response Delete([FromBody]string[] ids) + { + var result = new Response(); + try + { + _app.Delete(ids); + + } + catch (Exception ex) + { + result.Code = 500; + result.Message = ex.InnerException?.Message ?? ex.Message; + } + + return result; + } + + public <%=ModuleName%>sController(<%=ModuleName%>App app) + { + _app = app; + } + } +} diff --git a/CodeSmith/CSharp/ApiGenerate/ModifyReq.cst b/CodeSmith/CSharp/ApiGenerate/ModifyReq.cst new file mode 100644 index 0000000..34bbb56 --- /dev/null +++ b/CodeSmith/CSharp/ApiGenerate/ModifyReq.cst @@ -0,0 +1,66 @@ +<%@ Template Language="C#" TargetLanguage="C#" Debug="True" Encoding="UTF-8" %> + +<%@ Assembly Src="../Internal/Model.cs" %> +<%@ Assembly Src="../Internal/Extensions.cs" %> + +<%@ Import Namespace="System.Collections.Generic" %> +<%@ Import Namespace="System.Linq" %> +<%@ Import Namespace="System.Text" %> +<%@ Import Namespace="System.Text.RegularExpressions" %> + +<%@ Import Namespace="SchemaMapper" %> + +<%@ Property Name="Table" + Type="SchemaExplorer.TableSchema" %> + +<%@ Property Name="HeaderModel" +Type="System.Boolean" +Category="1.Database" +Default="true" +Description="是否为启用头表模式,即类似‘入库订单’界面" %> + +<%@ Property Name="EntityNamespace" + Type="System.String" %> +//------------------------------------------------------------------------------ +// +// This code was generated by a CodeSmith Template. +// +// DO NOT MODIFY contents of this file. Changes to this +// file will be lost if the code is regenerated. +// Author:Yubao Li +// +//------------------------------------------------------------------------------ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text; +using OpenAuth.Repository.Core; + +namespace OpenAuth.App.Request +{ + /// + /// <%= Table.Description %> + /// + [Table("<%= Table.Name%>")] + public partial class AddOrUpdate<%= Table.Name %>Req + { + + <% foreach(ColumnSchema p in Table.Columns) { + + %> + /// + /// <%=p.Description %> + /// + public <%= p.SystemType.ToNullableType(p.AllowDBNull == true) %> <%= p.Name%> { get; set; } + <% } %> + + //todo:根据自己的业务场景添加需要的字段 + <% + if(Table.Name.Contains("Tbl") && (!Table.Name.Contains("Dtbl")) && this.HeaderModel){ + var dtblName = Table.Name.Replace("Tbl","Dtbl"); //明细表的表名 + %> + public ListReq> <%=dtblName%>Reqs { get; set; } + <% } %> + } +} \ No newline at end of file diff --git a/CodeSmith/CSharp/ApiGenerate/Request.cst b/CodeSmith/CSharp/ApiGenerate/Request.cst new file mode 100644 index 0000000..6b9b70e --- /dev/null +++ b/CodeSmith/CSharp/ApiGenerate/Request.cst @@ -0,0 +1,17 @@ +<%-- +Name: Database Table Properties +Author: yubaolee +Description: Create a list of properties from a database table +--%> +<%@ CodeTemplate Language="C#" Encoding="utf-8" TargetLanguage="C#" Debug="False" Description="应用层" %> +<%@ Property Name="ModuleName" Type="String" Category="Context" Description="模块名称" %> +<%@ Map Name="CSharpAlias" Src="System-CSharpAlias" Description="System to C# Type Map" %> +<%@ Assembly Name="SchemaExplorer" %> +<%@ Import Namespace="SchemaExplorer" %> +namespace OpenAuth.App.Request +{ + public class Query<%=ModuleName%>ListReq : PageReq + { + //todo:根据自己的业务场景添加需要的字段 + } +} \ No newline at end of file diff --git a/CodeSmith/CSharp/Internal/Context.Generated.cst b/CodeSmith/CSharp/Internal/Context.Generated.cst new file mode 100644 index 0000000..eddb09d --- /dev/null +++ b/CodeSmith/CSharp/Internal/Context.Generated.cst @@ -0,0 +1,81 @@ +<%@ Template Language="C#" TargetLanguage="C#" Debug="True" Encoding="UTF-8" %> + +<%@ Assembly Src="../Internal/Model.cs" %> +<%@ Assembly Src="../Internal/Extensions.cs" %> + +<%@ Import Namespace="System.Collections.Generic" %> +<%@ Import Namespace="System.Linq" %> +<%@ Import Namespace="System.Text" %> +<%@ Import Namespace="System.Text.RegularExpressions" %> + +<%@ Import Namespace="SchemaMapper" %> + +<%@ Property Name="WholeDb" +Type="System.Boolean" +Category="1.Database" +Default="true" +Description="是否为整个数据库" %> + +<%@ Property Name="SourceDatabase" + Type="SchemaExplorer.DatabaseSchema" + Category="1.Database" + Description="The source database." %> + +<%@ Property Name="SourceTables" +Type="SchemaExplorer.TableSchemaCollection" +Category="1.Database" Description="选择部分表" %> + +<%@ Property Name="ContextNamespace" Type="System.String" %> +<%@ Property Name="EntityNamespace" Type="System.String" %> + + +using Microsoft.EntityFrameworkCore; +using <%= EntityNamespace %>; + +namespace <%= ContextNamespace %> +{ + <% + string dbContextName; + if(WholeDb){ + dbContextName = SourceDatabase.Name.ToSafeName(); + } + else{ + dbContextName = SourceTables.First().Database.Name.ToSafeName(); + } + dbContextName = StringUtil.ToPascalCase(dbContextName); + Response.WriteLine(" public partial class "+ dbContextName +"Context: DbContext"); + + %> + { + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + //当主键为联合主键时,需要把这里的内容拷贝到对应的位置 + <% + TableSchemaCollection tables; + if(WholeDb){ + tables = SourceDatabase.Tables; + } + else{ + tables = SourceTables; + } + + foreach(TableSchema table in tables) + { + if(table.PrimaryKeys.Count <=1) continue; + var keys = string.Join(",", table.Columns.Where(u=>u.IsPrimaryKeyMember==true) + .Select(u =>"c."+u.Name)); + Response.WriteLine(" modelBuilder.Entity<"+table.Name+">()"); + Response.WriteLine(" .HasKey(c => new { "+keys+" });"); + } + %> + } + + <% + foreach(TableSchema table in tables) + { + Response.WriteLine(" public virtual DbSet<"+table.Name+"> "+StringUtil.ToPascalCase(StringUtil.ToPlural(table.Name))+" { get; set; }"); + } + %> + } +} \ No newline at end of file diff --git a/CodeSmith/CSharp/Internal/Entity.Generated.cst b/CodeSmith/CSharp/Internal/Entity.Generated.cst new file mode 100644 index 0000000..59ecd68 --- /dev/null +++ b/CodeSmith/CSharp/Internal/Entity.Generated.cst @@ -0,0 +1,75 @@ +<%@ Template Language="C#" TargetLanguage="C#" Debug="True" Encoding="UTF-8" %> + +<%@ Assembly Src="../Internal/Model.cs" %> +<%@ Assembly Src="../Internal/Extensions.cs" %> + +<%@ Import Namespace="System.Collections.Generic" %> +<%@ Import Namespace="System.Linq" %> +<%@ Import Namespace="System.Text" %> +<%@ Import Namespace="System.Text.RegularExpressions" %> + +<%@ Import Namespace="SchemaMapper" %> + +<%@ Property Name="Table" + Type="SchemaExplorer.TableSchema" %> + +<%@ Property Name="EntityNamespace" + Type="System.String" %> +//------------------------------------------------------------------------------ +// +// This code was generated by a CodeSmith Template. +// +// DO NOT MODIFY contents of this file. Changes to this +// file will be lost if the code is regenerated. +// Author:Yubao Li +// +//------------------------------------------------------------------------------ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text; +using OpenAuth.Repository.Core; + +namespace <%= EntityNamespace %> +{ + /// + /// <%= Table.Description %> + /// + [Table("<%= Table.Name%>")] + public partial class <%= Table.Name %> : StringEntity + { + public <%= Table.Name %>() + { + <% foreach(ColumnSchema p in Table.Columns) { + if(p.IsPrimaryKeyMember) continue; + string type = p.SystemType.ToNullableType(p.AllowDBNull == true); + if(type =="int" || type=="decimal") + Response.WriteLine(" this."+p.Name+"= 0;"); + else if(type =="string") + Response.WriteLine(" this."+p.Name+"= string.Empty;"); + else if(type.ToLower().Contains("datetime")) + Response.WriteLine(" this."+p.Name+"= DateTime.Now;"); + } // foreach %> + } + + + <% + foreach(ColumnSchema p in Table.Columns) { + if(p.IsPrimaryKeyMember) continue; + %> + /// + /// <%=p.Description %> + /// + [Description("<%=p.Description%>")] + <%if(p.Name.LastIndexOf("Id") != -1){%> + [Browsable(false)] + <%}%> + <%if(p.DataType == DbType.Byte){%> + public bool <%= p.Name%> { get; set; } + <%}else{%> + public <%= p.SystemType.ToNullableType(p.AllowDBNull == true) %> <%= p.Name%> { get; set; } + <%}%> + <% } // foreach %> + } +} \ No newline at end of file diff --git a/CodeSmith/CSharp/Internal/Extensions.cs b/CodeSmith/CSharp/Internal/Extensions.cs new file mode 100644 index 0000000..0e8dc28 --- /dev/null +++ b/CodeSmith/CSharp/Internal/Extensions.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using CodeSmith.Engine; + +namespace SchemaMapper +{ + public enum CodeLanguage + { + CSharp, + VisualBasic + } + + public static class Extensions + { + private static readonly HashSet _csharpKeywords; + private static readonly HashSet _visualBasicKeywords; + private static readonly Dictionary _csharpTypeAlias; + + static Extensions() + { + _csharpKeywords = new HashSet(StringComparer.Ordinal) + { + "as", "do", "if", "in", "is", + "for", "int", "new", "out", "ref", "try", + "base", "bool", "byte", "case", "char", "else", "enum", "goto", "lock", "long", "null", "this", "true", "uint", "void", + "break", "catch", "class", "const", "event", "false", "fixed", "float", "sbyte", "short", "throw", "ulong", "using", "while", + "double", "extern", "object", "params", "public", "return", "sealed", "sizeof", "static", "string", "struct", "switch", "typeof", "unsafe", "ushort", + "checked", "decimal", "default", "finally", "foreach", "private", "virtual", + "abstract", "continue", "delegate", "explicit", "implicit", "internal", "operator", "override", "readonly", "volatile", + "__arglist", "__makeref", "__reftype", "interface", "namespace", "protected", "unchecked", + "__refvalue", "stackalloc" + }; + + _visualBasicKeywords = new HashSet(StringComparer.OrdinalIgnoreCase) + { + "as", "do", "if", "in", "is", "me", "of", "on", "or", "to", + "and", "dim", "end", "for", "get", "let", "lib", "mod", "new", "not", "rem", "set", "sub", "try", "xor", + "ansi", "auto", "byte", "call", "case", "cdbl", "cdec", "char", "cint", "clng", "cobj", "csng", "cstr", "date", "each", "else", + "enum", "exit", "goto", "like", "long", "loop", "next", "step", "stop", "then", "true", "wend", "when", "with", + "alias", "byref", "byval", "catch", "cbool", "cbyte", "cchar", "cdate", "class", "const", "ctype", "cuint", "culng", "endif", "erase", "error", + "event", "false", "gosub", "isnot", "redim", "sbyte", "short", "throw", "ulong", "until", "using", "while", + "csbyte", "cshort", "double", "elseif", "friend", "global", "module", "mybase", "object", "option", "orelse", "public", "resume", "return", "select", "shared", + "single", "static", "string", "typeof", "ushort", + "andalso", "boolean", "cushort", "decimal", "declare", "default", "finally", "gettype", "handles", "imports", "integer", "myclass", "nothing", "partial", "private", "shadows", + "trycast", "unicode", "variant", + "assembly", "continue", "delegate", "function", "inherits", "operator", "optional", "preserve", "property", "readonly", "synclock", "uinteger", "widening", + "addressof", "interface", "namespace", "narrowing", "overloads", "overrides", "protected", "structure", "writeonly", + "addhandler", "directcast", "implements", "paramarray", "raiseevent", "withevents", + "mustinherit", "overridable", + "mustoverride", + "removehandler", + "class_finalize", "notinheritable", "notoverridable", + "class_initialize" + }; + + _csharpTypeAlias = new Dictionary(16) + { + {"System.Int16", "short"}, + {"System.Int32", "int"}, + {"System.Int64", "long"}, + {"System.String", "string"}, + {"System.Object", "object"}, + {"System.Boolean", "bool"}, + {"System.Void", "void"}, + {"System.Char", "char"}, + {"System.Byte", "byte"}, + {"System.UInt16", "ushort"}, + {"System.UInt32", "uint"}, + {"System.UInt64", "ulong"}, + {"System.SByte", "sbyte"}, + {"System.Single", "float"}, + {"System.Double", "double"}, + {"System.Decimal", "decimal"} + }; + } + + public static string ToCamelCase(this string name) + { + return StringUtil.ToCamelCase(name); + } + + public static string ToPascalCase(this string name) + { + return StringUtil.ToPascalCase(name); + } + + + public static string ToFieldName(this string name) + { + return "_" + StringUtil.ToCamelCase(name); + } + + public static string MakeUnique(this string name, Func exists) + { + string uniqueName = name; + int count = 1; + + while (exists(uniqueName)) + uniqueName = string.Concat(name, count++); + + return uniqueName; + } + + public static bool IsKeyword(this string text, CodeLanguage language = CodeLanguage.CSharp) + { + return language == CodeLanguage.VisualBasic + ? _visualBasicKeywords.Contains(text) + : _csharpKeywords.Contains(text); + } + + public static string ToSafeName(this string name, CodeLanguage language = CodeLanguage.CSharp) + { + if (!name.IsKeyword(language)) + return name; + + return language == CodeLanguage.VisualBasic + ? string.Format("[{0}]", name) + : "@" + name; + } + + public static string ToType(this Type type, CodeLanguage language = CodeLanguage.CSharp) + { + return ToType(type.FullName, language); + } + + public static string ToType(this string type, CodeLanguage language = CodeLanguage.CSharp) + { + if (type == "System.Xml.XmlDocument") + type = "System.String"; + + string t; + if (language == CodeLanguage.CSharp && _csharpTypeAlias.TryGetValue(type, out t)) + return t; + + + return type; + } + + public static string ToNullableType(this Type type, bool isNullable = false, CodeLanguage language = CodeLanguage.CSharp) + { + return ToNullableType(type.FullName, isNullable, language); + } + + public static string ToNullableType(this string type, bool isNullable = false, CodeLanguage language = CodeLanguage.CSharp) + { + bool isValueType = type.IsValueType(); + + type = type.ToType(language); + + if (!isValueType || !isNullable) + return type; + + return language == CodeLanguage.VisualBasic + ? string.Format("Nullable(Of {0})", type) + : type + "?"; + } + + public static bool IsValueType(this string type) + { + if (!type.StartsWith("System.")) + return false; + + var t = Type.GetType(type, false); + return t != null && t.IsValueType; + } + + public static string ToDelimitedString(this IEnumerable values, string delimiter, string format = null) + { + var sb = new StringBuilder(); + foreach (var i in values) + { + if (sb.Length > 0) + sb.Append(delimiter); + + if (string.IsNullOrEmpty(format)) + sb.Append(i); + else + sb.AppendFormat(format, i); + } + + return sb.ToString(); + } + + } +} diff --git a/CodeSmith/CSharp/Internal/Generator.cs b/CodeSmith/CSharp/Internal/Generator.cs new file mode 100644 index 0000000..751b669 --- /dev/null +++ b/CodeSmith/CSharp/Internal/Generator.cs @@ -0,0 +1,837 @@ +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text.RegularExpressions; +using CodeSmith.Engine; +using SchemaExplorer; + +namespace SchemaMapper +{ + public enum TableNaming + { + Mixed = 0, + Plural = 1, + Singular = 2 + } + + public enum EntityNaming + { + Preserve = 0, + Plural = 1, + Singular = 2 + } + + public enum RelationshipNaming + { + None = 0, + Plural = 1, + ListSuffix = 2 + } + + public enum ContextNaming + { + Preserve = 0, + Plural = 1, + TableSuffix = 2 + } + + public class GeneratorSettings + { + public GeneratorSettings() + { + RelationshipNaming = RelationshipNaming.ListSuffix; + EntityNaming = EntityNaming.Singular; + TableNaming = TableNaming.Singular; + CleanExpressions = new List { @"^\d+" }; + IgnoreExpressions = new List(); + } + + public TableNaming TableNaming { get; set; } + + public EntityNaming EntityNaming { get; set; } + + public RelationshipNaming RelationshipNaming { get; set; } + + public ContextNaming ContextNaming { get; set; } + + public List IgnoreExpressions { get; set; } + + public List CleanExpressions { get; set; } + + public bool InclusionMode { get; set; } + + public bool IsIgnored(string name) + { + if (IgnoreExpressions.Count == 0) + return false; + + bool isMatch = IgnoreExpressions.Any(regex => Regex.IsMatch(name, regex)); + + return InclusionMode ? !isMatch : isMatch; + } + + public string CleanName(string name) + { + if (CleanExpressions.Count == 0) + return name; + + foreach (var regex in CleanExpressions.Where(r => !string.IsNullOrEmpty(r))) + if (Regex.IsMatch(name, regex)) + return Regex.Replace(name, regex, ""); + + return name; + } + + public string RelationshipName(string name) + { + if (RelationshipNaming == RelationshipNaming.None) + return name; + + if (RelationshipNaming == RelationshipNaming.ListSuffix) + return name + "List"; + + return StringUtil.ToPascalCase(StringUtil.ToPlural(name)); + } + + public string ContextName(string name) + { + if (ContextNaming == ContextNaming.Preserve) + return name; + + if (ContextNaming == ContextNaming.TableSuffix) + return name + "Table"; + + return StringUtil.ToPascalCase(StringUtil.ToPlural(name)); + } + + public string EntityName(string name) + { + if (TableNaming != TableNaming.Plural && EntityNaming == EntityNaming.Plural) + name = StringUtil.ToPlural(name); + else if (TableNaming != TableNaming.Singular && EntityNaming == EntityNaming.Singular) + name = StringUtil.ToSingular(name); + + return StringUtil.ToPascalCase(name); + } + } + + public class SchemaItemProcessedEventArgs : EventArgs + { + public SchemaItemProcessedEventArgs(string name) + { + _name = name; + } + + private readonly string _name; + public string Name + { + get { return _name; } + } + } + + public class UniqueNamer + { + private readonly ConcurrentDictionary> _names; + + public UniqueNamer() + { + _names = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); + Comparer = StringComparer.CurrentCulture; + + // add existing + UniqueContextName("ChangeTracker"); + UniqueContextName("Configuration"); + UniqueContextName("Database"); + UniqueContextName("InternalContext"); + } + + public IEqualityComparer Comparer { get; set; } + + public string UniqueName(string bucketName, string name) + { + var hashSet = _names.GetOrAdd(bucketName, k => new HashSet(Comparer)); + string result = name.MakeUnique(hashSet.Contains); + hashSet.Add(result); + + return result; + } + + public string UniqueClassName(string className) + { + const string globalClassName = "global::ClassName"; + return UniqueName(globalClassName, className); + } + + public string UniqueContextName(string name) + { + const string globalContextname = "global::ContextName"; + return UniqueName(globalContextname, name); + } + + public string UniqueRelationshipName(string name) + { + const string globalContextname = "global::RelationshipName"; + return UniqueName(globalContextname, name); + } + + } + + public class Generator + { + private readonly UniqueNamer _namer; + + public Generator() + { + _settings = new GeneratorSettings(); + _namer = new UniqueNamer(); + } + + public event EventHandler SchemaItemProcessed; + protected void OnSchemaItemProcessed(string name) + { + var handler = SchemaItemProcessed; + if (handler == null) + return; + + handler(this, new SchemaItemProcessedEventArgs(name)); + } + + private readonly GeneratorSettings _settings; + public GeneratorSettings Settings + { + get { return _settings; } + } + + //按表信息创建DbContext + public EntityContext Generate(TableSchema tableSchema) + { + // only DeepLoad when in ignore mode + tableSchema.DeepLoad = !Settings.InclusionMode; + + var entityContext = new EntityContext(); + entityContext.DatabaseName = tableSchema.Database.Name; + + string dataContextName = StringUtil.ToPascalCase(tableSchema.Database.Name) + "Context"; + dataContextName = _namer.UniqueClassName(dataContextName); + + entityContext.ClassName = dataContextName; + + GetEntity(entityContext, tableSchema); + + + return entityContext; + } + + //按数据库连接信息创建DbContext + public EntityContext Generate(DatabaseSchema databaseSchema) + { + // only DeepLoad when in ignore mode + databaseSchema.DeepLoad = !Settings.InclusionMode; + + var entityContext = new EntityContext(); + entityContext.DatabaseName = databaseSchema.Name; + + string dataContextName = StringUtil.ToPascalCase(databaseSchema.Name) + "Context"; + dataContextName = _namer.UniqueClassName(dataContextName); + + entityContext.ClassName = dataContextName; + + foreach (TableSchema t in databaseSchema.Tables) + { + if (Settings.IsIgnored(t.FullName)) + { + Debug.WriteLine("Skipping Table: " + t.FullName); + } + else if (IsManyToMany(t)) + { + CreateManyToMany(entityContext, t); + } + else + { + Debug.WriteLine("Getting Table Schema: " + t.FullName); + GetEntity(entityContext, t); + } + + OnSchemaItemProcessed(t.FullName); + } + + return entityContext; + } + + //根据DbContext和tableSchema获取实体 + public Entity GetEntity(EntityContext entityContext, TableSchema tableSchema, bool processRelationships = true, bool processMethods = true) + { + string key = tableSchema.FullName; + + Entity entity = entityContext.Entities.ByTable(key) + ?? CreateEntity(entityContext, tableSchema); + + if (!entity.Properties.IsProcessed) + CreateProperties(entity, tableSchema); + + if (processRelationships && !entity.Relationships.IsProcessed) + CreateRelationships(entityContext, entity, tableSchema); + + if (processMethods && !entity.Methods.IsProcessed) + CreateMethods(entity, tableSchema); + + entity.IsProcessed = true; + return entity; + } + + private Entity CreateEntity(EntityContext entityContext, TableSchema tableSchema) + { + var entity = new Entity + { + FullName = tableSchema.FullName, + TableName = tableSchema.Name, + TableSchema = tableSchema.Owner, + Description = tableSchema.Description + }; + + string className = ToClassName(tableSchema.Name); + className = _namer.UniqueClassName(className); + + string mappingName = className + "Map"; + mappingName = _namer.UniqueClassName(mappingName); + + string contextName = Settings.ContextName(className); + contextName = ToPropertyName(entityContext.ClassName, contextName); + contextName = _namer.UniqueContextName(contextName); + + entity.ClassName = className; + entity.ContextName = contextName; + entity.MappingName = mappingName; + + entityContext.Entities.Add(entity); + + return entity; + } + + /// + /// 创建实体的属性 + /// + private void CreateProperties(Entity entity, TableSchema tableSchema) + { + foreach (ColumnSchema columnSchema in tableSchema.Columns) + { + // skip unsupported type + if (columnSchema.NativeType.Equals("hierarchyid", StringComparison.OrdinalIgnoreCase) + || columnSchema.NativeType.Equals("sql_variant", StringComparison.OrdinalIgnoreCase)) + { + Debug.WriteLine(string.Format("Skipping column '{0}' because it has an unsupported db type '{1}'.", + columnSchema.Name, columnSchema.NativeType)); + continue; + } + + Property property = entity.Properties.ByColumn(columnSchema.Name); + + if (property == null) + { + property = new Property { ColumnName = columnSchema.Name }; + entity.Properties.Add(property); + } + + string propertyName = ToPropertyName(entity.ClassName, columnSchema.Name); + propertyName = _namer.UniqueName(entity.ClassName, propertyName); + + property.PropertyName = propertyName; + + property.DataType = columnSchema.DataType; + property.SystemType = columnSchema.SystemType; + property.NativeType = columnSchema.NativeType; + property.Description = columnSchema.Description; + + property.IsPrimaryKey = columnSchema.IsPrimaryKeyMember; + property.IsForeignKey = columnSchema.IsForeignKeyMember; + property.IsNullable = columnSchema.AllowDBNull; + + property.IsIdentity = IsIdentity(columnSchema); + property.IsRowVersion = IsRowVersion(columnSchema); + property.IsAutoGenerated = IsDbGenerated(columnSchema); + + if (columnSchema.IsUnique) + property.IsUnique = columnSchema.IsUnique; + + if (property.SystemType == typeof(string) + || property.SystemType == typeof(byte[])) + { + property.MaxLength = columnSchema.Size; + } + + if (property.SystemType == typeof(float) + || property.SystemType == typeof(double) + || property.SystemType == typeof(decimal)) + { + property.Precision = columnSchema.Precision; + property.Scale = columnSchema.Scale; + } + + property.IsProcessed = true; + } + + entity.Properties.IsProcessed = true; + } + + + private void CreateRelationships(EntityContext entityContext, Entity entity, TableSchema tableSchema) + { + foreach (TableKeySchema tableKey in tableSchema.ForeignKeys) + { + if (Settings.IsIgnored(tableKey.ForeignKeyTable.FullName) + || Settings.IsIgnored(tableKey.PrimaryKeyTable.FullName)) + { + Debug.WriteLine("Skipping relationship '{0}' because table '{1}' or '{2}' is ignored.", + tableKey.FullName, tableKey.ForeignKeyTable.FullName, tableKey.PrimaryKeyTable.FullName); + + continue; + } + + CreateRelationship(entityContext, entity, tableKey); + } + + entity.Relationships.IsProcessed = true; + } + + private void CreateRelationship(EntityContext entityContext, Entity foreignEntity, TableKeySchema tableKeySchema) + { + Entity primaryEntity = GetEntity(entityContext, tableKeySchema.PrimaryKeyTable, false, false); + + string primaryName = primaryEntity.ClassName; + string foreignName = foreignEntity.ClassName; + + string relationshipName = tableKeySchema.Name; + relationshipName = _namer.UniqueRelationshipName(relationshipName); + + bool isCascadeDelete = IsCascadeDelete(tableKeySchema); + bool foreignMembersRequired; + bool primaryMembersRequired; + + var foreignMembers = GetKeyMembers(foreignEntity, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name, out foreignMembersRequired); + var primaryMembers = GetKeyMembers(primaryEntity, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name, out primaryMembersRequired); + + Relationship foreignRelationship = foreignEntity.Relationships + .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey); + + if (foreignRelationship == null) + { + foreignRelationship = new Relationship { RelationshipName = relationshipName }; + foreignEntity.Relationships.Add(foreignRelationship); + } + foreignRelationship.IsMapped = true; + foreignRelationship.IsForeignKey = true; + foreignRelationship.ThisCardinality = foreignMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne; + foreignRelationship.ThisEntity = foreignName; + foreignRelationship.ThisProperties = new List(foreignMembers); + foreignRelationship.OtherEntity = primaryName; + foreignRelationship.OtherProperties = new List(primaryMembers); + foreignRelationship.CascadeDelete = isCascadeDelete; + + string prefix = GetMemberPrefix(foreignRelationship, primaryName, foreignName); + + string foreignPropertyName = ToPropertyName(foreignEntity.ClassName, prefix + primaryName); + foreignPropertyName = _namer.UniqueName(foreignEntity.ClassName, foreignPropertyName); + foreignRelationship.ThisPropertyName = foreignPropertyName; + + // add reverse + Relationship primaryRelationship = primaryEntity.Relationships + .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey == false); + + if (primaryRelationship == null) + { + primaryRelationship = new Relationship { RelationshipName = relationshipName }; + primaryEntity.Relationships.Add(primaryRelationship); + } + + primaryRelationship.IsMapped = false; + primaryRelationship.IsForeignKey = false; + primaryRelationship.ThisEntity = primaryName; + primaryRelationship.ThisProperties = new List(primaryMembers); + primaryRelationship.OtherEntity = foreignName; + primaryRelationship.OtherProperties = new List(foreignMembers); + primaryRelationship.CascadeDelete = isCascadeDelete; + + bool isOneToOne = IsOneToOne(tableKeySchema, foreignRelationship); + + if (isOneToOne) + primaryRelationship.ThisCardinality = primaryMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne; + else + primaryRelationship.ThisCardinality = Cardinality.Many; + + string primaryPropertyName = prefix + foreignName; + if (!isOneToOne) + primaryPropertyName = Settings.RelationshipName(primaryPropertyName); + + primaryPropertyName = ToPropertyName(primaryEntity.ClassName, primaryPropertyName); + primaryPropertyName = _namer.UniqueName(primaryEntity.ClassName, primaryPropertyName); + + primaryRelationship.ThisPropertyName = primaryPropertyName; + + foreignRelationship.OtherPropertyName = primaryRelationship.ThisPropertyName; + foreignRelationship.OtherCardinality = primaryRelationship.ThisCardinality; + + primaryRelationship.OtherPropertyName = foreignRelationship.ThisPropertyName; + primaryRelationship.OtherCardinality = foreignRelationship.ThisCardinality; + + foreignRelationship.IsProcessed = true; + primaryRelationship.IsProcessed = true; + } + + private void CreateManyToMany(EntityContext entityContext, TableSchema joinTable) + { + if (joinTable.ForeignKeys.Count != 2) + return; + + var joinTableName = joinTable.Name; + var joinSchemaName = joinTable.Owner; + + // first fkey is always left, second fkey is right + var leftForeignKey = joinTable.ForeignKeys[0]; + var leftTable = leftForeignKey.PrimaryKeyTable; + var joinLeftColumn = leftForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList(); + var leftEntity = GetEntity(entityContext, leftTable, false, false); + + var rightForeignKey = joinTable.ForeignKeys[1]; + var rightTable = rightForeignKey.PrimaryKeyTable; + var joinRightColumn = rightForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList(); + var rightEntity = GetEntity(entityContext, rightTable, false, false); + + string leftPropertyName = Settings.RelationshipName(rightEntity.ClassName); + leftPropertyName = _namer.UniqueName(leftEntity.ClassName, leftPropertyName); + + string rightPropertyName = Settings.RelationshipName(leftEntity.ClassName); + rightPropertyName = _namer.UniqueName(rightEntity.ClassName, rightPropertyName); + + string relationshipName = string.Format("{0}|{1}", + leftForeignKey.Name, + rightForeignKey.Name); + + relationshipName = _namer.UniqueRelationshipName(relationshipName); + + var left = new Relationship { RelationshipName = relationshipName }; + left.IsForeignKey = false; + left.IsMapped = true; + + left.ThisCardinality = Cardinality.Many; + left.ThisEntity = leftEntity.ClassName; + left.ThisPropertyName = leftPropertyName; + + left.OtherCardinality = Cardinality.Many; + left.OtherEntity = rightEntity.ClassName; + left.OtherPropertyName = rightPropertyName; + + left.JoinTable = joinTableName; + left.JoinSchema = joinSchemaName; + left.JoinThisColumn = new List(joinLeftColumn); + left.JoinOtherColumn = new List(joinRightColumn); + + leftEntity.Relationships.Add(left); + + var right = new Relationship { RelationshipName = relationshipName }; + right.IsForeignKey = false; + right.IsMapped = false; + + right.ThisCardinality = Cardinality.Many; + right.ThisEntity = rightEntity.ClassName; + right.ThisPropertyName = rightPropertyName; + + right.OtherCardinality = Cardinality.Many; + right.OtherEntity = leftEntity.ClassName; + right.OtherPropertyName = leftPropertyName; + + right.JoinTable = joinTableName; + right.JoinSchema = joinSchemaName; + right.JoinThisColumn = new List(joinRightColumn); + right.JoinOtherColumn = new List(joinLeftColumn); + + rightEntity.Relationships.Add(right); + } + + + private void CreateMethods(Entity entity, TableSchema tableSchema) + { + if (tableSchema.HasPrimaryKey) + { + var method = GetMethodFromColumns(entity, tableSchema.PrimaryKey.MemberColumns); + if (method != null) + { + method.IsKey = true; + method.SourceName = tableSchema.PrimaryKey.FullName; + + if (!entity.Methods.Any(m => m.NameSuffix == method.NameSuffix)) + entity.Methods.Add(method); + } + } + + GetIndexMethods(entity, tableSchema); + GetForeignKeyMethods(entity, tableSchema); + + entity.Methods.IsProcessed = true; + } + + private static void GetForeignKeyMethods(Entity entity, TableSchema table) + { + var columns = new List(); + + foreach (ColumnSchema column in table.ForeignKeyColumns) + { + columns.Add(column); + + Method method = GetMethodFromColumns(entity, columns); + if (method != null && !entity.Methods.Any(m => m.NameSuffix == method.NameSuffix)) + entity.Methods.Add(method); + + columns.Clear(); + } + } + + private static void GetIndexMethods(Entity entity, TableSchema table) + { + foreach (IndexSchema index in table.Indexes) + { + Method method = GetMethodFromColumns(entity, index.MemberColumns); + if (method == null) + continue; + + method.SourceName = index.FullName; + method.IsUnique = index.IsUnique; + method.IsIndex = true; + + if (!entity.Methods.Any(m => m.NameSuffix == method.NameSuffix)) + entity.Methods.Add(method); + } + } + + private static Method GetMethodFromColumns(Entity entity, IEnumerable columns) + { + var method = new Method(); + string methodName = string.Empty; + + foreach (var column in columns) + { + var property = entity.Properties.ByColumn(column.Name); + if (property == null) + continue; + + method.Properties.Add(property); + methodName += property.PropertyName; + } + + if (method.Properties.Count == 0) + return null; + + method.NameSuffix = methodName; + return method; + } + + + private static List GetKeyMembers(Entity entity, IEnumerable members, string name, out bool isRequired) + { + var keyMembers = new List(); + isRequired = false; + + foreach (var member in members) + { + var property = entity.Properties.ByColumn(member.Name); + + if (property == null) + throw new InvalidOperationException(string.Format( + "Could not find column {0} for relationship {1}.", + member.Name, + name)); + + if (!isRequired) + isRequired = property.IsRequired; + + keyMembers.Add(property.PropertyName); + } + + return keyMembers; + } + + private static string GetMemberPrefix(Relationship relationship, string primaryClass, string foreignClass) + { + string thisKey = relationship.ThisProperties.FirstOrDefault() ?? string.Empty; + string otherKey = relationship.OtherProperties.FirstOrDefault() ?? string.Empty; + + bool isSameName = thisKey.Equals(otherKey, StringComparison.OrdinalIgnoreCase); + isSameName = (isSameName || thisKey.Equals(primaryClass + otherKey, StringComparison.OrdinalIgnoreCase)); + + string prefix = string.Empty; + if (isSameName) + return prefix; + + prefix = thisKey.Replace(otherKey, ""); + prefix = prefix.Replace(primaryClass, ""); + prefix = prefix.Replace(foreignClass, ""); + prefix = Regex.Replace(prefix, @"(_ID|_id|_Id|\.ID|\.id|\.Id|ID|Id)$", ""); + prefix = Regex.Replace(prefix, @"^\d", ""); + + return prefix; + } + + private static bool IsOneToOne(TableKeySchema tableKeySchema, Relationship foreignRelationship) + { + bool isFkeyPkey = tableKeySchema.ForeignKeyTable.HasPrimaryKey + && tableKeySchema.ForeignKeyTable.PrimaryKey != null + && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count == 1 + && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Contains( + foreignRelationship.ThisProperties.FirstOrDefault()); + + if (isFkeyPkey) + return true; + + // if f.key is unique + return tableKeySchema.ForeignKeyMemberColumns.All(column => column.IsUnique); + } + + private static bool IsManyToMany(TableSchema tableSchema) + { + // 1) Table must have Two ForeignKeys. + // 2) All columns must be either... + // a) Member of a Foreign Key. + // b) DbGenerated + + if (tableSchema.Columns.Count < 2) + return false; + + if (tableSchema.ForeignKeyColumns.Count != 2) + return false; + + // all columns are fkeys + if (tableSchema.Columns.Count == 2 && + tableSchema.ForeignKeyColumns.Count == 2) + return true; + + // check all non fkey columns to make sure db gen'd + return tableSchema.NonForeignKeyColumns.All(c => + IsDbGenerated(c) || HasDefaultValue(c)); + } + + #region Name Helpers + private string ToClassName(string name) + { + name = Settings.EntityName(name); + string legalName = ToLegalName(name); + + return legalName; + } + + private string ToPropertyName(string className, string name) + { + string propertyName = ToLegalName(name); + if (className.Equals(propertyName, StringComparison.OrdinalIgnoreCase)) + propertyName += "Member"; + + return propertyName; + } + + private string ToLegalName(string name) + { + string legalName = Settings.CleanName(name); + legalName = StringUtil.ToPascalCase(legalName); + + return legalName; + } + #endregion + + #region Column Flag Helpers + private static bool IsCascadeDelete(SchemaObjectBase column) + { + bool cascadeDelete = false; + string value; + try + { + if (column.ExtendedProperties.Contains(ExtendedPropertyNames.CascadeDelete)) + { + value = column.ExtendedProperties[ExtendedPropertyNames.CascadeDelete].Value.ToString(); + bool.TryParse(value, out cascadeDelete); + } + } + catch (Exception ex) + { + Debug.WriteLine("Error: " + ex.Message); + } + + return cascadeDelete; + } + + private static bool IsRowVersion(DataObjectBase column) + { + bool isTimeStamp = column.NativeType.Equals( + "timestamp", StringComparison.OrdinalIgnoreCase); + bool isRowVersion = column.NativeType.Equals( + "rowversion", StringComparison.OrdinalIgnoreCase); + + return (isTimeStamp || isRowVersion); + } + + private static bool IsDbGenerated(DataObjectBase column) + { + if (IsRowVersion(column)) + return true; + + if (IsIdentity(column)) + return true; + + bool isComputed = false; + string value; + try + { + if (column.ExtendedProperties.Contains(ExtendedPropertyNames.IsComputed)) + { + value = column.ExtendedProperties[ExtendedPropertyNames.IsComputed].Value.ToString(); + bool.TryParse(value, out isComputed); + } + } + catch (Exception ex) + { + Debug.WriteLine("Error: " + ex.Message); + } + + return isComputed; + } + + private static bool IsIdentity(DataObjectBase column) + { + string temp; + bool isIdentity = false; + try + { + if (column.ExtendedProperties.Contains(ExtendedPropertyNames.IsIdentity)) + { + temp = column.ExtendedProperties[ExtendedPropertyNames.IsIdentity].Value.ToString(); + bool.TryParse(temp, out isIdentity); + } + } + catch (Exception ex) + { + Debug.WriteLine("Error: " + ex.Message); + } + + return isIdentity; + } + + private static bool HasDefaultValue(DataObjectBase column) + { + try + { + if (!column.ExtendedProperties.Contains(ExtendedPropertyNames.DefaultValue)) + return false; + + string value = column.ExtendedProperties[ExtendedPropertyNames.DefaultValue].Value.ToString(); + return !string.IsNullOrEmpty(value); + } + catch (Exception ex) + { + Debug.WriteLine("Error: " + ex.Message); + } + + return false; + } + #endregion + } +} diff --git a/CodeSmith/CSharp/Internal/Model.cs b/CodeSmith/CSharp/Internal/Model.cs new file mode 100644 index 0000000..b7b2a6f --- /dev/null +++ b/CodeSmith/CSharp/Internal/Model.cs @@ -0,0 +1,370 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data; +using System.Diagnostics; +using System.Linq; +using System.Xml.Serialization; + +namespace SchemaMapper +{ + #region Base + public enum Cardinality + { + ZeroOrOne, + One, + Many + } + + public class EntityBase + { + [XmlIgnore] + public bool IsProcessed { get; set; } + } + #endregion + + #region Model + [DebuggerDisplay("Context: {ContextName}, Database: {DatabaseName}")] + public class EntityContext : EntityBase + { + public EntityContext() + { + Entities = new EntityCollection(); + } + + public string ClassName { get; set; } + public string DatabaseName { get; set; } + + public EntityCollection Entities { get; set; } + + public void RenameEntity(string originalName, string newName) + { + if (originalName == newName) + return; + + Debug.WriteLine("Rename Entity '{0}' to '{1}'.", originalName, newName); + foreach (var entity in Entities) + { + if (entity.ClassName == originalName) + entity.ClassName = newName; + + foreach (var relationship in entity.Relationships) + { + if (relationship.ThisEntity == originalName) + relationship.ThisEntity = newName; + if (relationship.OtherEntity == originalName) + relationship.OtherEntity = newName; + } + } + } + + public void RenameProperty(string entityName, string originalName, string newName) + { + if (originalName == newName) + return; + + Debug.WriteLine("Rename Property '{0}' to '{1}' in Entity '{2}'.", originalName, newName, entityName); + foreach (var entity in Entities) + { + if (entity.ClassName == entityName) + { + var property = entity.Properties.ByProperty(originalName); + if (property != null) + property.PropertyName = newName; + } + + foreach (var relationship in entity.Relationships) + { + if (relationship.ThisEntity == entityName) + for (int i = 0; i < relationship.ThisProperties.Count; i++) + if (relationship.ThisProperties[i] == originalName) + relationship.ThisProperties[i] = newName; + + if (relationship.OtherEntity == entityName) + for (int i = 0; i < relationship.OtherProperties.Count; i++) + if (relationship.OtherProperties[i] == originalName) + relationship.OtherProperties[i] = newName; + } + } + + } + } + + [DebuggerDisplay("Class: {ClassName}, Table: {FullName}, Context: {ContextName}")] + public class Entity : EntityBase + { + public Entity() + { + Properties = new PropertyCollection(); + Relationships = new RelationshipCollection(); + Methods = new MethodCollection(); + } + + public string ContextName { get; set; } + public string ClassName { get; set; } + public string MappingName { get; set; } + public string Description{ get;set;} + + public string TableSchema { get; set; } + public string TableName { get; set; } + public string FullName { get; set; } + + public PropertyCollection Properties { get; set; } + public RelationshipCollection Relationships { get; set; } + public MethodCollection Methods { get; set; } + } + + [DebuggerDisplay("Property: {PropertyName}, Column: {ColumnName}, Type: {NativeType}")] + public class Property : EntityBase + { + public string PropertyName { get; set; } + public string ColumnName { get; set; } + public string Description { get; set; } + + public DbType DataType { get; set; } + public string NativeType { get; set; } + + [XmlIgnore] + public Type SystemType { get; set; } + + public int? Order { get; set; } + public bool OrderSpecified + { + get { return Order.HasValue; } + } + + public bool? IsNullable { get; set; } + public bool IsNullableSpecified + { + get { return IsNullable.HasValue; } + } + + public bool IsRequired + { + get { return IsNullable == false; } + set { IsNullable = !value; } + } + public bool IsOptional + { + get { return IsNullable == true; } + set { IsNullable = value; } + } + + public bool? IsPrimaryKey { get; set; } + public bool IsPrimaryKeySpecified + { + get { return IsPrimaryKey.HasValue; } + } + public bool? IsForeignKey { get; set; } + public bool IsForeignKeySpecified + { + get { return IsForeignKey.HasValue; } + } + + public bool? IsAutoGenerated { get; set; } + public bool IsAutoGeneratedSpecified + { + get { return IsAutoGenerated.HasValue; } + } + public bool? IsReadOnly { get; set; } + public bool IsReadOnlySpecified + { + get { return IsReadOnly.HasValue; } + } + public bool? IsRowVersion { get; set; } + public bool IsRowVersionSpecified + { + get { return IsRowVersion.HasValue; } + } + public bool? IsIdentity { get; set; } + public bool IsIdentitySpecified + { + get { return IsIdentity.HasValue; } + } + public bool? IsUnique { get; set; } + public bool IsUniqueSpecified + { + get { return IsUnique.HasValue; } + } + + public bool? IsUnicode { get; set; } + public bool IsUnicodeSpecified + { + get { return IsUnicode.HasValue; } + } + public bool? IsFixedLength { get; set; } + public bool IsFixedLengthSpecified + { + get { return IsFixedLength.HasValue; } + } + + public int? MaxLength { get; set; } + public bool MaxLengthSpecified + { + get { return MaxLength.HasValue; } + } + + public byte? Precision { get; set; } + public bool PrecisionSpecified + { + get { return Precision.HasValue; } + } + public int? Scale { get; set; } + public bool ScaleSpecified + { + get { return Scale.HasValue; } + } + } + + [DebuggerDisplay("Other: {OtherEntity}, Property: {OtherPropertyName}, Relationship: {RelationshipName}")] + public class Relationship : EntityBase + { + public Relationship() + { + OtherProperties = new List(); + ThisProperties = new List(); + } + + public string RelationshipName { get; set; } + + public string ThisEntity { get; set; } + public string ThisPropertyName { get; set; } + public Cardinality ThisCardinality { get; set; } + public List ThisProperties { get; set; } + + public string OtherEntity { get; set; } + public string OtherPropertyName { get; set; } + public Cardinality OtherCardinality { get; set; } + public List OtherProperties { get; set; } + + public bool? CascadeDelete { get; set; } + public bool IsForeignKey { get; set; } + public bool IsMapped { get; set; } + + public bool IsManyToMany + { + get + { + return ThisCardinality == Cardinality.Many + && OtherCardinality == Cardinality.Many; + } + } + + public bool IsOneToOne + { + get + { + return ThisCardinality != Cardinality.Many + && OtherCardinality != Cardinality.Many; + } + } + + public string JoinTable { get; set; } + public string JoinSchema { get; set; } + public List JoinThisColumn { get; set; } + public List JoinOtherColumn { get; set; } + + } + + [DebuggerDisplay("Suffix: {NameSuffix}, IsKey: {IsKey}, IsUnique: {IsUnique}")] + public class Method : EntityBase + { + public Method() + { + Properties = new List(); + } + + public string NameSuffix { get; set; } + public string SourceName { get; set; } + + public bool IsKey { get; set; } + public bool IsUnique { get; set; } + public bool IsIndex { get; set; } + + public List Properties { get; set; } + } + #endregion + + #region Collections + public class EntityCollection + : ObservableCollection + { + public bool IsProcessed { get; set; } + + public Entity ByTable(string fullName) + { + return this.FirstOrDefault(x => x.FullName == fullName); + } + + public Entity ByTable(string tableName, string tableSchema) + { + return this.FirstOrDefault(x => x.TableName == tableName && x.TableSchema == tableSchema); + } + + public Entity ByClass(string className) + { + return this.FirstOrDefault(x => x.ClassName == className); + } + + public Entity ByContext(string contextName) + { + return this.FirstOrDefault(x => x.ContextName == contextName); + } + } + + public class PropertyCollection + : ObservableCollection + { + public bool IsProcessed { get; set; } + + public IEnumerable PrimaryKeys + { + get { return this.Where(p => p.IsPrimaryKey == true); } + } + + public IEnumerable ForeignKeys + { + get { return this.Where(p => p.IsForeignKey == true); } + } + + public Property ByColumn(string columnName) + { + return this.FirstOrDefault(x => x.ColumnName == columnName); + } + + public Property ByProperty(string propertyName) + { + return this.FirstOrDefault(x => x.PropertyName == propertyName); + } + } + + public class RelationshipCollection + : ObservableCollection + { + public bool IsProcessed { get; set; } + + public Relationship ByName(string name) + { + return this.FirstOrDefault(x => x.RelationshipName == name); + } + + public Relationship ByProperty(string propertyName) + { + return this.FirstOrDefault(x => x.ThisPropertyName == propertyName); + } + + public Relationship ByOther(string name) + { + return this.FirstOrDefault(x => x.OtherEntity == name); + } + } + + public class MethodCollection + : ObservableCollection + { + public bool IsProcessed { get; set; } + } + + #endregion +} + diff --git a/CodeSmith/CSharp/Internal/Parser.cs b/CodeSmith/CSharp/Internal/Parser.cs new file mode 100644 index 0000000..95766be --- /dev/null +++ b/CodeSmith/CSharp/Internal/Parser.cs @@ -0,0 +1,639 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using ICSharpCode.NRefactory.CSharp; + +namespace SchemaMapper +{ + #region Mapping Parser + [DebuggerDisplay("Table: {TableName}, Entity: {EntityClass}, Mapping: {MappingClass}")] + public class ParsedEntity + { + public ParsedEntity() + { + Properties = new List(); + Relationships = new List(); + } + + public string EntityClass { get; set; } + public string MappingClass { get; set; } + + public string TableName { get; set; } + public string TableSchema { get; set; } + + public List Properties { get; private set; } + public List Relationships { get; private set; } + } + + [DebuggerDisplay("Column: {ColumnName}, Property: {PropertyName}")] + public class ParsedProperty + { + public string ColumnName { get; set; } + public string PropertyName { get; set; } + } + + [DebuggerDisplay("This: {ThisPropertyName}, Other: {OtherPropertyName}")] + public class ParsedRelationship + { + public ParsedRelationship() + { + ThisProperties = new List(); + JoinThisColumn = new List(); + JoinOtherColumn = new List(); + } + + public string ThisPropertyName { get; set; } + public List ThisProperties { get; private set; } + + public string OtherPropertyName { get; set; } + + public string JoinTable { get; set; } + public string JoinSchema { get; set; } + public List JoinThisColumn { get; private set; } + public List JoinOtherColumn { get; private set; } + } + + public class MappingVisitor : DepthFirstAstVisitor + { + public MappingVisitor() + { + MappingBaseType = "EntityTypeConfiguration"; + } + + public string MappingBaseType { get; set; } + public ParsedEntity ParsedEntity { get; set; } + + public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data) + { + var baseType = typeDeclaration.BaseTypes.OfType().FirstOrDefault(); + if (baseType == null || baseType.MemberName != MappingBaseType) + return base.VisitTypeDeclaration(typeDeclaration, data); + + var entity = baseType.TypeArguments.OfType().FirstOrDefault(); + if (entity == null) + return base.VisitTypeDeclaration(typeDeclaration, data); + + if (ParsedEntity == null) + ParsedEntity = new ParsedEntity(); + + ParsedEntity.EntityClass = entity.MemberName; + ParsedEntity.MappingClass = typeDeclaration.Name; + + return base.VisitTypeDeclaration(typeDeclaration, ParsedEntity); + } + + public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data) + { + if (data == null) + return base.VisitInvocationExpression(invocationExpression, null); + + // visit all the methods + var identifier = invocationExpression.Target.Children.OfType().FirstOrDefault(); + string methodName = identifier == null ? string.Empty : identifier.Name; + + // the different types of incoming data, helps us know what we're parsing + var parsedEntity = data as ParsedEntity; + var parsedProperty = data as ParsedProperty; + var parsedRelationship = data as ParsedRelationship; + + switch (methodName) + { + case "ToTable": + var tableNameExpression = invocationExpression.Arguments + .OfType() + .ToArray(); + + string tableName = null; + string tableSchema = null; + + if (tableNameExpression.Length >= 1) + tableName = tableNameExpression[0].Value.ToString(); + if (tableNameExpression.Length >= 2) + tableSchema = tableNameExpression[1].Value.ToString(); + + // ToTable is either Entity -> Table map or Many to Many map + if (parsedEntity != null) + { + // when data is ParsedEntity, entity map + parsedEntity.TableName = tableName; + parsedEntity.TableSchema = tableSchema; + } + else if (parsedRelationship != null) + { + // when data is ParsedRelationship, many to many map + parsedRelationship.JoinTable = tableName; + parsedRelationship.JoinSchema = tableSchema; + } + break; + case "HasColumnName": + var columnNameExpression = invocationExpression.Arguments + .OfType() + .FirstOrDefault(); + + if (columnNameExpression == null) + break; + + // property to column map start. + string columnName = columnNameExpression.Value.ToString(); + var property = new ParsedProperty { ColumnName = columnName }; + ParsedEntity.Properties.Add(property); + + //only have column info at this point. pass data to get property name. + return base.VisitInvocationExpression(invocationExpression, property); + case "Property": + var propertyExpression = invocationExpression.Arguments + .OfType() + .FirstOrDefault(); + + if (parsedProperty == null || propertyExpression == null) + break; + + // ParsedProperty is passed in as data from HasColumnName, add property name + var propertyBodyExpression = propertyExpression.Body as MemberReferenceExpression; + if (propertyBodyExpression != null) + parsedProperty.PropertyName = propertyBodyExpression.MemberName; + + break; + case "Map": + // start a new Many to Many relationship + var mapRelation = new ParsedRelationship(); + ParsedEntity.Relationships.Add(mapRelation); + // pass to child nodes to fill in data + return base.VisitInvocationExpression(invocationExpression, mapRelation); + case "HasForeignKey": + var foreignExpression = invocationExpression.Arguments + .OfType() + .FirstOrDefault(); + + if (foreignExpression == null) + break; + + // when only 1 fkey, body will be member ref + if (foreignExpression.Body is MemberReferenceExpression) + { + var foreignBodyExpression = foreignExpression.Body as MemberReferenceExpression; + // start a new relationship + var foreignRelation = new ParsedRelationship(); + ParsedEntity.Relationships.Add(foreignRelation); + + foreignRelation.ThisProperties.Add(foreignBodyExpression.MemberName); + // pass as data for child nodes to fill in data + return base.VisitInvocationExpression(invocationExpression, foreignRelation); + } + // when more then 1 fkey, body will be an anonymous type + if (foreignExpression.Body is AnonymousTypeCreateExpression) + { + var foreignBodyExpression = foreignExpression.Body as AnonymousTypeCreateExpression; + var foreignRelation = new ParsedRelationship(); + ParsedEntity.Relationships.Add(foreignRelation); + + var properties = foreignBodyExpression.Children + .OfType() + .Select(m => m.MemberName); + + foreignRelation.ThisProperties.AddRange(properties); + + return base.VisitInvocationExpression(invocationExpression, foreignRelation); + } + break; + case "HasMany": + var hasManyExpression = invocationExpression.Arguments + .OfType() + .FirstOrDefault(); + + if (parsedRelationship == null || hasManyExpression == null) + break; + + // filling existing relationship data + var hasManyBodyExpression = hasManyExpression.Body as MemberReferenceExpression; + if (hasManyBodyExpression != null) + parsedRelationship.ThisPropertyName = hasManyBodyExpression.MemberName; + + break; + case "WithMany": + var withManyExpression = invocationExpression.Arguments + .OfType() + .FirstOrDefault(); + + if (parsedRelationship == null || withManyExpression == null) + break; + + // filling existing relationship data + var withManyBodyExpression = withManyExpression.Body as MemberReferenceExpression; + if (withManyBodyExpression != null) + parsedRelationship.OtherPropertyName = withManyBodyExpression.MemberName; + + break; + case "HasRequired": + case "HasOptional": + var hasExpression = invocationExpression.Arguments + .OfType() + .FirstOrDefault(); + + if (parsedRelationship == null || hasExpression == null) + break; + + // filling existing relationship data + var hasBodyExpression = hasExpression.Body as MemberReferenceExpression; + if (hasBodyExpression != null) + parsedRelationship.ThisPropertyName = hasBodyExpression.MemberName; + + break; + case "MapLeftKey": + if (parsedRelationship == null) + break; + + var leftKeyExpression = invocationExpression.Arguments + .OfType() + .Select(e => e.Value.ToString()); + + parsedRelationship.JoinThisColumn.AddRange(leftKeyExpression); + break; + case "MapRightKey": + if (parsedRelationship == null) + break; + + var rightKeyExpression = invocationExpression.Arguments + .OfType() + .Select(e => e.Value.ToString()); + + parsedRelationship.JoinOtherColumn.AddRange(rightKeyExpression); + break; + } + + return base.VisitInvocationExpression(invocationExpression, data); + } + } + + public static class MappingParser + { + public static ParsedEntity Parse(string mappingFile) + { + if (string.IsNullOrEmpty(mappingFile) || !File.Exists(mappingFile)) + return null; + + var parser = new CSharpParser(); + CompilationUnit compilationUnit; + + using (var stream = File.OpenText(mappingFile)) + compilationUnit = parser.Parse(stream, mappingFile); + + var visitor = new MappingVisitor(); + + visitor.VisitCompilationUnit(compilationUnit, null); + var parsedEntity = visitor.ParsedEntity; + + if (parsedEntity != null) + Debug.WriteLine("Parsed Mapping File: '{0}'; Properties: {1}; Relationships: {2}", + Path.GetFileName(mappingFile), + parsedEntity.Properties.Count, + parsedEntity.Relationships.Count); + + return parsedEntity; + } + } + #endregion + + #region Context Parser + [DebuggerDisplay("Context: {ContextClass}")] + public class ParsedContext + { + public ParsedContext() + { + Properties = new List(); + } + + public string ContextClass { get; set; } + + public List Properties { get; private set; } + } + + [DebuggerDisplay("Entity: {EntityClass}, Property: {ContextProperty}")] + public class ParsedEntitySet + { + public string EntityClass { get; set; } + public string ContextProperty { get; set; } + } + + public class ContextVisitor : DepthFirstAstVisitor + { + public ContextVisitor() + { + ContextBaseType = "DbContext"; + DataSetType = "DbSet"; + } + + public string ContextBaseType { get; set; } + public string DataSetType { get; set; } + + public ParsedContext ParsedContext { get; set; } + + public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data) + { + var baseType = typeDeclaration.BaseTypes + .OfType() + .FirstOrDefault(); + + // warning: if inherited from custom base type, this will break + // anyway to improve this? + if (baseType == null || baseType.MemberName != ContextBaseType) + return base.VisitTypeDeclaration(typeDeclaration, data); + + if (ParsedContext == null) + ParsedContext = new ParsedContext(); + + ParsedContext.ContextClass = typeDeclaration.Name; + + return base.VisitTypeDeclaration(typeDeclaration, ParsedContext); + } + + public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data) + { + if (data == null) + return base.VisitPropertyDeclaration(propertyDeclaration, null); + + // look for property to return generic DbSet type + var memberType = propertyDeclaration.ReturnType as MemberType; + if (memberType == null || memberType.MemberName != DataSetType) + return base.VisitPropertyDeclaration(propertyDeclaration, data); + + // get the first generic type + var entityType = memberType.TypeArguments + .OfType() + .FirstOrDefault(); + + if (entityType == null) + return base.VisitPropertyDeclaration(propertyDeclaration, data); + + var entitySet = new ParsedEntitySet + { + EntityClass = entityType.MemberName, + ContextProperty = propertyDeclaration.Name + }; + + ParsedContext.Properties.Add(entitySet); + + return base.VisitPropertyDeclaration(propertyDeclaration, data); + } + } + + public static class ContextParser + { + public static ParsedContext Parse(string contextFile) + { + if (string.IsNullOrEmpty(contextFile) || !File.Exists(contextFile)) + return null; + + var parser = new CSharpParser(); + CompilationUnit compilationUnit; + + using (var stream = File.OpenText(contextFile)) + compilationUnit = parser.Parse(stream, contextFile); + + var visitor = new ContextVisitor(); + + visitor.VisitCompilationUnit(compilationUnit, null); + var parsedContext = visitor.ParsedContext; + + if (parsedContext != null) + Debug.WriteLine("Parsed Context File: '{0}'; Entities: {1}", + Path.GetFileName(contextFile), + parsedContext.Properties.Count); + + return parsedContext; + } + } + #endregion + + public static class Synchronizer + { + public static bool UpdateFromSource(EntityContext generatedContext, string contextDirectory, string mappingDirectory) + { + if (generatedContext == null) + return false; + + // make sure to update the entities before the context + UpdateFromMapping(generatedContext, mappingDirectory); + UpdateFromContext(generatedContext, contextDirectory); + return true; + } + + private static void UpdateFromContext(EntityContext generatedContext, string contextDirectory) + { + if (generatedContext == null + || contextDirectory == null + || !Directory.Exists(contextDirectory)) + return; + + // parse context + ParsedContext parsedContext = null; + var files = Directory.EnumerateFiles(contextDirectory, "*.Generated.cs").GetEnumerator(); + while (files.MoveNext() && parsedContext == null) + parsedContext = ContextParser.Parse(files.Current); + + if (parsedContext == null) + return; + + if (generatedContext.ClassName != parsedContext.ContextClass) + { + Debug.WriteLine("Rename Context Class'{0}' to '{1}'.", + generatedContext.ClassName, + parsedContext.ContextClass); + + generatedContext.ClassName = parsedContext.ContextClass; + } + + foreach (var parsedProperty in parsedContext.Properties) + { + var entity = generatedContext.Entities.ByClass(parsedProperty.EntityClass); + if (entity == null) + continue; + + + if (entity.ContextName == parsedProperty.ContextProperty) + continue; + + Debug.WriteLine("Rename Context Property'{0}' to '{1}'.", + entity.ContextName, + parsedProperty.ContextProperty); + + entity.ContextName = parsedProperty.ContextProperty; + } + } + + private static void UpdateFromMapping(EntityContext generatedContext, string mappingDirectory) + { + if (generatedContext == null + || mappingDirectory == null + || !Directory.Exists(mappingDirectory)) + return; + + // parse all mapping files + var mappingFiles = Directory.EnumerateFiles(mappingDirectory, "*.Generated.cs"); + var parsedEntities = mappingFiles + .Select(MappingParser.Parse) + .Where(parsedEntity => parsedEntity != null) + .ToList(); + + var relationshipQueue = new List>(); + + // update all entity and property names first because relationships are linked by property names + foreach (var parsedEntity in parsedEntities) + { + // find entity by table name to support renaming entity + var entity = generatedContext.Entities + .ByTable(parsedEntity.TableName, parsedEntity.TableSchema); + + if (entity == null) + continue; + + // sync names + if (entity.MappingName != parsedEntity.MappingClass) + { + Debug.WriteLine("Rename Mapping Class'{0}' to '{1}'.", + entity.MappingName, + parsedEntity.MappingClass); + + entity.MappingName = parsedEntity.MappingClass; + } + + // use rename api to make sure all instances are renamed + generatedContext.RenameEntity(entity.ClassName, parsedEntity.EntityClass); + + // sync properties + foreach (var parsedProperty in parsedEntity.Properties) + { + // find property by column name to support property name rename + var property = entity.Properties.ByColumn(parsedProperty.ColumnName); + if (property == null) + continue; + + // use rename api to make sure all instances are renamed + generatedContext.RenameProperty( + entity.ClassName, + property.PropertyName, + parsedProperty.PropertyName); + } + + // save relationship for later processing + var item = new Tuple(entity, parsedEntity); + relationshipQueue.Add(item); + } + + // update relationships last + foreach (var tuple in relationshipQueue) + UpdateRelationships(generatedContext, tuple.Item1, tuple.Item2); + } + + private static void UpdateRelationships(EntityContext generatedContext, Entity entity, ParsedEntity parsedEntity) + { + // sync relationships + foreach (var parsedRelationship in parsedEntity.Relationships.Where(r => r.JoinTable == null)) + { + var parsedProperties = parsedRelationship.ThisProperties; + var relationship = entity.Relationships + .Where(r => !r.IsManyToMany) + .FirstOrDefault(r => r.ThisProperties.Except(parsedProperties).Count() == 0); + + if (relationship == null) + continue; + + bool isThisSame = relationship.ThisPropertyName == parsedRelationship.ThisPropertyName; + bool isOtherSame = relationship.OtherPropertyName == parsedRelationship.OtherPropertyName; + + if (isThisSame && isOtherSame) + continue; + + if (!isThisSame) + { + Debug.WriteLine("Rename Relationship Property '{0}.{1}' to '{0}.{2}'.", + relationship.ThisEntity, + relationship.ThisPropertyName, + parsedRelationship.ThisPropertyName); + + relationship.ThisPropertyName = parsedRelationship.ThisPropertyName; + } + if (!isOtherSame) + { + Debug.WriteLine("Rename Relationship Property '{0}.{1}' to '{0}.{2}'.", + relationship.OtherEntity, + relationship.OtherPropertyName, + parsedRelationship.OtherPropertyName); + + relationship.OtherPropertyName = parsedRelationship.OtherPropertyName; + } + + // sync other relationship + var otherEntity = generatedContext.Entities.ByClass(relationship.OtherEntity); + if (otherEntity == null) + continue; + + var otherRelationship = otherEntity.Relationships.ByName(relationship.RelationshipName); + if (otherRelationship == null) + continue; + + otherRelationship.ThisPropertyName = relationship.OtherPropertyName; + otherRelationship.OtherPropertyName = relationship.ThisPropertyName; + } + + // sync many to many + foreach (var parsedRelationship in parsedEntity.Relationships.Where(r => r.JoinTable != null)) + { + var joinThisColumn = parsedRelationship.JoinThisColumn; + var joinOtherColumn = parsedRelationship.JoinOtherColumn; + + var relationship = entity.Relationships + .Where(r => r.IsManyToMany) + .FirstOrDefault(r => + r.JoinThisColumn.Except(joinThisColumn).Count() == 0 && + r.JoinOtherColumn.Except(joinOtherColumn).Count() == 0 && + r.JoinTable == parsedRelationship.JoinTable && + r.JoinSchema == parsedRelationship.JoinSchema); + + if (relationship == null) + continue; + + + bool isThisSame = relationship.ThisPropertyName == parsedRelationship.ThisPropertyName; + bool isOtherSame = relationship.OtherPropertyName == parsedRelationship.OtherPropertyName; + + if (isThisSame && isOtherSame) + continue; + + if (!isThisSame) + { + Debug.WriteLine("Rename Relationship Property '{0}.{1}' to '{0}.{2}'.", + relationship.ThisEntity, + relationship.ThisPropertyName, + parsedRelationship.ThisPropertyName); + + relationship.ThisPropertyName = parsedRelationship.ThisPropertyName; + } + if (!isOtherSame) + { + Debug.WriteLine("Rename Relationship Property '{0}.{1}' to '{0}.{2}'.", + relationship.OtherEntity, + relationship.OtherPropertyName, + parsedRelationship.OtherPropertyName); + + relationship.OtherPropertyName = parsedRelationship.OtherPropertyName; + } + + // sync other relationship + var otherEntity = generatedContext.Entities.ByClass(relationship.OtherEntity); + if (otherEntity == null) + continue; + + var otherRelationship = otherEntity.Relationships.ByName(relationship.RelationshipName); + if (otherRelationship == null) + continue; + + otherRelationship.ThisPropertyName = relationship.OtherPropertyName; + otherRelationship.OtherPropertyName = relationship.ThisPropertyName; + } + } + } +} diff --git a/CodeSmith/CSharp/Web/Controller.cst b/CodeSmith/CSharp/Web/Controller.cst new file mode 100644 index 0000000..9957a1c --- /dev/null +++ b/CodeSmith/CSharp/Web/Controller.cst @@ -0,0 +1,105 @@ +<%-- +Name: Database Table Properties +Author: yubaolee +Description: Create a list of properties from a database table +--%> +<%@ CodeTemplate Language="C#" Encoding="utf-8" TargetLanguage="C#" Debug="False" Description="控制器" %> +<%@ Property Name="ModuleName" Type="String" Category="Context" Description="模块名称" %> +<%@ Map Name="CSharpAlias" Src="System-CSharpAlias" Description="System to C# Type Map" %> +<%@ Assembly Name="SchemaExplorer" %> +<%@ Import Namespace="SchemaExplorer" %> + +using System; +using System.Collections.Generic; +using System.Linq; +using Infrastructure; +using Microsoft.AspNetCore.Mvc; +using OpenAuth.App; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.Mvc.Controllers +{ + public class <%=ModuleName%>sController : BaseController + { + private readonly <%=ModuleName%>App _app; + + public <%=ModuleName%>sController(<%=ModuleName%>App app, IAuth auth) : base(auth) + { + _app = app; + } + + //主页 + public ActionResult Index() + { + return View(); + } + + /// + /// MVC界面添加 + /// + /// + /// + [HttpPost] + public string Add(AddOrUpdate<%=ModuleName%>Req obj) + { + try + { + _app.Add(obj); + + } + catch (Exception ex) + { + Result.Code = 500; + Result.Message = ex.Message; + } + return JsonHelper.Instance.Serialize(Result); + } + + /// + /// MVC界面修改 + /// + /// + /// + [HttpPost] + public string Update(AddOrUpdate<%=ModuleName%>Req obj) + { + try + { + _app.Update(obj); + + } + catch (Exception ex) + { + Result.Code = 500; + Result.Message = ex.Message; + } + return JsonHelper.Instance.Serialize(Result); + } + + /// + /// 加载列表 + /// + public string Load([FromQuery]Query<%=ModuleName%>ListReq request) + { + return JsonHelper.Instance.Serialize(_app.Load(request)); + } + + [HttpPost] + public string Delete(string[] ids) + { + try + { + _app.Delete(ids); + } + catch (Exception e) + { + Result.Code = 500; + Result.Message = e.Message; + } + + return JsonHelper.Instance.Serialize(Result); + } + } +} \ No newline at end of file diff --git a/CodeSmith/CSharp/Web/Index.cshtml.cst b/CodeSmith/CSharp/Web/Index.cshtml.cst new file mode 100644 index 0000000..7618888 --- /dev/null +++ b/CodeSmith/CSharp/Web/Index.cshtml.cst @@ -0,0 +1,98 @@ +<%-- +Name: 列表页面 +Author: yubaolee +Description: 列表页面 +--%> +<%@ CodeTemplate Language="C#" TargetLanguage="C#" Debug="False" Encoding="utf-8" Description="添加模块" %> +<%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="Context" +Description="连接的数据库" %> +<%@ Property Name="ModuleName" Type="String" Category="Context" Description="模块名称" %> + +<%@ Map Name="CSharpAlias" Src="System-CSharpAlias" Description="System to C# Type Map" %> +<%@ Assembly Name="SchemaExplorer" %> +<%@ Import Namespace="SchemaExplorer" %> +<%@ Assembly Src="Util.cs" %> +<%@ Import Namespace="Util" %> + +@section header +{ + +} + + +
+ + +
+ + + +
+ + + + + + + + diff --git a/CodeSmith/CSharp/Web/Util.cs b/CodeSmith/CSharp/Web/Util.cs new file mode 100644 index 0000000..a6832e4 --- /dev/null +++ b/CodeSmith/CSharp/Web/Util.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using CodeSmith.Engine; +using SchemaExplorer; + +namespace Util{ + public class Tools{ + public static String GetDescription(ColumnSchema column) { //得到字段的描述 + if(string.IsNullOrEmpty(column.Description)) + return column.Name; + else + return column.Description; + } + + public static bool NeedCascade(TableSchema SourceTable){ //判断表中是否需要下拉选择树 + return SourceTable.Columns.Contains("ParentId") + || SourceTable.Columns.Contains("CascadeId") ; + } + + + public static string CreateBlank(int level){ + if(level == 1){ + return " "; + } + else{ + var twoblanks = " "; + for (int i = level-1; i > 1; i--) + { + twoblanks +=twoblanks; + } + return CreateBlank(1) + twoblanks; + } + } + } +} \ No newline at end of file diff --git a/CodeSmith/CSharp/Web/index.js.cst b/CodeSmith/CSharp/Web/index.js.cst new file mode 100644 index 0000000..f76bdda --- /dev/null +++ b/CodeSmith/CSharp/Web/index.js.cst @@ -0,0 +1,186 @@ +<%-- +Name: 主JS界面 +Author: yubaolee +--%> +<%@ CodeTemplate Language="C#" TargetLanguage="C#" Debug="False" Encoding="utf-8" Description="添加模块" %> +<%@ Property Name="ModuleName" Type="String" Category="Context" Description="模块名称" %> + +<%@ Map Name="CSharpAlias" Src="System-CSharpAlias" Description="System to C# Type Map" %> +<%@ Assembly Name="SchemaExplorer" %> +<%@ Import Namespace="SchemaExplorer" %> +<%@ Assembly Src="Util.cs" %> +<%@ Import Namespace="Util" %> + +layui.config({ + base: "/js/" +}).use(['form', 'vue', 'ztree', 'layer', 'jquery', 'table', 'droptree', 'openauth', 'utils'], function () { + var form = layui.form, + layer = layui.layer, + $ = layui.jquery; + var table = layui.table; + var openauth = layui.openauth; + var toplayer = (top == undefined || top.layer === undefined) ? layer : top.layer; //顶层的LAYER + + $("#menus").loadMenus("<%=ModuleName%>"); + + + //加载表头 + $.getJSON('/<%=ModuleName%>s/Load', + { page: 1, limit: 1 }, + function (data) { + var columns = data.columnFields.filter(u => u.IsList ===true).map(function (e) { + return { + field: e.ColumnName, + title: e.Comment + }; + }); + columns.unshift({ + type: 'checkbox', + fixed: 'left' + }); + table.render({ + elem: '#mainList', + page: true, + url: '/<%=ModuleName%>s/Load', + cols: [columns] + , response: { + statusCode: 200 //规定成功的状态码,默认:0 + } + }); + }); + + + //主列表加载,可反复调用进行刷新 + var config = {}; //table的参数,如搜索key,点击tree的id + var mainList = function(options) { + if (options != undefined) { + $.extend(config, options); + } + table.reload('mainList', + { + url: '/<%=ModuleName%>s/Load', + where: config + , response: { + statusCode: 200 //规定成功的状态码,默认:0 + } + }); + }; + mainList(); + + //添加(编辑)对话框 + var editDlg = function () { + var vm; + var update = false; //是否为更新 + var show = function (data) { + var title = update ? "编辑信息" : "添加"; + layer.open({ + title: title, + area: ["500px", "400px"], + type: 1, + content: $('#divEdit'), + success: function () { + if(vm == undefined){ + vm = new Vue({ + el: "#formEdit", + data(){ + return { + tmp:data //使用一个tmp封装一下,后面可以直接用vm.tmp赋值 + } + }, + watch:{ + tmp(val){ + this.$nextTick(function () { + form.render(); //刷新select等 + layui.droptree("/Applications/GetList", "#AppName", "#AppId", false); + + }) + } + }, + mounted(){ + form.render(); + layui.droptree("/Applications/GetList", "#AppName", "#AppId", false); + + } + }); + }else{ + vm.tmp = Object.assign({}, vm.tmp,data) + } + }, + end: mainList + }); + var url = "/<%=ModuleName%>s/Add"; + if (update) { + url = "/<%=ModuleName%>s/Update"; + } + //提交数据 + form.on('submit(formSubmit)', + function (data) { + $.post(url, + data.field, + function (data) { + layer.msg(data.Message); + }, + "json"); + return false; + }); + } + return { + add: function () { //弹出添加 + update = false; + show({ + Id: '' + }); + }, + update: function (data) { //弹出编辑框 + update = true; + show(data); + } + }; + }(); + + //监听表格内部按钮 + table.on('tool(list)', function (obj) { + var data = obj.data; + if (obj.event === 'detail') { //查看 + layer.msg('ID:' + data.Id + ' 的查看操作'); + } + }); + + + //监听页面主按钮操作 + var active = { + btnDel: function () { //批量删除 + var checkStatus = table.checkStatus('mainList') + , data = checkStatus.data; + openauth.del("/<%=ModuleName%>s/Delete", + data.map(function (e) { return e.Id; }), + mainList); + } + , btnAdd: function () { //添加 + editDlg.add(); + } + , btnEdit: function () { //编辑 + var checkStatus = table.checkStatus('mainList') + , data = checkStatus.data; + if (data.length != 1) { + layer.msg("请选择编辑的行,且同时只能编辑一行"); + return; + } + editDlg.update(data[0]); + } + + , search: function () { //搜索 + mainList({ key: $('#key').val() }); + } + , btnRefresh: function () { + mainList(); + } + }; + + $('.toolList .layui-btn').on('click', function () { + var type = $(this).data('type'); + active[type] ? active[type].call(this) : ''; + }); + + //监听页面主按钮操作 end +}) diff --git a/CodeSmith/CSharp/WebGenerate.cst b/CodeSmith/CSharp/WebGenerate.cst new file mode 100644 index 0000000..c050980 --- /dev/null +++ b/CodeSmith/CSharp/WebGenerate.cst @@ -0,0 +1,130 @@ +<%-- +Author: yubaolee +Description: 用于生成OpenAuth.Core开源版前端Web界面,包括mvc controller/csthml/js +--%> +<%@ Template Language="C#" TargetLanguage="Text" Debug="True" OutputType="None" %> + +<%@ Assembly Name="SchemaExplorer" %> +<%@ Assembly Name="CodeSmith.CustomProperties" %> + +<%@ Assembly Name="Mono.Cecil" Path="..\Common" %> +<%@ Assembly Name="ICSharpCode.NRefactory" Path="..\Common" %> +<%@ Assembly Name="ICSharpCode.NRefactory.CSharp" Path="..\Common" %> + +<%@ Assembly Src="Internal\Model.cs" %> +<%@ Assembly Src="Internal\Extensions.cs" %> +<%@ Assembly Src="Internal\Generator.cs" %> +<%@ Assembly Src="Internal\Parser.cs" %> + +<%@ Import Namespace="System.Collections.Generic" %> +<%@ Import Namespace="System.IO" %> +<%@ Import Namespace="System.Linq" %> +<%@ Import Namespace="System.Text" %> +<%@ Import Namespace="System.Text.RegularExpressions" %> + +<%@ Import Namespace="SchemaMapper" %> + +<%@ Property Name="SourceTable" +Type="SchemaExplorer.TableSchema" +Category="Context" +Description="连接的数据库" +OnChanged="OnSourceDatabaseChanged"%> + +<%@ Property Name="ModuleName" + Type="System.String" + Description="模块名称,如:User"%> +<%@ Property Name="directory" + Type="System.String" + Default=".\" + Optional="True" + Description="代码生成路径" + Editor="System.Windows.Forms.Design.FolderNameEditor, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %> + +<%@ Register Name="HtmlGenerateClass" + Template="Web\Index.cshtml.cst" + MergeProperties="False" %> +<%@ Register Name="JSGenerateClass" + Template="Web\index.js.cst" + MergeProperties="False" %> +<%@ Register Name="ControllerGenerateClass" + Template="Web\Controller.cst" + MergeProperties="False" %> +Generating Entities ... +<% Generate(); %> + + \ No newline at end of file diff --git a/CodeSmith/Common/ICSharpCode.NRefactory.CSharp.dll b/CodeSmith/Common/ICSharpCode.NRefactory.CSharp.dll new file mode 100644 index 0000000000000000000000000000000000000000..978ef7175e3ae23f3fb7d0a2a91578da4ca06b2a GIT binary patch literal 2179072 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%0Dv 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%0AIW2Z+N2lk7_8R5B>&3%qnN5Yg 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≦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

=A*tX12HWOWP=I2yz8F&x9;h-AJ- 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

SJCX3wT7Nn(p578VPQL7Q>SHPYi#R% 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 F{~ytz`NRMK literal 0 HcmV?d00001 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b7a9eed --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +##See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. +#FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +#WORKDIR /app +#EXPOSE 10010 +# +#COPY . . +#ENV ASPNETCORE_URLS=http://+:10010 +#ENTRYPOINT ["dotnet", "/app/OpenAuth.WebApi.dll"] + + +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 10010 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["OpenAuth.WebApi/OpenAuth.WebApi.csproj", "OpenAuth.WebApi/"] +COPY ["Infrastructure/Infrastructure.csproj", "Infrastructure/"] +COPY ["OpenAuth.App/OpenAuth.App.csproj", "OpenAuth.App/"] +COPY ["OpenAuth.Repository/OpenAuth.Repository.csproj", "OpenAuth.Repository/"] +RUN dotnet restore "OpenAuth.WebApi/OpenAuth.WebApi.csproj" +COPY . . +WORKDIR "/src/OpenAuth.WebApi" +RUN dotnet build "OpenAuth.WebApi.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "OpenAuth.WebApi.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENV ASPNETCORE_URLS=http://+:10010 +ENTRYPOINT ["dotnet", "OpenAuth.WebApi.dll"] + diff --git a/Infrastructure/AppSetting.cs b/Infrastructure/AppSetting.cs new file mode 100644 index 0000000..861f385 --- /dev/null +++ b/Infrastructure/AppSetting.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; + +namespace Infrastructure +{ + /// + /// 配置项 + /// + public class AppSetting + { + + public AppSetting() + { + SSOPassport = "http://localhost:52789"; + Version = ""; + UploadPath = ""; + IdentityServerUrl = ""; + } + /// + /// SSO地址 + /// + public string SSOPassport { get; set; } + + /// + /// 版本信息 + /// 如果为demo,则屏蔽Post请求 + /// + public string Version { get; set; } + + /// + /// 数据库类型 SqlServer、MySql + /// + public Dictionary DbTypes { get; set; } + + /// 附件上传路径 + public string UploadPath { get; set; } + + //identity授权的地址 + public string IdentityServerUrl { get; set; } + + /// + /// Redis服务器配置 + /// + //public string RedisConf { get; set; } + public RedisConf RedisConf { get; set; } + + //是否是Identity授权方式 + public bool IsIdentityAuth => !string.IsNullOrEmpty(IdentityServerUrl); + } + + public class RedisConf + { + public string Conn { get; set; } + public int Database { get; set; } + } +} diff --git a/Infrastructure/AutoMapperExt.cs b/Infrastructure/AutoMapperExt.cs new file mode 100644 index 0000000..7dc7c53 --- /dev/null +++ b/Infrastructure/AutoMapperExt.cs @@ -0,0 +1,74 @@ +// *********************************************************************** +// Assembly : FairUtility +// Author : Yubao Li +// Created : 08-27-2015 +// +// Last Modified By : Yubao Li +// Last Modified On : 08-27-2015 +// *********************************************************************** +// +// Copyright (c) . All rights reserved. +// +// +// *********************************************************************** + +using System; +using AutoMapper; +using System.Collections; +using System.Collections.Generic; + +namespace Infrastructure +{ + public static class AutoMapperExt + { + /// + /// 类型映射 + /// + public static T MapTo(this object obj) + { + if (obj == null) return default(T); + + var config = new MapperConfiguration(cfg=>cfg.CreateMap(obj.GetType(),typeof(T))); + var mapper = config.CreateMapper(); + return mapper.Map(obj); + } + + /// + /// 集合列表类型映射 + /// + public static List MapToList(this IEnumerable source) + { + Type sourceType = source.GetType().GetGenericArguments()[0]; //获取枚举的成员类型 + var config = new MapperConfiguration(cfg => cfg.CreateMap(sourceType, typeof(TDestination))); + var mapper = config.CreateMapper(); + + return mapper.Map>(source); + } + + /// + /// 集合列表类型映射 + /// + public static List MapToList(this IEnumerable source) + { + var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination))); + var mapper = config.CreateMapper(); + + return mapper.Map>(source); + } + + /// + /// 类型映射 + /// + public static TDestination MapTo(this TSource source, TDestination destination) + where TSource : class + where TDestination : class + { + if (source == null) return destination; + + var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination))); + var mapper = config.CreateMapper(); + return mapper.Map(source); + } + + } +} \ No newline at end of file diff --git a/Infrastructure/Cache/CacheContext.cs b/Infrastructure/Cache/CacheContext.cs new file mode 100644 index 0000000..a11f0a0 --- /dev/null +++ b/Infrastructure/Cache/CacheContext.cs @@ -0,0 +1,88 @@ +// *********************************************************************** +// Assembly : Helper +// Author : yubaolee +// Created : 12-16-2016 +// +// Last Modified By : yubaolee +// Last Modified On : 12-21-2016 +// 使用微软默认带超时的Cache +// File: CacheContext.cs +// *********************************************************************** + +using System; +using System.Collections.Concurrent; +using Microsoft.Extensions.Caching.Memory; + +namespace Infrastructure.Cache +{ + public class CacheContext : ICacheContext + { + private IMemoryCache _objCache; + private static readonly ConcurrentDictionary> queueDic = new ConcurrentDictionary>(); + public CacheContext(IMemoryCache objCache) + { + _objCache = objCache; + } + + public override T Get(string key) + { + return _objCache.Get(key); + } + + public override bool Set(string key, T t, DateTime expire) + { + var obj = Get(key); + if (obj != null) + { + Remove(key); + } + + _objCache.Set(key, t, new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(expire)); //绝对过期时间 + + return true; + } + + public override bool Remove(string key) + { + _objCache.Remove(key); + return true; + } + /// + /// 添加并发锁 + /// + /// 值 + /// 执行方法 + /// 键 + /// + public override async Task Lock(string id, Func> func, string key = "hc") + { + var queue = queueDic.GetOrAdd(id, new ConcurrentQueue()); + var token = Guid.NewGuid().ToString(); + queue.Enqueue(token); + queue.TryPeek(out string newToken); + if (token != newToken) + { + while (true) + { + Thread.Sleep(10); + queue.TryPeek(out newToken); + if (token == newToken) + { + break; + } + } + } + + try + { + return await func(id); + } + finally + { + queue.TryDequeue(out string _); + } + + } + } +} diff --git a/Infrastructure/Cache/EnyimMemcachedContext.cs b/Infrastructure/Cache/EnyimMemcachedContext.cs new file mode 100644 index 0000000..c2fc64c --- /dev/null +++ b/Infrastructure/Cache/EnyimMemcachedContext.cs @@ -0,0 +1,55 @@ +// *********************************************************************** +// Assembly : Infrastructure +// Author : yubaolee +// Created : 06-21-2016 +// +// Last Modified By : yubaolee +// Last Modified On : 06-21-2016 +// Contact : Add services.AddEnyimMemcached(...) +// and app.UseEnyimMemcached() in Startup. +// File: EnyimMemcachedContext.cs +// *********************************************************************** + + + +using System; +using Enyim.Caching; +using Enyim.Caching.Memcached; + +namespace Infrastructure.Cache +{ + public sealed class EnyimMemcachedContext : ICacheContext + { + private IMemcachedClient _memcachedClient; + + public EnyimMemcachedContext(IMemcachedClient client) + { + _memcachedClient = client; + } + + /// + /// + /// + /// + /// + /// + public override T Get(string key) + { + return _memcachedClient.Get(key); + } + + public override bool Set(string key, T t, DateTime expire) + { + return _memcachedClient.Store(StoreMode.Set, key, t, expire); + } + + public override bool Remove(string key) + { + return _memcachedClient.Remove(key); + } + public override Task Lock(string id, Func> func, string key = "hc") + { + return func(id); + } + } +} \ No newline at end of file diff --git a/Infrastructure/Cache/ICacheContext.cs b/Infrastructure/Cache/ICacheContext.cs new file mode 100644 index 0000000..89580b7 --- /dev/null +++ b/Infrastructure/Cache/ICacheContext.cs @@ -0,0 +1,36 @@ +using System; + +namespace Infrastructure.Cache +{ + /// + /// 缓存接口 + /// + public abstract class ICacheContext + { + /// + /// 获取缓存项 + /// + /// 缓存对象类型 + /// 键 + /// 缓存对象 + public abstract T Get(string key); + + /// + /// 设置缓存项 + /// + /// 缓存对象类型 + /// 键 + /// 缓存对象 + /// true成功,false失败 + public abstract bool Set(string key, T t, DateTime expire); + + /// + /// 移除一个缓存项 + /// + /// 缓存项key + /// true成功,false失败 + public abstract bool Remove(string key); + public abstract Task Lock(string id, Func> func, string key = "hc"); + + } +} \ No newline at end of file diff --git a/Infrastructure/Cache/RedisCacheContext.cs b/Infrastructure/Cache/RedisCacheContext.cs new file mode 100644 index 0000000..ceedd6d --- /dev/null +++ b/Infrastructure/Cache/RedisCacheContext.cs @@ -0,0 +1,63 @@ +using System; +using Enyim.Caching; +using Enyim.Caching.Memcached; +using Microsoft.Extensions.Options; +using StackExchange.Redis; + +namespace Infrastructure.Cache +{ + /// + /// 缓存redis实现 + /// + public sealed class RedisCacheContext : ICacheContext + { + private ConnectionMultiplexer _conn { get; set; } + private IDatabase iDatabase { get; set; } + + public RedisCacheContext(IOptions options) + { + _conn = ConnectionMultiplexer.Connect(options.Value.RedisConf.Conn); + iDatabase = _conn.GetDatabase(options.Value.RedisConf.Database); + } + + public override T Get(string key) + { + RedisValue value = iDatabase.StringGet(key); + if (!value.HasValue) + { + return default(T); + } + + if (typeof(T) == typeof(string)) + { + return (T)Convert.ChangeType(value, typeof(T)); + } + else + { + return JsonHelper.Instance.Deserialize(value); + } + } + + public override bool Set(string key, T t, DateTime expire) + { + if (typeof(T) == typeof(string)) + { + return iDatabase.StringSet(key, t.ToString(), expire - DateTime.Now); + } + else + { + return iDatabase.StringSet(key, JsonHelper.Instance.Serialize(t), expire - DateTime.Now); + } + } + + public override bool Remove(string key) + { + return iDatabase.KeyDelete(key); + } + + public override Task Lock(string id, Func> func, string key = "hc") + { + return func(id); + } + } +} \ No newline at end of file diff --git a/Infrastructure/CommonException.cs b/Infrastructure/CommonException.cs new file mode 100644 index 0000000..32e0cc2 --- /dev/null +++ b/Infrastructure/CommonException.cs @@ -0,0 +1,22 @@ + +using System; + +namespace Infrastructure +{ + public class CommonException : Exception + { + private int _code; + + public CommonException(string message, int code) + : base(message) + { + this._code = code; + } + + public int Code + { + get { return _code; } + } + + } +} diff --git a/Infrastructure/Const/FlowInstanceStatus.cs b/Infrastructure/Const/FlowInstanceStatus.cs new file mode 100644 index 0000000..3e3c86a --- /dev/null +++ b/Infrastructure/Const/FlowInstanceStatus.cs @@ -0,0 +1,30 @@ +namespace Infrastructure.Const +{ + /// + /// 流程状态 + /// + public struct FlowInstanceStatus + { + /// + /// 撤销、召回 + /// + public const int Draft = -1; + /// + /// 正在运行 + /// + public const int Running = 0; + /// + /// 完成 + /// + public const int Finished = 1; + /// + /// 不同意 + /// + public const int Disagree = 3; + /// + /// 驳回 + /// + public const int Rejected = 4; + + } +} \ No newline at end of file diff --git a/Infrastructure/Const/HtmlElementType.cs b/Infrastructure/Const/HtmlElementType.cs new file mode 100644 index 0000000..0389706 --- /dev/null +++ b/Infrastructure/Const/HtmlElementType.cs @@ -0,0 +1,26 @@ +namespace Infrastructure.Const +{ + public struct HtmlElementType + { + public const string drop = "drop"; + public const string droplist = "droplist"; + public const string select = "select"; + public const string selectlist = "selectlist"; + public const string checkbox = "checkbox"; + public const string textarea = "textarea"; + public const string thanorequal = "thanorequal"; + public const string lessorequal = "lessorequal"; + + + public const string gt = "gt"; + public const string lt = "lt"; + public const string GT = ">"; + public const string LT = "<"; + public const string like = "like"; + + public const string ThanOrEqual = ">="; + public const string LessOrequal = "<="; + public const string Contains = "in"; + public const string Equal = "="; + } +} \ No newline at end of file diff --git a/Infrastructure/Const/JobStatus.cs b/Infrastructure/Const/JobStatus.cs new file mode 100644 index 0000000..7616d75 --- /dev/null +++ b/Infrastructure/Const/JobStatus.cs @@ -0,0 +1,17 @@ +namespace Infrastructure.Const +{ + /// + /// 定时任务状态 + /// + public enum JobStatus + { + /// + /// 未启动 + /// + NotRun, + /// + /// 正在运行 + /// + Running + } +} \ No newline at end of file diff --git a/Infrastructure/Const/LinqExpressionType.cs b/Infrastructure/Const/LinqExpressionType.cs new file mode 100644 index 0000000..ecc32e2 --- /dev/null +++ b/Infrastructure/Const/LinqExpressionType.cs @@ -0,0 +1,15 @@ +namespace Infrastructure.Const +{ + public enum LinqExpressionType + { + Equal=0,//= + NotEqual=1,//!= + GreaterThan,//> + LessThan,//< + ThanOrEqual,//>= + LessThanOrEqual,//<= + In, + Contains,//Contains + NotContains//NotContains + } +} diff --git a/Infrastructure/Const/QueryOrderBy.cs b/Infrastructure/Const/QueryOrderBy.cs new file mode 100644 index 0000000..f409707 --- /dev/null +++ b/Infrastructure/Const/QueryOrderBy.cs @@ -0,0 +1,8 @@ +namespace Infrastructure.Const +{ + public enum QueryOrderBy + { + Desc=1, + Asc=2 + } +} diff --git a/Infrastructure/Const/ResponseType.cs b/Infrastructure/Const/ResponseType.cs new file mode 100644 index 0000000..1552f90 --- /dev/null +++ b/Infrastructure/Const/ResponseType.cs @@ -0,0 +1,27 @@ +namespace Infrastructure.Const +{ + public enum ResponseType + { + ServerError = 1, + LoginExpiration = 302, + ParametersLack = 303, + TokenExpiration, + PINError, + NoPermissions, + NoRolePermissions, + LoginError, + AccountLocked, + LoginSuccess, + SaveSuccess, + AuditSuccess, + OperSuccess, + RegisterSuccess, + ModifyPwdSuccess, + EidtSuccess, + DelSuccess, + NoKey, + NoKeyDel, + KeyError, + Other + } +} diff --git a/Infrastructure/Const/SqlDbTypeName.cs b/Infrastructure/Const/SqlDbTypeName.cs new file mode 100644 index 0000000..2bc9bc7 --- /dev/null +++ b/Infrastructure/Const/SqlDbTypeName.cs @@ -0,0 +1,24 @@ +namespace Infrastructure.Const +{ + public struct SqlDbTypeName + { + public const string NVarChar = "nvarchar"; + public const string VarChar = "varchar"; + public const string NChar = "nchar"; + public const string Char = "char"; + public const string Text = "text"; + public const string Int = "int"; + public const string BigInt = "bigint"; + public const string DateTime = "datetime"; + public const string Date = "date"; + public const string SmallDateTime = "smalldatetime"; + public const string SmallDate = "smalldate"; + public const string Float = "float"; + public const string Decimal = "decimal"; + public const string Double = "double"; + public const string Bit = "bit"; + public const string Bool = "bool"; + public const string UniqueIdentifier = "uniqueidentifier"; + + } +} diff --git a/Infrastructure/Database/DbDataConvertExtensions.cs b/Infrastructure/Database/DbDataConvertExtensions.cs new file mode 100644 index 0000000..517f7ad --- /dev/null +++ b/Infrastructure/Database/DbDataConvertExtensions.cs @@ -0,0 +1,412 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Data; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Infrastructure.Extensions; + +namespace Infrastructure.Database +{ + /// + /// 数据库数据转换拓展 + /// + public static class DbDataConvertExtensions + { + /// + /// 将 DataTable 转 List 集合 + /// + /// 返回值类型 + /// DataTable + /// List{T} + public static List ToList(this DataTable dataTable) + { + return dataTable.ToList(typeof(List)) as List; + } + + /// + /// 将 DataTable 转 List 集合 + /// + /// 返回值类型 + /// DataTable + /// List{T} + public static async Task> ToListAsync(this DataTable dataTable) + { + var list = await dataTable.ToListAsync(typeof(List)); + return list as List; + } + + /// + /// 将 DataSet 转 元组 + /// + /// 元组元素类型 + /// DataSet + /// 元组类型 + public static List ToList(this DataSet dataSet) + { + var tuple = dataSet.ToList(typeof(List)); + return tuple[0] as List; + } + + /// + /// 将 DataSet 转 元组 + /// + /// 元组元素类型 + /// 元组元素类型 + /// DataSet + /// 元组类型 + public static (List list1, List list2) ToList(this DataSet dataSet) + { + var tuple = dataSet.ToList(typeof(List), typeof(List)); + return (tuple[0] as List, tuple[1] as List); + } + + /// + /// 将 DataSet 转 元组 + /// + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// DataSet + /// 元组类型 + public static (List list1, List list2, List list3) ToList(this DataSet dataSet) + { + var tuple = dataSet.ToList(typeof(List), typeof(List), typeof(List)); + return (tuple[0] as List, tuple[1] as List, tuple[2] as List); + } + + /// + /// 将 DataSet 转 元组 + /// + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// DataSet + /// 元组类型 + public static (List list1, List list2, List list3, List list4) ToList(this DataSet dataSet) + { + var tuple = dataSet.ToList(typeof(List), typeof(List), typeof(List), typeof(List)); + return (tuple[0] as List, tuple[1] as List, tuple[2] as List, tuple[3] as List); + } + + /// + /// 将 DataSet 转 元组 + /// + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// DataSet + /// 元组类型 + public static (List list1, List list2, List list3, List list4, List list5) ToList(this DataSet dataSet) + { + var tuple = dataSet.ToList(typeof(List), typeof(List), typeof(List), typeof(List), typeof(List)); + return (tuple[0] as List, tuple[1] as List, tuple[2] as List, tuple[3] as List, tuple[4] as List); + } + + /// + /// 将 DataSet 转 元组 + /// + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// DataSet + /// 元组类型 + public static (List list1, List list2, List list3, List list4, List list5, List list6) ToList(this DataSet dataSet) + { + var tuple = dataSet.ToList(typeof(List), typeof(List), typeof(List), typeof(List), typeof(List), typeof(List)); + return (tuple[0] as List, tuple[1] as List, tuple[2] as List, tuple[3] as List, tuple[4] as List, tuple[5] as List); + } + + /// + /// 将 DataSet 转 元组 + /// + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// DataSet + /// 元组类型 + public static (List list1, List list2, List list3, List list4, List list5, List list6, List list7) ToList(this DataSet dataSet) + { + var tuple = dataSet.ToList(typeof(List), typeof(List), typeof(List), typeof(List), typeof(List), typeof(List), typeof(List)); + return (tuple[0] as List, tuple[1] as List, tuple[2] as List, tuple[3] as List, tuple[4] as List, tuple[5] as List, tuple[6] as List); + } + + /// + /// 将 DataSet 转 元组 + /// + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// 元组元素类型 + /// DataSet + /// 元组类型 + public static (List list1, List list2, List list3, List list4, List list5, List list6, List list7, List list8) ToList(this DataSet dataSet) + { + var tuple = dataSet.ToList(typeof(List), typeof(List), typeof(List), typeof(List), typeof(List), typeof(List), typeof(List), typeof(List)); + return (tuple[0] as List, tuple[1] as List, tuple[2] as List, tuple[3] as List, tuple[4] as List, tuple[5] as List, tuple[6] as List, tuple[7] as List); + } + + /// + /// 将 DataSet 转 特定类型 + /// + /// DataSet + /// 特定类型集合 + /// List{object} + public static List ToList(this DataSet dataSet, params Type[] returnTypes) + { + if (returnTypes == null || returnTypes.Length == 0) return default; + + // 处理元组类型 + if (returnTypes.Length == 1 && returnTypes[0].IsValueType) + { + returnTypes = returnTypes[0].GenericTypeArguments; + } + + // 获取所有的 DataTable + var dataTables = dataSet.Tables; + + // 处理 8 个结果集 + if (returnTypes.Length >= 8) + { + return new List + { + dataTables[0].ToList(returnTypes[0]), + dataTables[1].ToList(returnTypes[1]), + dataTables[2].ToList(returnTypes[2]), + dataTables[3].ToList(returnTypes[3]), + dataTables[4].ToList(returnTypes[4]), + dataTables[5].ToList(returnTypes[5]), + dataTables[6].ToList(returnTypes[6]), + dataTables[7].ToList(returnTypes[7]) + }; + } + // 处理 7 个结果集 + else if (returnTypes.Length == 7) + { + return new List + { + dataTables[0].ToList(returnTypes[0]), + dataTables[1].ToList(returnTypes[1]), + dataTables[2].ToList(returnTypes[2]), + dataTables[3].ToList(returnTypes[3]), + dataTables[4].ToList(returnTypes[4]), + dataTables[5].ToList(returnTypes[5]), + dataTables[6].ToList(returnTypes[6]) + }; + } + // 处理 6 个结果集 + else if (returnTypes.Length == 6) + { + return new List + { + dataTables[0].ToList(returnTypes[0]), + dataTables[1].ToList(returnTypes[1]), + dataTables[2].ToList(returnTypes[2]), + dataTables[3].ToList(returnTypes[3]), + dataTables[4].ToList(returnTypes[4]), + dataTables[5].ToList(returnTypes[5]) + }; + } + // 处理 5 个结果集 + else if (returnTypes.Length == 5) + { + return new List + { + dataTables[0].ToList(returnTypes[0]), + dataTables[1].ToList(returnTypes[1]), + dataTables[2].ToList(returnTypes[2]), + dataTables[3].ToList(returnTypes[3]), + dataTables[4].ToList(returnTypes[4]) + }; + } + // 处理 4 个结果集 + else if (returnTypes.Length == 4) + { + return new List + { + dataTables[0].ToList(returnTypes[0]), + dataTables[1].ToList(returnTypes[1]), + dataTables[2].ToList(returnTypes[2]), + dataTables[3].ToList(returnTypes[3]) + }; + } + // 处理 3 个结果集 + else if (returnTypes.Length == 3) + { + return new List + { + dataTables[0].ToList(returnTypes[0]), + dataTables[1].ToList(returnTypes[1]), + dataTables[2].ToList(returnTypes[2]) + }; + } + // 处理 2 个结果集 + else if (returnTypes.Length == 2) + { + return new List + { + dataTables[0].ToList(returnTypes[0]), + dataTables[1].ToList(returnTypes[1]) + }; + } + // 处理 1 个结果集 + else + { + return new List + { + dataTables[0].ToList(returnTypes[0]) + }; + } + } + + /// + /// 将 DataSet 转 特定类型 + /// + /// DataSet + /// 特定类型集合 + /// object + public static Task> ToListAsync(this DataSet dataSet, params Type[] returnTypes) + { + return Task.FromResult(dataSet.ToList(returnTypes)); + } + + /// + /// 将 DataTable 转 特定类型 + /// + /// DataTable + /// 返回值类型 + /// object + public static object ToList(this DataTable dataTable, Type returnType) + { + var isGenericType = returnType.IsGenericType; + // 获取类型真实返回类型 + var underlyingType = isGenericType ? returnType.GenericTypeArguments.First() : returnType; + + var resultType = typeof(List<>).MakeGenericType(underlyingType); + var list = Activator.CreateInstance(resultType); + var addMethod = resultType.GetMethod("Add"); + + // 将 DataTable 转为行集合 + var dataRows = dataTable.AsEnumerable(); + + // 如果是基元类型 + if (underlyingType.IsRichPrimitive()) + { + // 遍历所有行 + foreach (var dataRow in dataRows) + { + // 只取第一列数据 + var firstColumnValue = dataRow[0]; + // 转换成目标类型数据 + var destValue = firstColumnValue?.ChangeType(underlyingType); + // 添加到集合中 + _ = addMethod.Invoke(list, new[] { destValue }); + } + } + // 处理Object类型 + else if (underlyingType == typeof(object)) + { + // 获取所有列名 + var columns = dataTable.Columns; + + // 遍历所有行 + foreach (var dataRow in dataRows) + { + var dic = new Dictionary(); + foreach (DataColumn column in columns) + { + dic.Add(column.ColumnName, dataRow[column]); + } + _ = addMethod.Invoke(list, new[] { dic }); + } + } + else + { + // 获取所有的数据列和类公开实例属性 + var dataColumns = dataTable.Columns; + var properties = underlyingType.GetProperties(BindingFlags.Public | BindingFlags.Instance); + //.Where(p => !p.IsDefined(typeof(NotMappedAttribute), true)); // sql 数据转换无需判断 [NotMapperd] 特性 + + // 遍历所有行 + foreach (var dataRow in dataRows) + { + var model = Activator.CreateInstance(underlyingType); + + // 遍历所有属性并一一赋值 + foreach (var property in properties) + { + // 获取属性对应的真实列名 + var columnName = property.Name; + if (property.IsDefined(typeof(ColumnAttribute), true)) + { + var columnAttribute = property.GetCustomAttribute(true); + if (!string.IsNullOrWhiteSpace(columnAttribute.Name)) columnName = columnAttribute.Name; + } + + // 如果 DataTable 不包含该列名,则跳过 + if (!dataColumns.Contains(columnName)) continue; + + // 获取列值 + var columnValue = dataRow[columnName]; + // 如果列值未空,则跳过 + if (columnValue == DBNull.Value) continue; + + // 转换成目标类型数据 + var destValue = columnValue?.ChangeType(property.PropertyType); + property.SetValue(model, destValue); + } + + // 添加到集合中 + _ = addMethod.Invoke(list, new[] { model }); + } + } + + return list; + } + + /// + /// 将 DataTable 转 特定类型 + /// + /// DataTable + /// 返回值类型 + /// object + public static Task ToListAsync(this DataTable dataTable, Type returnType) + { + return Task.FromResult(dataTable.ToList(returnType)); + } + + /// + /// 处理元组类型返回值 + /// + /// 数据集 + /// 返回值类型 + /// + internal static object ToValueTuple(this DataSet dataSet, Type tupleType) + { + // 获取元组最底层类型 + var underlyingTypes = tupleType.GetGenericArguments().Select(u => u.IsGenericType ? u.GetGenericArguments().First() : u); + + var toListMethod = typeof(DbDataConvertExtensions) + .GetMethods(BindingFlags.Public | BindingFlags.Static) + .First(u => u.Name == "ToList" && u.IsGenericMethod && u.GetGenericArguments().Length == tupleType.GetGenericArguments().Length) + .MakeGenericMethod(underlyingTypes.ToArray()); + + return toListMethod.Invoke(null, new[] { dataSet }); + } + } +} \ No newline at end of file diff --git a/Infrastructure/Define.cs b/Infrastructure/Define.cs new file mode 100644 index 0000000..b947574 --- /dev/null +++ b/Infrastructure/Define.cs @@ -0,0 +1,38 @@ +namespace Infrastructure +{ + public static class Define + { + public static string USERROLE = "UserRole"; //用户角色关联KEY + public const string ROLERESOURCE = "RoleResource"; //角色资源关联KEY + public const string USERORG = "UserOrg"; //用户机构关联KEY + public const string ROLEELEMENT = "RoleElement"; //角色菜单关联KEY + public const string ROLEMODULE = "RoleModule"; //角色模块关联KEY + public const string ROLEDATAPROPERTY = "RoleDataProperty"; //角色数据字段权限 + + + public const string DBTYPE_SQLSERVER = "SqlServer"; //sql server + public const string DBTYPE_MYSQL = "MySql"; //mysql + public const string DBTYPE_PostgreSQL = "PostgreSQL"; //PostgreSQL + public const string DBTYPE_ORACLE = "Oracle"; //oracle + + + public const int INVALID_TOKEN = 50014; //token无效 + + public const string TOKEN_NAME = "X-Token"; + public const string TENANT_ID = "tenantId"; + + + public const string SYSTEM_USERNAME = "System"; + public const string SYSTEM_USERPWD = "acdcd3db09e0dc32c222c1840144e31d"; + //public const string SYSTEM_USERPWD = "6ff33dd3478bae96663aced32f5262fa"; + public const string SYSTEM_SECRETKEY = "b6467189772775db"; + + public const string DATAPRIVILEGE_LOGINUSER = "{loginUser}"; //数据权限配置中,当前登录用户的key + public const string DATAPRIVILEGE_LOGINROLE = "{loginRole}"; //数据权限配置中,当前登录用户角色的key + public const string DATAPRIVILEGE_LOGINORG = "{loginOrg}"; //数据权限配置中,当前登录用户部门的key + + public const string JOBMAPKEY = "OpenJob"; + + public const string DEFAULT_FORM_INSTANCE_ID_NAME = "InstanceId"; + } +} diff --git a/Infrastructure/DynamicLinq.cs b/Infrastructure/DynamicLinq.cs new file mode 100644 index 0000000..d20a1f8 --- /dev/null +++ b/Infrastructure/DynamicLinq.cs @@ -0,0 +1,306 @@ +// *********************************************************************** +// Assembly : FairUtility +// Author : Yubao Li +// Created : 08-18-2015 +// +// Last Modified By : Yubao Li +// Last Modified On : 08-18-2015 +// *********************************************************************** +// +// Copyright (c) . All rights reserved. +// +// 动态linq +// *********************************************************************** + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace Infrastructure +{ + public static class DynamicLinq + { + public static ParameterExpression CreateLambdaParam(string name) + { + return Expression.Parameter(typeof(T), name); + } + + /// + /// 创建linq表达示的body部分 + /// + public static Expression GenerateBody(this ParameterExpression param, Filter filterObj) + { + PropertyInfo property = typeof(T).GetProperty(filterObj.Key); + + Expression left = null; //组装左边 + //组装右边 + Expression right = null; + + if (property != null) + { + left = Expression.Property(param, property); + if (property.PropertyType == typeof(int)) + { + right = Expression.Constant(int.Parse(filterObj.Value)); + } + else if (property.PropertyType == typeof(DateTime)) + { + right = Expression.Constant(DateTime.Parse(filterObj.Value)); + } + else if (property.PropertyType == typeof(string)) + { + right = Expression.Constant(filterObj.Value); + } + else if (property.PropertyType == typeof(decimal)) + { + right = Expression.Constant(decimal.Parse(filterObj.Value)); + } + else if (property.PropertyType == typeof(Guid)) + { + right = Expression.Constant(Guid.Parse(filterObj.Value)); + } + else if (property.PropertyType == typeof(bool)) + { + right = Expression.Constant(filterObj.Value.Equals("1")); + } + else if (property.PropertyType == typeof(Guid?)) + { + left = Expression.Property(left, "Value"); + right = Expression.Constant(Guid.Parse(filterObj.Value)); + } + else + { + throw new Exception("暂不能解析该Key的类型"); + } + } + else //如果左边不是属性,直接是值的情况 + { + left = Expression.Constant(filterObj.Key); + right = Expression.Constant(filterObj.Value); + } + + //c.XXX=="XXX" + Expression filter = Expression.Equal(left, right); + switch (filterObj.Contrast) + { + case "<=": + filter = Expression.LessThanOrEqual(left, right); + break; + + case "<": + filter = Expression.LessThan(left, right); + break; + + case ">": + filter = Expression.GreaterThan(left, right); + break; + + case ">=": + filter = Expression.GreaterThanOrEqual(left, right); + break; + case "!=": + filter = Expression.NotEqual(left, right); + break; + case "contains": + filter = Expression.Call(left, typeof(string).GetMethod("Contains", new Type[] {typeof(string)}), + Expression.Constant(filterObj.Value)); + break; + case "in": + var lExp = Expression.Constant(filterObj.Value.Split(',').ToList()); //数组 + var methodInfo = typeof(List).GetMethod("Contains", + new Type[] {typeof(string)}); //Contains语句 + filter = Expression.Call(lExp, methodInfo, left); + break; + case "not in": + var listExpression = Expression.Constant(filterObj.Value.Split(',').ToList()); //数组 + var method = typeof(List).GetMethod("Contains", new Type[] {typeof(string)}); //Contains语句 + filter = Expression.Not(Expression.Call(listExpression, method, left)); + break; + //交集,使用交集时左值必须时固定的值 + case "intersect": //交集 + if (property != null) + { + throw new Exception("交集模式下,表达式左边不能为变量,请调整数据规则,如:c=>\"A,B,C\" intersect \"B,D\""); + } + + var rightval = filterObj.Value.Split(',').ToList(); + var leftval = filterObj.Key.Split(',').ToList(); + var val = rightval.Intersect(leftval); + + filter = Expression.Constant(val.Count() > 0); + break; + } + + return filter; + } + + public static Expression> GenerateTypeBody(this ParameterExpression param, Filter filterObj) + { + return (Expression>) (param.GenerateBody(filterObj)); + } + + /// + /// 创建完整的lambda + /// + public static LambdaExpression GenerateLambda(this ParameterExpression param, Expression body) + { + //c=>c.XXX=="XXX" + return Expression.Lambda(body, param); + } + + public static Expression> GenerateTypeLambda(this ParameterExpression param, Expression body) + { + return (Expression>) (param.GenerateLambda(body)); + } + + public static Expression AndAlso(this Expression expression, Expression expressionRight) + { + return Expression.AndAlso(expression, expressionRight); + } + + public static Expression Or(this Expression expression, Expression expressionRight) + { + return Expression.Or(expression, expressionRight); + } + + public static Expression And(this Expression expression, Expression expressionRight) + { + return Expression.And(expression, expressionRight); + } + + public static IQueryable GenerateFilter(this IQueryable query, string parametername, string filterjson) + { + if (!string.IsNullOrEmpty(filterjson)) + { + var filterGroup = JsonHelper.Instance.Deserialize(filterjson); + query = GenerateFilter(query, parametername, filterGroup); + } + + return query; + } + + /// + /// 转换FilterGroup为Lambda表达式 + /// + /// + /// + /// + /// + /// + public static IQueryable GenerateFilter(this IQueryable query, string parametername, + FilterGroup filterGroup) + { + var param = CreateLambdaParam(parametername); + Expression result = ConvertGroup(filterGroup, param); + query = query.Where(param.GenerateTypeLambda(result)); + return query; + } + + /// + /// 转换filtergroup为表达式 + /// + /// + /// + /// + /// + public static Expression ConvertGroup(FilterGroup filterGroup, ParameterExpression param) + { + if (filterGroup == null) return null; + + if (filterGroup.Filters.Length == 1 &&(filterGroup.Children == null || !filterGroup.Children.Any())) //只有一个条件 + { + return param.GenerateBody(filterGroup.Filters[0]); + } + + Expression result = ConvertFilters(filterGroup.Filters, param, filterGroup.Operation); + Expression gresult = ConvertGroup(filterGroup.Children, param, filterGroup.Operation); + if (gresult == null) return result; + if (result == null) return gresult; + + if (filterGroup.Operation == "and") + { + return result.AndAlso(gresult); + } + else //or + { + return result.Or(gresult); + } + } + + /// + /// 转换FilterGroup[]为表达式,不管FilterGroup里面的Filters + /// + /// + /// + /// + /// + /// + private static Expression ConvertGroup(FilterGroup[] groups, ParameterExpression param, string operation) + { + if (groups == null || !groups.Any()) return null; + + Expression result = ConvertGroup(groups[0], param); + + if (groups.Length == 1) return result; + + if (operation == "and") + { + foreach (var filter in groups.Skip(1)) + { + result = result.AndAlso(ConvertGroup(filter, param)); + } + } + else + { + foreach (var filter in groups.Skip(1)) + { + result = result.Or(ConvertGroup(filter, param)); + } + } + + return result; + } + + /// + /// 转换Filter数组为表达式 + /// + /// + /// + /// + /// + /// + private static Expression ConvertFilters(Filter[] filters, ParameterExpression param, string operation) + { + if (filters == null || !filters.Any()) + { + return null; + } + + Expression result = param.GenerateBody(filters[0]); + + if (filters.Length == 1) + { + return result; + } + + if (operation == "and") + { + foreach (var filter in filters.Skip(1)) + { + result = result.AndAlso(param.GenerateBody(filter)); + } + } + else + { + foreach (var filter in filters.Skip(1)) + { + result = result.Or(param.GenerateBody(filter)); + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/Infrastructure/DynamicQueryable.cs b/Infrastructure/DynamicQueryable.cs new file mode 100644 index 0000000..9fb59a9 --- /dev/null +++ b/Infrastructure/DynamicQueryable.cs @@ -0,0 +1,2079 @@ +//Copyright (C) Microsoft Corporation. All rights reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading; + +namespace Infrastructure +{ + public static class DynamicQueryable + { + public static IQueryable Where(this IQueryable source, string predicate, params object[] values) { + return (IQueryable)Where((IQueryable)source, predicate, values); + } + + public static IQueryable Where(this IQueryable source, string predicate, params object[] values) { + if (source == null) throw new ArgumentNullException("source"); + if (predicate == null) throw new ArgumentNullException("predicate"); + LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values); + return source.Provider.CreateQuery( + Expression.Call( + typeof(Queryable), "Where", + new Type[] { source.ElementType }, + source.Expression, Expression.Quote(lambda))); + } + + public static IQueryable Select(this IQueryable source, string selector, params object[] values) { + if (source == null) throw new ArgumentNullException("source"); + if (selector == null) throw new ArgumentNullException("selector"); + LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, null, selector, values); + return source.Provider.CreateQuery( + Expression.Call( + typeof(Queryable), "Select", + new Type[] { source.ElementType, lambda.Body.Type }, + source.Expression, Expression.Quote(lambda))); + } + + public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values) { + return (IQueryable)OrderBy((IQueryable)source, ordering, values); + } + + public static IQueryable ThenBy(this IQueryable source, string ordering, params object[] values) + { + return (IQueryable)ThenBy((IQueryable)source, ordering, values); + } + + public static IQueryable ThenBy(this IQueryable source, string ordering, params object[] values) + { + if (source == null) throw new ArgumentNullException("source"); + if (ordering == null) throw new ArgumentNullException("ordering"); + ParameterExpression[] parameters = new ParameterExpression[] { + Expression.Parameter(source.ElementType, "") }; + ExpressionParser parser = new ExpressionParser(parameters, ordering, values); + IEnumerable orderings = parser.ParseOrdering(); + Expression queryExpr = source.Expression; + string methodAsc = "ThenBy"; + string methodDesc = "ThenByDescending"; + foreach (DynamicOrdering o in orderings) + { + queryExpr = Expression.Call( + typeof(Queryable), o.Ascending ? methodAsc : methodDesc, + new Type[] { source.ElementType, o.Selector.Type }, + queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters))); + + } + return source.Provider.CreateQuery(queryExpr); + } + + public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values) { + if (source == null) throw new ArgumentNullException("source"); + if (ordering == null) throw new ArgumentNullException("ordering"); + ParameterExpression[] parameters = new ParameterExpression[] { + Expression.Parameter(source.ElementType, "") }; + ExpressionParser parser = new ExpressionParser(parameters, ordering, values); + IEnumerable orderings = parser.ParseOrdering(); + Expression queryExpr = source.Expression; + string methodAsc = "OrderBy"; + string methodDesc = "OrderByDescending"; + foreach (DynamicOrdering o in orderings) { + queryExpr = Expression.Call( + typeof(Queryable), o.Ascending ? methodAsc : methodDesc, + new Type[] { source.ElementType, o.Selector.Type }, + queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters))); + methodAsc = "ThenBy"; + methodDesc = "ThenByDescending"; + } + return source.Provider.CreateQuery(queryExpr); + } + + public static IQueryable OrderBy(this IQueryable source, string propertyName, bool ascending) + where T : class + { + Type type = typeof (T); + + PropertyInfo property = type.GetProperty(propertyName); + if (property == null) + throw new ArgumentException("propertyName", "Not Exist"); + + ParameterExpression param = Expression.Parameter(type, "p"); + Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property); + LambdaExpression orderByExpression = Expression.Lambda(propertyAccessExpression, param); + + string methodName = ascending ? "OrderBy" : "OrderByDescending"; + + MethodCallExpression resultExp = Expression.Call(typeof (Queryable), methodName, + new Type[] {type, property.PropertyType}, source.Expression, Expression.Quote(orderByExpression)); + + return source.Provider.CreateQuery(resultExp); + } + + public static IQueryable Take(this IQueryable source, int count) { + if (source == null) throw new ArgumentNullException("source"); + return source.Provider.CreateQuery( + Expression.Call( + typeof(Queryable), "Take", + new Type[] { source.ElementType }, + source.Expression, Expression.Constant(count))); + } + + public static IQueryable Skip(this IQueryable source, int count) { + if (source == null) throw new ArgumentNullException("source"); + return source.Provider.CreateQuery( + Expression.Call( + typeof(Queryable), "Skip", + new Type[] { source.ElementType }, + source.Expression, Expression.Constant(count))); + } + + public static IQueryable GroupBy(this IQueryable source, string keySelector, string elementSelector, params object[] values) { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + if (elementSelector == null) throw new ArgumentNullException("elementSelector"); + LambdaExpression keyLambda = DynamicExpression.ParseLambda(source.ElementType, null, keySelector, values); + LambdaExpression elementLambda = DynamicExpression.ParseLambda(source.ElementType, null, elementSelector, values); + return source.Provider.CreateQuery( + Expression.Call( + typeof(Queryable), "GroupBy", + new Type[] { source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type }, + source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda))); + } + + public static bool Any(this IQueryable source) { + if (source == null) throw new ArgumentNullException("source"); + return (bool)source.Provider.Execute( + Expression.Call( + typeof(Queryable), "Any", + new Type[] { source.ElementType }, source.Expression)); + } + + public static int Count(this IQueryable source) { + if (source == null) throw new ArgumentNullException("source"); + return (int)source.Provider.Execute( + Expression.Call( + typeof(Queryable), "Count", + new Type[] { source.ElementType }, source.Expression)); + } + } + + public abstract class DynamicClass + { + public override string ToString() { + PropertyInfo[] props = this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); + StringBuilder sb = new StringBuilder(); + sb.Append("{"); + for (int i = 0; i < props.Length; i++) { + if (i > 0) sb.Append(", "); + sb.Append(props[i].Name); + sb.Append("="); + sb.Append(props[i].GetValue(this, null)); + } + sb.Append("}"); + return sb.ToString(); + } + } + + public class DynamicProperty + { + string name; + Type type; + + public DynamicProperty(string name, Type type) { + if (name == null) throw new ArgumentNullException("name"); + if (type == null) throw new ArgumentNullException("type"); + this.name = name; + this.type = type; + } + + public string Name { + get { return name; } + } + + public Type Type { + get { return type; } + } + } + + public static class DynamicExpression + { + public static Expression Parse(Type resultType, string expression, params object[] values) { + ExpressionParser parser = new ExpressionParser(null, expression, values); + return parser.Parse(resultType); + } + + public static LambdaExpression ParseLambda(Type itType, Type resultType, string expression, params object[] values) { + return ParseLambda(new ParameterExpression[] { Expression.Parameter(itType, "") }, resultType, expression, values); + } + + public static LambdaExpression ParseLambda(ParameterExpression[] parameters, Type resultType, string expression, params object[] values) { + ExpressionParser parser = new ExpressionParser(parameters, expression, values); + return Expression.Lambda(parser.Parse(resultType), parameters); + } + + public static Expression> ParseLambda(string expression, params object[] values) { + return (Expression>)ParseLambda(typeof(T), typeof(S), expression, values); + } + + public static Type CreateClass(params DynamicProperty[] properties) { + return ClassFactory.Instance.GetDynamicClass(properties); + } + + public static Type CreateClass(IEnumerable properties) { + return ClassFactory.Instance.GetDynamicClass(properties); + } + } + + internal class DynamicOrdering + { + public Expression Selector; + public bool Ascending; + } + + internal class Signature : IEquatable + { + public DynamicProperty[] properties; + public int hashCode; + + public Signature(IEnumerable properties) { + this.properties = properties.ToArray(); + hashCode = 0; + foreach (DynamicProperty p in properties) { + hashCode ^= p.Name.GetHashCode() ^ p.Type.GetHashCode(); + } + } + + public override int GetHashCode() { + return hashCode; + } + + public override bool Equals(object obj) { + return obj is Signature ? Equals((Signature)obj) : false; + } + + public bool Equals(Signature other) { + if (properties.Length != other.properties.Length) return false; + for (int i = 0; i < properties.Length; i++) { + if (properties[i].Name != other.properties[i].Name || + properties[i].Type != other.properties[i].Type) return false; + } + return true; + } + } + + internal class ClassFactory + { + public static readonly ClassFactory Instance = new ClassFactory(); + + static ClassFactory() { } // Trigger lazy initialization of static fields + + ModuleBuilder module; + Dictionary classes; + int classCount; + ReaderWriterLock rwLock; + + private ClassFactory() { + AssemblyName name = new AssemblyName("DynamicClasses"); + AssemblyBuilder assembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); + // AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); +#if ENABLE_LINQ_PARTIAL_TRUST + new ReflectionPermission(PermissionState.Unrestricted).Assert(); +#endif + try { + module = assembly.DefineDynamicModule("Module"); + } + finally { +#if ENABLE_LINQ_PARTIAL_TRUST + PermissionSet.RevertAssert(); +#endif + } + classes = new Dictionary(); + rwLock = new ReaderWriterLock(); + } + + public Type GetDynamicClass(IEnumerable properties) { + rwLock.AcquireReaderLock(Timeout.Infinite); + try { + Signature signature = new Signature(properties); + Type type; + if (!classes.TryGetValue(signature, out type)) { + type = CreateDynamicClass(signature.properties); + //fixed by https://gitee.com/DUWENINK + if (!classes.ContainsKey(signature)){ + classes.Add(signature, type); + } + } + return type; + } + finally { + rwLock.ReleaseReaderLock(); + } + } + + Type CreateDynamicClass(DynamicProperty[] properties) { + LockCookie cookie = rwLock.UpgradeToWriterLock(Timeout.Infinite); + try { + string typeName = "DynamicClass" + (classCount + 1); +#if ENABLE_LINQ_PARTIAL_TRUST + new ReflectionPermission(PermissionState.Unrestricted).Assert(); +#endif + try { + TypeBuilder tb = this.module.DefineType(typeName, TypeAttributes.Class | + TypeAttributes.Public, typeof(DynamicClass)); + FieldInfo[] fields = GenerateProperties(tb, properties); + GenerateEquals(tb, fields); + GenerateGetHashCode(tb, fields); + Type result = tb.CreateType(); + classCount++; + return result; + } + finally { +#if ENABLE_LINQ_PARTIAL_TRUST + PermissionSet.RevertAssert(); +#endif + } + } + finally { + rwLock.DowngradeFromWriterLock(ref cookie); + } + } + + FieldInfo[] GenerateProperties(TypeBuilder tb, DynamicProperty[] properties) { + FieldInfo[] fields = new FieldBuilder[properties.Length]; + for (int i = 0; i < properties.Length; i++) { + DynamicProperty dp = properties[i]; + FieldBuilder fb = tb.DefineField("_" + dp.Name, dp.Type, FieldAttributes.Private); + PropertyBuilder pb = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, null); + MethodBuilder mbGet = tb.DefineMethod("get_" + dp.Name, + MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, + dp.Type, Type.EmptyTypes); + ILGenerator genGet = mbGet.GetILGenerator(); + genGet.Emit(OpCodes.Ldarg_0); + genGet.Emit(OpCodes.Ldfld, fb); + genGet.Emit(OpCodes.Ret); + MethodBuilder mbSet = tb.DefineMethod("set_" + dp.Name, + MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, + null, new Type[] { dp.Type }); + ILGenerator genSet = mbSet.GetILGenerator(); + genSet.Emit(OpCodes.Ldarg_0); + genSet.Emit(OpCodes.Ldarg_1); + genSet.Emit(OpCodes.Stfld, fb); + genSet.Emit(OpCodes.Ret); + pb.SetGetMethod(mbGet); + pb.SetSetMethod(mbSet); + fields[i] = fb; + } + return fields; + } + + void GenerateEquals(TypeBuilder tb, FieldInfo[] fields) { + MethodBuilder mb = tb.DefineMethod("Equals", + MethodAttributes.Public | MethodAttributes.ReuseSlot | + MethodAttributes.Virtual | MethodAttributes.HideBySig, + typeof(bool), new Type[] { typeof(object) }); + ILGenerator gen = mb.GetILGenerator(); + LocalBuilder other = gen.DeclareLocal(tb); + Label next = gen.DefineLabel(); + gen.Emit(OpCodes.Ldarg_1); + gen.Emit(OpCodes.Isinst, tb); + gen.Emit(OpCodes.Stloc, other); + gen.Emit(OpCodes.Ldloc, other); + gen.Emit(OpCodes.Brtrue_S, next); + gen.Emit(OpCodes.Ldc_I4_0); + gen.Emit(OpCodes.Ret); + gen.MarkLabel(next); + foreach (FieldInfo field in fields) { + Type ft = field.FieldType; + Type ct = typeof(EqualityComparer<>).MakeGenericType(ft); + next = gen.DefineLabel(); + gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null); + gen.Emit(OpCodes.Ldarg_0); + gen.Emit(OpCodes.Ldfld, field); + gen.Emit(OpCodes.Ldloc, other); + gen.Emit(OpCodes.Ldfld, field); + gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", new Type[] { ft, ft }), null); + gen.Emit(OpCodes.Brtrue_S, next); + gen.Emit(OpCodes.Ldc_I4_0); + gen.Emit(OpCodes.Ret); + gen.MarkLabel(next); + } + gen.Emit(OpCodes.Ldc_I4_1); + gen.Emit(OpCodes.Ret); + } + + void GenerateGetHashCode(TypeBuilder tb, FieldInfo[] fields) { + MethodBuilder mb = tb.DefineMethod("GetHashCode", + MethodAttributes.Public | MethodAttributes.ReuseSlot | + MethodAttributes.Virtual | MethodAttributes.HideBySig, + typeof(int), Type.EmptyTypes); + ILGenerator gen = mb.GetILGenerator(); + gen.Emit(OpCodes.Ldc_I4_0); + foreach (FieldInfo field in fields) { + Type ft = field.FieldType; + Type ct = typeof(EqualityComparer<>).MakeGenericType(ft); + gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null); + gen.Emit(OpCodes.Ldarg_0); + gen.Emit(OpCodes.Ldfld, field); + gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", new Type[] { ft }), null); + gen.Emit(OpCodes.Xor); + } + gen.Emit(OpCodes.Ret); + } + } + + public sealed class ParseException : Exception + { + int position; + + public ParseException(string message, int position) + : base(message) { + this.position = position; + } + + public int Position { + get { return position; } + } + + public override string ToString() { + return string.Format(Res.ParseExceptionFormat, Message, position); + } + } + + internal class ExpressionParser + { + struct Token + { + public TokenId id; + public string text; + public int pos; + } + + enum TokenId + { + Unknown, + End, + Identifier, + StringLiteral, + IntegerLiteral, + RealLiteral, + Exclamation, + Percent, + Amphersand, + OpenParen, + CloseParen, + Asterisk, + Plus, + Comma, + Minus, + Dot, + Slash, + Colon, + LessThan, + Equal, + GreaterThan, + Question, + OpenBracket, + CloseBracket, + Bar, + ExclamationEqual, + DoubleAmphersand, + LessThanEqual, + LessGreater, + DoubleEqual, + GreaterThanEqual, + DoubleBar + } + + interface ILogicalSignatures + { + void F(bool x, bool y); + void F(bool? x, bool? y); + } + + interface IArithmeticSignatures + { + void F(int x, int y); + void F(uint x, uint y); + void F(long x, long y); + void F(ulong x, ulong y); + void F(float x, float y); + void F(double x, double y); + void F(decimal x, decimal y); + void F(int? x, int? y); + void F(uint? x, uint? y); + void F(long? x, long? y); + void F(ulong? x, ulong? y); + void F(float? x, float? y); + void F(double? x, double? y); + void F(decimal? x, decimal? y); + } + + interface IRelationalSignatures : IArithmeticSignatures + { + void F(string x, string y); + void F(char x, char y); + void F(DateTime x, DateTime y); + void F(TimeSpan x, TimeSpan y); + void F(char? x, char? y); + void F(DateTime? x, DateTime? y); + void F(TimeSpan? x, TimeSpan? y); + } + + interface IEqualitySignatures : IRelationalSignatures + { + void F(bool x, bool y); + void F(bool? x, bool? y); + } + + interface IAddSignatures : IArithmeticSignatures + { + void F(DateTime x, TimeSpan y); + void F(TimeSpan x, TimeSpan y); + void F(DateTime? x, TimeSpan? y); + void F(TimeSpan? x, TimeSpan? y); + } + + interface ISubtractSignatures : IAddSignatures + { + void F(DateTime x, DateTime y); + void F(DateTime? x, DateTime? y); + } + + interface INegationSignatures + { + void F(int x); + void F(long x); + void F(float x); + void F(double x); + void F(decimal x); + void F(int? x); + void F(long? x); + void F(float? x); + void F(double? x); + void F(decimal? x); + } + + interface INotSignatures + { + void F(bool x); + void F(bool? x); + } + + interface IEnumerableSignatures + { + void Where(bool predicate); + void Any(); + void Any(bool predicate); + void All(bool predicate); + void Count(); + void Count(bool predicate); + void Min(object selector); + void Max(object selector); + void Sum(int selector); + void Sum(int? selector); + void Sum(long selector); + void Sum(long? selector); + void Sum(float selector); + void Sum(float? selector); + void Sum(double selector); + void Sum(double? selector); + void Sum(decimal selector); + void Sum(decimal? selector); + void Average(int selector); + void Average(int? selector); + void Average(long selector); + void Average(long? selector); + void Average(float selector); + void Average(float? selector); + void Average(double selector); + void Average(double? selector); + void Average(decimal selector); + void Average(decimal? selector); + } + + static readonly Type[] predefinedTypes = { + typeof(Object), + typeof(Boolean), + typeof(Char), + typeof(String), + typeof(SByte), + typeof(Byte), + typeof(Int16), + typeof(UInt16), + typeof(Int32), + typeof(UInt32), + typeof(Int64), + typeof(UInt64), + typeof(Single), + typeof(Double), + typeof(Decimal), + typeof(DateTime), + typeof(TimeSpan), + typeof(Guid), + typeof(Math), + typeof(Convert) + }; + + static readonly Expression trueLiteral = Expression.Constant(true); + static readonly Expression falseLiteral = Expression.Constant(false); + static readonly Expression nullLiteral = Expression.Constant(null); + + static readonly string keywordIt = "it"; + static readonly string keywordIif = "iif"; + static readonly string keywordNew = "new"; + + static Dictionary keywords; + + Dictionary symbols; + IDictionary externals; + Dictionary literals; + ParameterExpression it; + string text; + int textPos; + int textLen; + char ch; + Token token; + + public ExpressionParser(ParameterExpression[] parameters, string expression, object[] values) { + if (expression == null) throw new ArgumentNullException("expression"); + if (keywords == null) keywords = CreateKeywords(); + symbols = new Dictionary(StringComparer.OrdinalIgnoreCase); + literals = new Dictionary(); + if (parameters != null) ProcessParameters(parameters); + if (values != null) ProcessValues(values); + text = expression; + textLen = text.Length; + SetTextPos(0); + NextToken(); + } + + void ProcessParameters(ParameterExpression[] parameters) { + foreach (ParameterExpression pe in parameters) + if (!String.IsNullOrEmpty(pe.Name)) + AddSymbol(pe.Name, pe); + if (parameters.Length == 1 && String.IsNullOrEmpty(parameters[0].Name)) + it = parameters[0]; + } + + void ProcessValues(object[] values) { + for (int i = 0; i < values.Length; i++) { + object value = values[i]; + if (i == values.Length - 1 && value is IDictionary) { + externals = (IDictionary)value; + } + else { + AddSymbol("@" + i.ToString(System.Globalization.CultureInfo.InvariantCulture), value); + } + } + } + + void AddSymbol(string name, object value) { + if (symbols.ContainsKey(name)) + throw ParseError(Res.DuplicateIdentifier, name); + symbols.Add(name, value); + } + + public Expression Parse(Type resultType) { + int exprPos = token.pos; + Expression expr = ParseExpression(); + if (resultType != null) + if ((expr = PromoteExpression(expr, resultType, true)) == null) + throw ParseError(exprPos, Res.ExpressionTypeMismatch, GetTypeName(resultType)); + ValidateToken(TokenId.End, Res.SyntaxError); + return expr; + } + +#pragma warning disable 0219 + public IEnumerable ParseOrdering() { + List orderings = new List(); + while (true) { + Expression expr = ParseExpression(); + bool ascending = true; + if (TokenIdentifierIs("asc") || TokenIdentifierIs("ascending")) { + NextToken(); + } + else if (TokenIdentifierIs("desc") || TokenIdentifierIs("descending")) { + NextToken(); + ascending = false; + } + orderings.Add(new DynamicOrdering { Selector = expr, Ascending = ascending }); + if (token.id != TokenId.Comma) break; + NextToken(); + } + ValidateToken(TokenId.End, Res.SyntaxError); + return orderings; + } +#pragma warning restore 0219 + + // ?: operator + Expression ParseExpression() { + int errorPos = token.pos; + Expression expr = ParseLogicalOr(); + if (token.id == TokenId.Question) { + NextToken(); + Expression expr1 = ParseExpression(); + ValidateToken(TokenId.Colon, Res.ColonExpected); + NextToken(); + Expression expr2 = ParseExpression(); + expr = GenerateConditional(expr, expr1, expr2, errorPos); + } + return expr; + } + + // ||, or operator + Expression ParseLogicalOr() { + Expression left = ParseLogicalAnd(); + while (token.id == TokenId.DoubleBar || TokenIdentifierIs("or")) { + Token op = token; + NextToken(); + Expression right = ParseLogicalAnd(); + CheckAndPromoteOperands(typeof(ILogicalSignatures), op.text, ref left, ref right, op.pos); + left = Expression.OrElse(left, right); + } + return left; + } + + // &&, and operator + Expression ParseLogicalAnd() { + Expression left = ParseComparison(); + while (token.id == TokenId.DoubleAmphersand || TokenIdentifierIs("and")) { + Token op = token; + NextToken(); + Expression right = ParseComparison(); + CheckAndPromoteOperands(typeof(ILogicalSignatures), op.text, ref left, ref right, op.pos); + left = Expression.AndAlso(left, right); + } + return left; + } + + // =, ==, !=, <>, >, >=, <, <= operators + Expression ParseComparison() { + Expression left = ParseAdditive(); + while (token.id == TokenId.Equal || token.id == TokenId.DoubleEqual || + token.id == TokenId.ExclamationEqual || token.id == TokenId.LessGreater || + token.id == TokenId.GreaterThan || token.id == TokenId.GreaterThanEqual || + token.id == TokenId.LessThan || token.id == TokenId.LessThanEqual) { + Token op = token; + NextToken(); + Expression right = ParseAdditive(); + bool isEquality = op.id == TokenId.Equal || op.id == TokenId.DoubleEqual || + op.id == TokenId.ExclamationEqual || op.id == TokenId.LessGreater; + if (isEquality && !left.Type.IsValueType && !right.Type.IsValueType) { + if (left.Type != right.Type) { + if (left.Type.IsAssignableFrom(right.Type)) { + right = Expression.Convert(right, left.Type); + } + else if (right.Type.IsAssignableFrom(left.Type)) { + left = Expression.Convert(left, right.Type); + } + else { + throw IncompatibleOperandsError(op.text, left, right, op.pos); + } + } + } + else if (IsEnumType(left.Type) || IsEnumType(right.Type)) { + if (left.Type != right.Type) { + Expression e; + if ((e = PromoteExpression(right, left.Type, true)) != null) { + right = e; + } + else if ((e = PromoteExpression(left, right.Type, true)) != null) { + left = e; + } + else { + throw IncompatibleOperandsError(op.text, left, right, op.pos); + } + } + } + else { + CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures), + op.text, ref left, ref right, op.pos); + } + switch (op.id) { + case TokenId.Equal: + case TokenId.DoubleEqual: + left = GenerateEqual(left, right); + break; + case TokenId.ExclamationEqual: + case TokenId.LessGreater: + left = GenerateNotEqual(left, right); + break; + case TokenId.GreaterThan: + left = GenerateGreaterThan(left, right); + break; + case TokenId.GreaterThanEqual: + left = GenerateGreaterThanEqual(left, right); + break; + case TokenId.LessThan: + left = GenerateLessThan(left, right); + break; + case TokenId.LessThanEqual: + left = GenerateLessThanEqual(left, right); + break; + } + } + return left; + } + + // +, -, & operators + Expression ParseAdditive() { + Expression left = ParseMultiplicative(); + while (token.id == TokenId.Plus || token.id == TokenId.Minus || + token.id == TokenId.Amphersand) { + Token op = token; + NextToken(); + Expression right = ParseMultiplicative(); + switch (op.id) { + case TokenId.Plus: + if (left.Type == typeof(string) || right.Type == typeof(string)) + goto case TokenId.Amphersand; + CheckAndPromoteOperands(typeof(IAddSignatures), op.text, ref left, ref right, op.pos); + left = GenerateAdd(left, right); + break; + case TokenId.Minus: + CheckAndPromoteOperands(typeof(ISubtractSignatures), op.text, ref left, ref right, op.pos); + left = GenerateSubtract(left, right); + break; + case TokenId.Amphersand: + left = GenerateStringConcat(left, right); + break; + } + } + return left; + } + + // *, /, %, mod operators + Expression ParseMultiplicative() { + Expression left = ParseUnary(); + while (token.id == TokenId.Asterisk || token.id == TokenId.Slash || + token.id == TokenId.Percent || TokenIdentifierIs("mod")) { + Token op = token; + NextToken(); + Expression right = ParseUnary(); + CheckAndPromoteOperands(typeof(IArithmeticSignatures), op.text, ref left, ref right, op.pos); + switch (op.id) { + case TokenId.Asterisk: + left = Expression.Multiply(left, right); + break; + case TokenId.Slash: + left = Expression.Divide(left, right); + break; + case TokenId.Percent: + case TokenId.Identifier: + left = Expression.Modulo(left, right); + break; + } + } + return left; + } + + // -, !, not unary operators + Expression ParseUnary() { + if (token.id == TokenId.Minus || token.id == TokenId.Exclamation || + TokenIdentifierIs("not")) { + Token op = token; + NextToken(); + if (op.id == TokenId.Minus && (token.id == TokenId.IntegerLiteral || + token.id == TokenId.RealLiteral)) { + token.text = "-" + token.text; + token.pos = op.pos; + return ParsePrimary(); + } + Expression expr = ParseUnary(); + if (op.id == TokenId.Minus) { + CheckAndPromoteOperand(typeof(INegationSignatures), op.text, ref expr, op.pos); + expr = Expression.Negate(expr); + } + else { + CheckAndPromoteOperand(typeof(INotSignatures), op.text, ref expr, op.pos); + expr = Expression.Not(expr); + } + return expr; + } + return ParsePrimary(); + } + + Expression ParsePrimary() { + Expression expr = ParsePrimaryStart(); + while (true) { + if (token.id == TokenId.Dot) { + NextToken(); + expr = ParseMemberAccess(null, expr); + } + else if (token.id == TokenId.OpenBracket) { + expr = ParseElementAccess(expr); + } + else { + break; + } + } + return expr; + } + + Expression ParsePrimaryStart() { + switch (token.id) { + case TokenId.Identifier: + return ParseIdentifier(); + case TokenId.StringLiteral: + return ParseStringLiteral(); + case TokenId.IntegerLiteral: + return ParseIntegerLiteral(); + case TokenId.RealLiteral: + return ParseRealLiteral(); + case TokenId.OpenParen: + return ParseParenExpression(); + default: + throw ParseError(Res.ExpressionExpected); + } + } + + Expression ParseStringLiteral() { + ValidateToken(TokenId.StringLiteral); + char quote = token.text[0]; + string s = token.text.Substring(1, token.text.Length - 2); + int start = 0; + while (true) { + int i = s.IndexOf(quote, start); + if (i < 0) break; + s = s.Remove(i, 1); + start = i + 1; + } + //if (quote == '\'') { + // if (s.Length != 1) + // throw ParseError(Res.InvalidCharacterLiteral); + // NextToken(); + // return CreateLiteral(s[0], s); + //} + NextToken(); + return CreateLiteral(s, s); + } + + Expression ParseIntegerLiteral() { + ValidateToken(TokenId.IntegerLiteral); + string text = token.text; + if (text[0] != '-') { + ulong value; + if (!UInt64.TryParse(text, out value)) + throw ParseError(Res.InvalidIntegerLiteral, text); + NextToken(); + if (value <= (ulong)Int32.MaxValue) return CreateLiteral((int)value, text); + if (value <= (ulong)UInt32.MaxValue) return CreateLiteral((uint)value, text); + if (value <= (ulong)Int64.MaxValue) return CreateLiteral((long)value, text); + return CreateLiteral(value, text); + } + else { + long value; + if (!Int64.TryParse(text, out value)) + throw ParseError(Res.InvalidIntegerLiteral, text); + NextToken(); + if (value >= Int32.MinValue && value <= Int32.MaxValue) + return CreateLiteral((int)value, text); + return CreateLiteral(value, text); + } + } + + Expression ParseRealLiteral() { + ValidateToken(TokenId.RealLiteral); + string text = token.text; + object value = null; + char last = text[text.Length - 1]; + if (last == 'F' || last == 'f') { + float f; + if (Single.TryParse(text.Substring(0, text.Length - 1), out f)) value = f; + } + else { + double d; + if (Double.TryParse(text, out d)) value = d; + } + if (value == null) throw ParseError(Res.InvalidRealLiteral, text); + NextToken(); + return CreateLiteral(value, text); + } + + Expression CreateLiteral(object value, string text) { + ConstantExpression expr = Expression.Constant(value); + literals.Add(expr, text); + return expr; + } + + Expression ParseParenExpression() { + ValidateToken(TokenId.OpenParen, Res.OpenParenExpected); + NextToken(); + Expression e = ParseExpression(); + ValidateToken(TokenId.CloseParen, Res.CloseParenOrOperatorExpected); + NextToken(); + return e; + } + + Expression ParseIdentifier() { + ValidateToken(TokenId.Identifier); + object value; + if (keywords.TryGetValue(token.text, out value)) { + if (value is Type) return ParseTypeAccess((Type)value); + if (value == (object)keywordIt) return ParseIt(); + if (value == (object)keywordIif) return ParseIif(); + if (value == (object)keywordNew) return ParseNew(); + NextToken(); + return (Expression)value; + } + if (symbols.TryGetValue(token.text, out value) || + externals != null && externals.TryGetValue(token.text, out value)) { + Expression expr = value as Expression; + if (expr == null) { + expr = Expression.Constant(value); + } + else { + LambdaExpression lambda = expr as LambdaExpression; + if (lambda != null) return ParseLambdaInvocation(lambda); + } + NextToken(); + return expr; + } + if (it != null) return ParseMemberAccess(null, it); + throw ParseError(Res.UnknownIdentifier, token.text); + } + + Expression ParseIt() { + if (it == null) + throw ParseError(Res.NoItInScope); + NextToken(); + return it; + } + + Expression ParseIif() { + int errorPos = token.pos; + NextToken(); + Expression[] args = ParseArgumentList(); + if (args.Length != 3) + throw ParseError(errorPos, Res.IifRequiresThreeArgs); + return GenerateConditional(args[0], args[1], args[2], errorPos); + } + + Expression GenerateConditional(Expression test, Expression expr1, Expression expr2, int errorPos) { + if (test.Type != typeof(bool)) + throw ParseError(errorPos, Res.FirstExprMustBeBool); + if (expr1.Type != expr2.Type) { + Expression expr1as2 = expr2 != nullLiteral ? PromoteExpression(expr1, expr2.Type, true) : null; + Expression expr2as1 = expr1 != nullLiteral ? PromoteExpression(expr2, expr1.Type, true) : null; + if (expr1as2 != null && expr2as1 == null) { + expr1 = expr1as2; + } + else if (expr2as1 != null && expr1as2 == null) { + expr2 = expr2as1; + } + else { + string type1 = expr1 != nullLiteral ? expr1.Type.Name : "null"; + string type2 = expr2 != nullLiteral ? expr2.Type.Name : "null"; + if (expr1as2 != null && expr2as1 != null) + throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2); + throw ParseError(errorPos, Res.NeitherTypeConvertsToOther, type1, type2); + } + } + return Expression.Condition(test, expr1, expr2); + } + + Expression ParseNew() { + NextToken(); + ValidateToken(TokenId.OpenParen, Res.OpenParenExpected); + NextToken(); + List properties = new List(); + List expressions = new List(); + while (true) { + int exprPos = token.pos; + Expression expr = ParseExpression(); + string propName; + if (TokenIdentifierIs("as")) { + NextToken(); + propName = GetIdentifier(); + NextToken(); + } + else { + MemberExpression me = expr as MemberExpression; + if (me == null) throw ParseError(exprPos, Res.MissingAsClause); + propName = me.Member.Name; + } + expressions.Add(expr); + properties.Add(new DynamicProperty(propName, expr.Type)); + if (token.id != TokenId.Comma) break; + NextToken(); + } + ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected); + NextToken(); + Type type = DynamicExpression.CreateClass(properties); + MemberBinding[] bindings = new MemberBinding[properties.Count]; + for (int i = 0; i < bindings.Length; i++) + bindings[i] = Expression.Bind(type.GetProperty(properties[i].Name), expressions[i]); + return Expression.MemberInit(Expression.New(type), bindings); + } + + Expression ParseLambdaInvocation(LambdaExpression lambda) { + int errorPos = token.pos; + NextToken(); + Expression[] args = ParseArgumentList(); + MethodBase method; + if (FindMethod(lambda.Type, "Invoke", false, args, out method) != 1) + throw ParseError(errorPos, Res.ArgsIncompatibleWithLambda); + return Expression.Invoke(lambda, args); + } + + Expression ParseTypeAccess(Type type) { + int errorPos = token.pos; + NextToken(); + if (token.id == TokenId.Question) { + if (!type.IsValueType || IsNullableType(type)) + throw ParseError(errorPos, Res.TypeHasNoNullableForm, GetTypeName(type)); + type = typeof(Nullable<>).MakeGenericType(type); + NextToken(); + } + if (token.id == TokenId.OpenParen) { + Expression[] args = ParseArgumentList(); + MethodBase method; + switch (FindBestMethod(type.GetConstructors(), args, out method)) { + case 0: + if (args.Length == 1) + return GenerateConversion(args[0], type, errorPos); + throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type)); + case 1: + return Expression.New((ConstructorInfo)method, args); + default: + throw ParseError(errorPos, Res.AmbiguousConstructorInvocation, GetTypeName(type)); + } + } + ValidateToken(TokenId.Dot, Res.DotOrOpenParenExpected); + NextToken(); + return ParseMemberAccess(type, null); + } + + Expression GenerateConversion(Expression expr, Type type, int errorPos) { + Type exprType = expr.Type; + if (exprType == type) return expr; + if (exprType.IsValueType && type.IsValueType) { + if ((IsNullableType(exprType) || IsNullableType(type)) && + GetNonNullableType(exprType) == GetNonNullableType(type)) + return Expression.Convert(expr, type); + if ((IsNumericType(exprType) || IsEnumType(exprType)) && + (IsNumericType(type)) || IsEnumType(type)) + return Expression.ConvertChecked(expr, type); + } + if (exprType.IsAssignableFrom(type) || type.IsAssignableFrom(exprType) || + exprType.IsInterface || type.IsInterface) + return Expression.Convert(expr, type); + throw ParseError(errorPos, Res.CannotConvertValue, + GetTypeName(exprType), GetTypeName(type)); + } + + Expression ParseMemberAccess(Type type, Expression instance) { + if (instance != null) type = instance.Type; + int errorPos = token.pos; + string id = GetIdentifier(); + NextToken(); + if (token.id == TokenId.OpenParen) { + if (instance != null && type != typeof(string)) { + Type enumerableType = FindGenericType(typeof(IEnumerable<>), type); + if (enumerableType != null) { + Type elementType = enumerableType.GetGenericArguments()[0]; + return ParseAggregate(instance, elementType, id, errorPos); + } + } + Expression[] args = ParseArgumentList(); + MethodBase mb; + switch (FindMethod(type, id, instance == null, args, out mb)) { + case 0: + throw ParseError(errorPos, Res.NoApplicableMethod, + id, GetTypeName(type)); + case 1: + MethodInfo method = (MethodInfo)mb; + if (!IsPredefinedType(method.DeclaringType)) + throw ParseError(errorPos, Res.MethodsAreInaccessible, GetTypeName(method.DeclaringType)); + if (method.ReturnType == typeof(void)) + throw ParseError(errorPos, Res.MethodIsVoid, + id, GetTypeName(method.DeclaringType)); + return Expression.Call(instance, (MethodInfo)method, args); + default: + throw ParseError(errorPos, Res.AmbiguousMethodInvocation, + id, GetTypeName(type)); + } + } + else { + MemberInfo member = FindPropertyOrField(type, id, instance == null); + if (member == null) + throw ParseError(errorPos, Res.UnknownPropertyOrField, + id, GetTypeName(type)); + return member is PropertyInfo ? + Expression.Property(instance, (PropertyInfo)member) : + Expression.Field(instance, (FieldInfo)member); + } + } + + static Type FindGenericType(Type generic, Type type) { + while (type != null && type != typeof(object)) { + if (type.IsGenericType && type.GetGenericTypeDefinition() == generic) return type; + if (generic.IsInterface) { + foreach (Type intfType in type.GetInterfaces()) { + Type found = FindGenericType(generic, intfType); + if (found != null) return found; + } + } + type = type.BaseType; + } + return null; + } + + Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos) { + ParameterExpression outerIt = it; + ParameterExpression innerIt = Expression.Parameter(elementType, ""); + it = innerIt; + Expression[] args = ParseArgumentList(); + it = outerIt; + MethodBase signature; + if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out signature) != 1) + throw ParseError(errorPos, Res.NoApplicableAggregate, methodName); + Type[] typeArgs; + if (signature.Name == "Min" || signature.Name == "Max") { + typeArgs = new Type[] { elementType, args[0].Type }; + } + else { + typeArgs = new Type[] { elementType }; + } + if (args.Length == 0) { + args = new Expression[] { instance }; + } + else { + args = new Expression[] { instance, Expression.Lambda(args[0], innerIt) }; + } + return Expression.Call(typeof(Enumerable), signature.Name, typeArgs, args); + } + + Expression[] ParseArgumentList() { + ValidateToken(TokenId.OpenParen, Res.OpenParenExpected); + NextToken(); + Expression[] args = token.id != TokenId.CloseParen ? ParseArguments() : new Expression[0]; + ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected); + NextToken(); + return args; + } + + Expression[] ParseArguments() { + List argList = new List(); + while (true) { + argList.Add(ParseExpression()); + if (token.id != TokenId.Comma) break; + NextToken(); + } + return argList.ToArray(); + } + + Expression ParseElementAccess(Expression expr) { + int errorPos = token.pos; + ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected); + NextToken(); + Expression[] args = ParseArguments(); + ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected); + NextToken(); + if (expr.Type.IsArray) { + if (expr.Type.GetArrayRank() != 1 || args.Length != 1) + throw ParseError(errorPos, Res.CannotIndexMultiDimArray); + Expression index = PromoteExpression(args[0], typeof(int), true); + if (index == null) + throw ParseError(errorPos, Res.InvalidIndex); + return Expression.ArrayIndex(expr, index); + } + else { + MethodBase mb; + switch (FindIndexer(expr.Type, args, out mb)) { + case 0: + throw ParseError(errorPos, Res.NoApplicableIndexer, + GetTypeName(expr.Type)); + case 1: + return Expression.Call(expr, (MethodInfo)mb, args); + default: + throw ParseError(errorPos, Res.AmbiguousIndexerInvocation, + GetTypeName(expr.Type)); + } + } + } + + static bool IsPredefinedType(Type type) { + foreach (Type t in predefinedTypes) if (t == type) return true; + return false; + } + + static bool IsNullableType(Type type) { + return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + static Type GetNonNullableType(Type type) { + return IsNullableType(type) ? type.GetGenericArguments()[0] : type; + } + + static string GetTypeName(Type type) { + Type baseType = GetNonNullableType(type); + string s = baseType.Name; + if (type != baseType) s += '?'; + return s; + } + + static bool IsNumericType(Type type) { + return GetNumericTypeKind(type) != 0; + } + + static bool IsSignedIntegralType(Type type) { + return GetNumericTypeKind(type) == 2; + } + + static bool IsUnsignedIntegralType(Type type) { + return GetNumericTypeKind(type) == 3; + } + + static int GetNumericTypeKind(Type type) { + type = GetNonNullableType(type); + if (type.IsEnum) return 0; + switch (Type.GetTypeCode(type)) { + case TypeCode.Char: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return 1; + case TypeCode.SByte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + return 2; + case TypeCode.Byte: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + return 3; + default: + return 0; + } + } + + static bool IsEnumType(Type type) { + return GetNonNullableType(type).IsEnum; + } + + void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr, int errorPos) { + Expression[] args = new Expression[] { expr }; + MethodBase method; + if (FindMethod(signatures, "F", false, args, out method) != 1) + throw ParseError(errorPos, Res.IncompatibleOperand, + opName, GetTypeName(args[0].Type)); + expr = args[0]; + } + + void CheckAndPromoteOperands(Type signatures, string opName, ref Expression left, ref Expression right, int errorPos) { + Expression[] args = new Expression[] { left, right }; + MethodBase method; + if (FindMethod(signatures, "F", false, args, out method) != 1) + throw IncompatibleOperandsError(opName, left, right, errorPos); + left = args[0]; + right = args[1]; + } + + Exception IncompatibleOperandsError(string opName, Expression left, Expression right, int pos) { + return ParseError(pos, Res.IncompatibleOperands, + opName, GetTypeName(left.Type), GetTypeName(right.Type)); + } + + MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess) { + BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly | + (staticAccess ? BindingFlags.Static : BindingFlags.Instance); + foreach (Type t in SelfAndBaseTypes(type)) { + MemberInfo[] members = t.FindMembers(MemberTypes.Property | MemberTypes.Field, + flags, Type.FilterNameIgnoreCase, memberName); + if (members.Length != 0) return members[0]; + } + return null; + } + + int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method) { + BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly | + (staticAccess ? BindingFlags.Static : BindingFlags.Instance); + foreach (Type t in SelfAndBaseTypes(type)) { + MemberInfo[] members = t.FindMembers(MemberTypes.Method, + flags, Type.FilterNameIgnoreCase, methodName); + int count = FindBestMethod(members.Cast(), args, out method); + if (count != 0) return count; + } + method = null; + return 0; + } + + int FindIndexer(Type type, Expression[] args, out MethodBase method) { + foreach (Type t in SelfAndBaseTypes(type)) { + MemberInfo[] members = t.GetDefaultMembers(); + if (members.Length != 0) { + IEnumerable methods = members. + OfType(). + Select(p => (MethodBase)p.GetGetMethod()). + Where(m => m != null); + int count = FindBestMethod(methods, args, out method); + if (count != 0) return count; + } + } + method = null; + return 0; + } + + static IEnumerable SelfAndBaseTypes(Type type) { + if (type.IsInterface) { + List types = new List(); + AddInterface(types, type); + return types; + } + return SelfAndBaseClasses(type); + } + + static IEnumerable SelfAndBaseClasses(Type type) { + while (type != null) { + yield return type; + type = type.BaseType; + } + } + + static void AddInterface(List types, Type type) { + if (!types.Contains(type)) { + types.Add(type); + foreach (Type t in type.GetInterfaces()) AddInterface(types, t); + } + } + + class MethodData + { + public MethodBase MethodBase; + public ParameterInfo[] Parameters; + public Expression[] Args; + } + + int FindBestMethod(IEnumerable methods, Expression[] args, out MethodBase method) { + MethodData[] applicable = methods. + Select(m => new MethodData { MethodBase = m, Parameters = m.GetParameters() }). + Where(m => IsApplicable(m, args)). + ToArray(); + if (applicable.Length > 1) { + applicable = applicable. + Where(m => applicable.All(n => m == n || IsBetterThan(args, m, n))). + ToArray(); + } + if (applicable.Length == 1) { + MethodData md = applicable[0]; + for (int i = 0; i < args.Length; i++) args[i] = md.Args[i]; + method = md.MethodBase; + } + else { + method = null; + } + return applicable.Length; + } + + bool IsApplicable(MethodData method, Expression[] args) { + if (method.Parameters.Length != args.Length) return false; + Expression[] promotedArgs = new Expression[args.Length]; + for (int i = 0; i < args.Length; i++) { + ParameterInfo pi = method.Parameters[i]; + if (pi.IsOut) return false; + Expression promoted = PromoteExpression(args[i], pi.ParameterType, false); + if (promoted == null) return false; + promotedArgs[i] = promoted; + } + method.Args = promotedArgs; + return true; + } + + Expression PromoteExpression(Expression expr, Type type, bool exact) { + if (expr.Type == type) return expr; + if (expr is ConstantExpression) { + ConstantExpression ce = (ConstantExpression)expr; + if (ce == nullLiteral) { + if (!type.IsValueType || IsNullableType(type)) + return Expression.Constant(null, type); + } + else { + string text; + if (literals.TryGetValue(ce, out text)) { + Type target = GetNonNullableType(type); + Object value = null; + switch (Type.GetTypeCode(ce.Type)) { + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + value = ParseNumber(text, target); + break; + case TypeCode.Double: + if (target == typeof(decimal)) value = ParseNumber(text, target); + break; + case TypeCode.String: + value = ParseEnum(text, target); + break; + } + if (value != null) + return Expression.Constant(value, type); + } + } + } + if (IsCompatibleWith(expr.Type, type)) { + if (type.IsValueType || exact) return Expression.Convert(expr, type); + return expr; + } + return null; + } + + static object ParseNumber(string text, Type type) { + switch (Type.GetTypeCode(GetNonNullableType(type))) { + case TypeCode.SByte: + sbyte sb; + if (sbyte.TryParse(text, out sb)) return sb; + break; + case TypeCode.Byte: + byte b; + if (byte.TryParse(text, out b)) return b; + break; + case TypeCode.Int16: + short s; + if (short.TryParse(text, out s)) return s; + break; + case TypeCode.UInt16: + ushort us; + if (ushort.TryParse(text, out us)) return us; + break; + case TypeCode.Int32: + int i; + if (int.TryParse(text, out i)) return i; + break; + case TypeCode.UInt32: + uint ui; + if (uint.TryParse(text, out ui)) return ui; + break; + case TypeCode.Int64: + long l; + if (long.TryParse(text, out l)) return l; + break; + case TypeCode.UInt64: + ulong ul; + if (ulong.TryParse(text, out ul)) return ul; + break; + case TypeCode.Single: + float f; + if (float.TryParse(text, out f)) return f; + break; + case TypeCode.Double: + double d; + if (double.TryParse(text, out d)) return d; + break; + case TypeCode.Decimal: + decimal e; + if (decimal.TryParse(text, out e)) return e; + break; + } + return null; + } + + static object ParseEnum(string name, Type type) { + if (type.IsEnum) { + MemberInfo[] memberInfos = type.FindMembers(MemberTypes.Field, + BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static, + Type.FilterNameIgnoreCase, name); + if (memberInfos.Length != 0) return ((FieldInfo)memberInfos[0]).GetValue(null); + } + return null; + } + + static bool IsCompatibleWith(Type source, Type target) { + if (source == target) return true; + if (!target.IsValueType) return target.IsAssignableFrom(source); + Type st = GetNonNullableType(source); + Type tt = GetNonNullableType(target); + if (st != source && tt == target) return false; + TypeCode sc = st.IsEnum ? TypeCode.Object : Type.GetTypeCode(st); + TypeCode tc = tt.IsEnum ? TypeCode.Object : Type.GetTypeCode(tt); + switch (sc) { + case TypeCode.SByte: + switch (tc) { + case TypeCode.SByte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return true; + } + break; + case TypeCode.Byte: + switch (tc) { + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.UInt16: + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return true; + } + break; + case TypeCode.Int16: + switch (tc) { + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return true; + } + break; + case TypeCode.UInt16: + switch (tc) { + case TypeCode.UInt16: + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return true; + } + break; + case TypeCode.Int32: + switch (tc) { + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return true; + } + break; + case TypeCode.UInt32: + switch (tc) { + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return true; + } + break; + case TypeCode.Int64: + switch (tc) { + case TypeCode.Int64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return true; + } + break; + case TypeCode.UInt64: + switch (tc) { + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + return true; + } + break; + case TypeCode.Single: + switch (tc) { + case TypeCode.Single: + case TypeCode.Double: + return true; + } + break; + default: + if (st == tt) return true; + break; + } + return false; + } + + static bool IsBetterThan(Expression[] args, MethodData m1, MethodData m2) { + bool better = false; + for (int i = 0; i < args.Length; i++) { + int c = CompareConversions(args[i].Type, + m1.Parameters[i].ParameterType, + m2.Parameters[i].ParameterType); + if (c < 0) return false; + if (c > 0) better = true; + } + return better; + } + + // Return 1 if s -> t1 is a better conversion than s -> t2 + // Return -1 if s -> t2 is a better conversion than s -> t1 + // Return 0 if neither conversion is better + static int CompareConversions(Type s, Type t1, Type t2) { + if (t1 == t2) return 0; + if (s == t1) return 1; + if (s == t2) return -1; + bool t1t2 = IsCompatibleWith(t1, t2); + bool t2t1 = IsCompatibleWith(t2, t1); + if (t1t2 && !t2t1) return 1; + if (t2t1 && !t1t2) return -1; + if (IsSignedIntegralType(t1) && IsUnsignedIntegralType(t2)) return 1; + if (IsSignedIntegralType(t2) && IsUnsignedIntegralType(t1)) return -1; + return 0; + } + + Expression GenerateEqual(Expression left, Expression right) { + return Expression.Equal(left, right); + } + + Expression GenerateNotEqual(Expression left, Expression right) { + return Expression.NotEqual(left, right); + } + + Expression GenerateGreaterThan(Expression left, Expression right) { + if (left.Type == typeof(string)) { + return Expression.GreaterThan( + GenerateStaticMethodCall("Compare", left, right), + Expression.Constant(0) + ); + } + return Expression.GreaterThan(left, right); + } + + Expression GenerateGreaterThanEqual(Expression left, Expression right) { + if (left.Type == typeof(string)) { + return Expression.GreaterThanOrEqual( + GenerateStaticMethodCall("Compare", left, right), + Expression.Constant(0) + ); + } + return Expression.GreaterThanOrEqual(left, right); + } + + Expression GenerateLessThan(Expression left, Expression right) { + if (left.Type == typeof(string)) { + return Expression.LessThan( + GenerateStaticMethodCall("Compare", left, right), + Expression.Constant(0) + ); + } + return Expression.LessThan(left, right); + } + + Expression GenerateLessThanEqual(Expression left, Expression right) { + if (left.Type == typeof(string)) { + return Expression.LessThanOrEqual( + GenerateStaticMethodCall("Compare", left, right), + Expression.Constant(0) + ); + } + return Expression.LessThanOrEqual(left, right); + } + + Expression GenerateAdd(Expression left, Expression right) { + if (left.Type == typeof(string) && right.Type == typeof(string)) { + return GenerateStaticMethodCall("Concat", left, right); + } + return Expression.Add(left, right); + } + + Expression GenerateSubtract(Expression left, Expression right) { + return Expression.Subtract(left, right); + } + + Expression GenerateStringConcat(Expression left, Expression right) { + return Expression.Call( + null, + typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }), + new[] { left, right }); + } + + MethodInfo GetStaticMethod(string methodName, Expression left, Expression right) { + return left.Type.GetMethod(methodName, new[] { left.Type, right.Type }); + } + + Expression GenerateStaticMethodCall(string methodName, Expression left, Expression right) { + return Expression.Call(null, GetStaticMethod(methodName, left, right), new[] { left, right }); + } + + void SetTextPos(int pos) { + textPos = pos; + ch = textPos < textLen ? text[textPos] : '\0'; + } + + void NextChar() { + if (textPos < textLen) textPos++; + ch = textPos < textLen ? text[textPos] : '\0'; + } + + void NextToken() { + while (Char.IsWhiteSpace(ch)) NextChar(); + TokenId t; + int tokenPos = textPos; + switch (ch) { + case '!': + NextChar(); + if (ch == '=') { + NextChar(); + t = TokenId.ExclamationEqual; + } + else { + t = TokenId.Exclamation; + } + break; + case '%': + NextChar(); + t = TokenId.Percent; + break; + case '&': + NextChar(); + if (ch == '&') { + NextChar(); + t = TokenId.DoubleAmphersand; + } + else { + t = TokenId.Amphersand; + } + break; + case '(': + NextChar(); + t = TokenId.OpenParen; + break; + case ')': + NextChar(); + t = TokenId.CloseParen; + break; + case '*': + NextChar(); + t = TokenId.Asterisk; + break; + case '+': + NextChar(); + t = TokenId.Plus; + break; + case ',': + NextChar(); + t = TokenId.Comma; + break; + case '-': + NextChar(); + t = TokenId.Minus; + break; + case '.': + NextChar(); + t = TokenId.Dot; + break; + case '/': + NextChar(); + t = TokenId.Slash; + break; + case ':': + NextChar(); + t = TokenId.Colon; + break; + case '<': + NextChar(); + if (ch == '=') { + NextChar(); + t = TokenId.LessThanEqual; + } + else if (ch == '>') { + NextChar(); + t = TokenId.LessGreater; + } + else { + t = TokenId.LessThan; + } + break; + case '=': + NextChar(); + if (ch == '=') { + NextChar(); + t = TokenId.DoubleEqual; + } + else { + t = TokenId.Equal; + } + break; + case '>': + NextChar(); + if (ch == '=') { + NextChar(); + t = TokenId.GreaterThanEqual; + } + else { + t = TokenId.GreaterThan; + } + break; + case '?': + NextChar(); + t = TokenId.Question; + break; + case '[': + NextChar(); + t = TokenId.OpenBracket; + break; + case ']': + NextChar(); + t = TokenId.CloseBracket; + break; + case '|': + NextChar(); + if (ch == '|') { + NextChar(); + t = TokenId.DoubleBar; + } + else { + t = TokenId.Bar; + } + break; + case '"': + case '\'': + char quote = ch; + do { + NextChar(); + while (textPos < textLen && ch != quote) NextChar(); + if (textPos == textLen) + throw ParseError(textPos, Res.UnterminatedStringLiteral); + NextChar(); + } while (ch == quote); + t = TokenId.StringLiteral; + break; + default: + if (Char.IsLetter(ch) || ch == '@' || ch == '_') { + do { + NextChar(); + } while (Char.IsLetterOrDigit(ch) || ch == '_'); + t = TokenId.Identifier; + break; + } + if (Char.IsDigit(ch)) { + t = TokenId.IntegerLiteral; + do { + NextChar(); + } while (Char.IsDigit(ch)); + if (ch == '.') { + t = TokenId.RealLiteral; + NextChar(); + ValidateDigit(); + do { + NextChar(); + } while (Char.IsDigit(ch)); + } + if (ch == 'E' || ch == 'e') { + t = TokenId.RealLiteral; + NextChar(); + if (ch == '+' || ch == '-') NextChar(); + ValidateDigit(); + do { + NextChar(); + } while (Char.IsDigit(ch)); + } + if (ch == 'F' || ch == 'f') NextChar(); + break; + } + if (textPos == textLen) { + t = TokenId.End; + break; + } + throw ParseError(textPos, Res.InvalidCharacter, ch); + } + token.id = t; + token.text = text.Substring(tokenPos, textPos - tokenPos); + token.pos = tokenPos; + } + + bool TokenIdentifierIs(string id) { + return token.id == TokenId.Identifier && String.Equals(id, token.text, StringComparison.OrdinalIgnoreCase); + } + + string GetIdentifier() { + ValidateToken(TokenId.Identifier, Res.IdentifierExpected); + string id = token.text; + if (id.Length > 1 && id[0] == '@') id = id.Substring(1); + return id; + } + + void ValidateDigit() { + if (!Char.IsDigit(ch)) throw ParseError(textPos, Res.DigitExpected); + } + + void ValidateToken(TokenId t, string errorMessage) { + if (token.id != t) throw ParseError(errorMessage); + } + + void ValidateToken(TokenId t) { + if (token.id != t) throw ParseError(Res.SyntaxError); + } + + Exception ParseError(string format, params object[] args) { + return ParseError(token.pos, format, args); + } + + Exception ParseError(int pos, string format, params object[] args) { + return new ParseException(string.Format(System.Globalization.CultureInfo.CurrentCulture, format, args), pos); + } + + static Dictionary CreateKeywords() { + Dictionary d = new Dictionary(StringComparer.OrdinalIgnoreCase); + d.Add("true", trueLiteral); + d.Add("false", falseLiteral); + d.Add("null", nullLiteral); + d.Add(keywordIt, keywordIt); + d.Add(keywordIif, keywordIif); + d.Add(keywordNew, keywordNew); + foreach (Type type in predefinedTypes) d.Add(type.Name, type); + return d; + } + } + + static class Res + { + public const string DuplicateIdentifier = "The identifier '{0}' was defined more than once"; + public const string ExpressionTypeMismatch = "Expression of type '{0}' expected"; + public const string ExpressionExpected = "Expression expected"; + public const string InvalidCharacterLiteral = "Character literal must contain exactly one character"; + public const string InvalidIntegerLiteral = "Invalid integer literal '{0}'"; + public const string InvalidRealLiteral = "Invalid real literal '{0}'"; + public const string UnknownIdentifier = "Unknown identifier '{0}'"; + public const string NoItInScope = "No 'it' is in scope"; + public const string IifRequiresThreeArgs = "The 'iif' function requires three arguments"; + public const string FirstExprMustBeBool = "The first expression must be of type 'Boolean'"; + public const string BothTypesConvertToOther = "Both of the types '{0}' and '{1}' convert to the other"; + public const string NeitherTypeConvertsToOther = "Neither of the types '{0}' and '{1}' converts to the other"; + public const string MissingAsClause = "Expression is missing an 'as' clause"; + public const string ArgsIncompatibleWithLambda = "Argument list incompatible with lambda expression"; + public const string TypeHasNoNullableForm = "Type '{0}' has no nullable form"; + public const string NoMatchingConstructor = "No matching constructor in type '{0}'"; + public const string AmbiguousConstructorInvocation = "Ambiguous invocation of '{0}' constructor"; + public const string CannotConvertValue = "A value of type '{0}' cannot be converted to type '{1}'"; + public const string NoApplicableMethod = "No applicable method '{0}' exists in type '{1}'"; + public const string MethodsAreInaccessible = "Methods on type '{0}' are not accessible"; + public const string MethodIsVoid = "Method '{0}' in type '{1}' does not return a value"; + public const string AmbiguousMethodInvocation = "Ambiguous invocation of method '{0}' in type '{1}'"; + public const string UnknownPropertyOrField = "No property or field '{0}' exists in type '{1}'"; + public const string NoApplicableAggregate = "No applicable aggregate method '{0}' exists"; + public const string CannotIndexMultiDimArray = "Indexing of multi-dimensional arrays is not supported"; + public const string InvalidIndex = "Array index must be an integer expression"; + public const string NoApplicableIndexer = "No applicable indexer exists in type '{0}'"; + public const string AmbiguousIndexerInvocation = "Ambiguous invocation of indexer in type '{0}'"; + public const string IncompatibleOperand = "Operator '{0}' incompatible with operand type '{1}'"; + public const string IncompatibleOperands = "Operator '{0}' incompatible with operand types '{1}' and '{2}'"; + public const string UnterminatedStringLiteral = "Unterminated string literal"; + public const string InvalidCharacter = "Syntax error '{0}'"; + public const string DigitExpected = "Digit expected"; + public const string SyntaxError = "Syntax error"; + public const string TokenExpected = "{0} expected"; + public const string ParseExceptionFormat = "{0} (at index {1})"; + public const string ColonExpected = "':' expected"; + public const string OpenParenExpected = "'(' expected"; + public const string CloseParenOrOperatorExpected = "')' or operator expected"; + public const string CloseParenOrCommaExpected = "')' or ',' expected"; + public const string DotOrOpenParenExpected = "'.' or '(' expected"; + public const string OpenBracketExpected = "'[' expected"; + public const string CloseBracketOrCommaExpected = "']' or ',' expected"; + public const string IdentifierExpected = "Identifier expected"; + } +} diff --git a/Infrastructure/Encryption.cs b/Infrastructure/Encryption.cs new file mode 100644 index 0000000..20f4483 --- /dev/null +++ b/Infrastructure/Encryption.cs @@ -0,0 +1,59 @@ +using System; +using System.Security.Cryptography; +using System.Text; + +namespace Infrastructure +{ + public class Encryption + { + private static string encryptKey = "4h!@w$rng,i#$@x1%)5^3(7*5P31/Ee0"; + + //默认密钥向量 + private static byte[] Keys = { 0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6D, 0x79, 0x53, 0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F }; + /// + /// 加密 + /// + /// + /// + public static string Encrypt(string encryptString) + { + if (string.IsNullOrEmpty(encryptString)) + return string.Empty; + RijndaelManaged rijndaelProvider = new RijndaelManaged(); + rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 32)); + rijndaelProvider.IV = Keys; + ICryptoTransform rijndaelEncrypt = rijndaelProvider.CreateEncryptor(); + + byte[] inputData = Encoding.UTF8.GetBytes(encryptString); + byte[] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, 0, inputData.Length); + + return Convert.ToBase64String(encryptedData); + } + /// + /// 解密 + /// + /// + /// + public static string Decrypt(string decryptString) + { + if (string.IsNullOrEmpty(decryptString)) + return string.Empty; + try + { + RijndaelManaged rijndaelProvider = new RijndaelManaged(); + rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 32)); + rijndaelProvider.IV = Keys; + ICryptoTransform rijndaelDecrypt = rijndaelProvider.CreateDecryptor(); + + byte[] inputData = Convert.FromBase64String(decryptString); + byte[] decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length); + + return Encoding.UTF8.GetString(decryptedData); + } + catch + { + return ""; + } + } + } +} diff --git a/Infrastructure/Extensions/AutofacManager/AutofacContainerModule.cs b/Infrastructure/Extensions/AutofacManager/AutofacContainerModule.cs new file mode 100644 index 0000000..8585aaa --- /dev/null +++ b/Infrastructure/Extensions/AutofacManager/AutofacContainerModule.cs @@ -0,0 +1,22 @@ +using System; + +namespace Infrastructure.Extensions.AutofacManager +{ + /// + /// 提供全局静态获取服务的能力。 + /// 例:AutofacContainerModule.GetService<IPathProvider>() + /// + public class AutofacContainerModule + { + static private IServiceProvider _provider; + public static void ConfigServiceProvider(IServiceProvider serviceProvider) + { + _provider = serviceProvider; + } + public static TService GetService() where TService:class + { + Type typeParameterType = typeof(TService); + return (TService)_provider.GetService(typeParameterType); + } + } +} diff --git a/Infrastructure/Extensions/AutofacManager/IDependency.cs b/Infrastructure/Extensions/AutofacManager/IDependency.cs new file mode 100644 index 0000000..638e254 --- /dev/null +++ b/Infrastructure/Extensions/AutofacManager/IDependency.cs @@ -0,0 +1,9 @@ +namespace Infrastructure.Extensions.AutofacManager +{ + /// + /// 所有AutoFac注入的基类 + /// + public interface IDependency + { + } +} diff --git a/Infrastructure/Extensions/ConvertJsonExtension.cs b/Infrastructure/Extensions/ConvertJsonExtension.cs new file mode 100644 index 0000000..3cc0e0a --- /dev/null +++ b/Infrastructure/Extensions/ConvertJsonExtension.cs @@ -0,0 +1,377 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Reflection; +using System.Text; +using Newtonsoft.Json; + +namespace Infrastructure.Extensions +{ + public static class ConvertJsonExtension + { + #region 私有方法 + /// + /// 过滤特殊字符 + /// + /// 字符串 + /// json字符串 + private static string String2Json(String s) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.Length; i++) + { + char c = s.ToCharArray()[i]; + switch (c) + { + case '\"': + sb.Append("\\\""); break; + case '\\': + sb.Append("\\\\"); break; + case '/': + sb.Append("\\/"); break; + case '\b': + sb.Append("\\b"); break; + case '\f': + sb.Append("\\f"); break; + case '\n': + sb.Append("\\n"); break; + case '\r': + sb.Append("\\r"); break; + case '\t': + sb.Append("\\t"); break; + default: + sb.Append(c); break; + } + } + return sb.ToString(); + } + /// + /// 格式化字符型、日期型、布尔型 + /// + /// + /// + /// + private static string StringFormat(string str, Type type) + { + if (type == typeof(string)) + { + str = String2Json(str); + str = "\"" + str + "\""; + } + else if (type == typeof(DateTime)) + { + str = "\"" + str + "\""; + } + else if (type == typeof(bool)) + { + str = str.ToLower(); + } + else if (type != typeof(string) && string.IsNullOrEmpty(str)) + { + str = "\"" + str + "\""; + } + return str; + } + + #endregion + + #region list转换成JSON + /// + /// list转换为Json + /// + /// + /// + /// + public static string ListToJson(this IList list) + { + object obj = list[0]; + return ListToJson(list, obj.GetType().Name); + } + /// + /// list转换为json + /// + /// + /// + /// + /// + private static string ListToJson(this IList list, string JsonName) + { + if (list.Count == 0) + { + return ""; + } + StringBuilder Json = new StringBuilder(); + if (string.IsNullOrEmpty(JsonName)) + JsonName = list[0].GetType().Name; + Json.Append("{\"" + JsonName + "\":["); + + for (int i = 0; i < list.Count; i++) + { + T obj = Activator.CreateInstance(); + PropertyInfo[] pi = obj.GetType().GetProperties(); + Json.Append("{"); + for (int j = 0; j < pi.Length; j++) + { + Type type = pi[j].GetValue(list[i], null).GetType(); + Json.Append("\"" + pi[j].Name.ToString() + "\":" + StringFormat(pi[j].GetValue(list[i], null).ToString(), type)); + if (j < pi.Length - 1) + { + Json.Append(","); + } + } + Json.Append("}"); + if (i < list.Count - 1) + { + Json.Append(","); + } + } + Json.Append("]}"); + return Json.ToString(); + } + #endregion + + #region 对象转换为Json + /// + /// 对象转换为json + /// + /// json对象 + /// json字符串 + public static string ToJson(this object jsonObject) + { + string jsonString = "{"; + PropertyInfo[] propertyInfo = jsonObject.GetType().GetProperties(); + for (int i = 0; i < propertyInfo.Length; i++) + { + object objectValue = propertyInfo[i].GetGetMethod().Invoke(jsonObject, null); + string value = string.Empty; + if (objectValue is DateTime || objectValue is Guid || objectValue is TimeSpan) + { + value = "'" + objectValue.ToString() + "'"; + } + else if (objectValue is string) + { + value = "'" + ToJson(objectValue.ToString()) + "'"; + } + else if (objectValue is IEnumerable) + { + value = ToJson((IEnumerable)objectValue); + } + else + { + value = ToJson(objectValue.ToString()); + } + jsonString += "\"" + ToJson(propertyInfo[i].Name) + "\":" + value + ","; + } + jsonString.Remove(jsonString.Length - 1, jsonString.Length); + return jsonString + "}"; + } + + #endregion + + #region 对象集合转换为json + /// + /// 对象集合转换为json + /// + /// 对象集合 + /// json字符串 + public static string ToJson(this IEnumerable array) + { + string jsonString = "{"; + foreach (object item in array) + { + jsonString += ToJson(item) + ","; + } + jsonString.Remove(jsonString.Length - 1, jsonString.Length); + return jsonString + "]"; + } + #endregion + + #region 普通集合转换Json + /// + /// 普通集合转换Json + /// + /// 集合对象 + /// Json字符串 + public static string ToArrayString(this IEnumerable array) + { + string jsonString = "["; + foreach (object item in array) + { + jsonString = ToJson(item.ToString()) + ","; + } + jsonString.Remove(jsonString.Length - 1, jsonString.Length); + return jsonString + "]"; + } + #endregion + + #region DataSet转换为Json + /// + /// DataSet转换为Json + /// + /// DataSet对象 + /// Json字符串 + public static string ToJson(this DataSet dataSet) + { + string jsonString = "{"; + foreach (DataTable table in dataSet.Tables) + { + jsonString += "\"" + table.TableName + "\":" + ToJson(table) + ","; + } + jsonString = jsonString.TrimEnd(','); + return jsonString + "}"; + } + #endregion + + #region Datatable转换为Json + /// + /// Datatable转换为Json + /// + /// Datatable对象 + /// Json字符串 + public static string ToJson(this DataTable dt) + { + StringBuilder jsonString = new StringBuilder(); + jsonString.Append("["); + DataRowCollection drc = dt.Rows; + for (int i = 0; i < drc.Count; i++) + { + jsonString.Append("{"); + for (int j = 0; j < dt.Columns.Count; j++) + { + string strKey = dt.Columns[j].ColumnName; + string strValue = drc[i][j].ToString(); + Type type = dt.Columns[j].DataType; + jsonString.Append("\"" + strKey + "\":"); + strValue = StringFormat(strValue, type); + if (j < dt.Columns.Count - 1) + { + jsonString.Append(strValue + ","); + } + else + { + jsonString.Append(strValue); + } + } + jsonString.Append("},"); + } + jsonString.Remove(jsonString.Length - 1, 1); + jsonString.Append("]"); + return jsonString.ToString(); + } + /// + /// DataTable转换为Json + /// + public static string ToJson(this DataTable dt, string jsonName) + { + StringBuilder Json = new StringBuilder(); + if (string.IsNullOrEmpty(jsonName)) + jsonName = dt.TableName; + Json.Append("{\"" + jsonName + "\":["); + if (dt.Rows.Count > 0) + { + for (int i = 0; i < dt.Rows.Count; i++) + { + Json.Append("{"); + for (int j = 0; j < dt.Columns.Count; j++) + { + Type type = dt.Rows[i][j].GetType(); + Json.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + StringFormat(dt.Rows[i][j].ToString(), type)); + if (j < dt.Columns.Count - 1) + { + Json.Append(","); + } + } + Json.Append("}"); + if (i < dt.Rows.Count - 1) + { + Json.Append(","); + } + } + } + Json.Append("]}"); + return Json.ToString(); + } + + #endregion + + #region DataReader转换为Json + /// + /// DataReader转换为Json + /// + /// DataReader对象 + /// Json字符串 + public static string ReaderJson(this IDataReader dataReader) + { + StringBuilder jsonString = new StringBuilder(); + Dictionary ModelField = new Dictionary(); + for (int i = 0; i < dataReader.FieldCount; i++) + { + ModelField.Add(dataReader.GetName(i), dataReader.GetFieldType(i)); + } + jsonString.Append("["); + while (dataReader.Read()) + { + jsonString.Append("{"); + foreach (KeyValuePair keyVal in ModelField) + { + Type type = keyVal.Value; + string strKey = keyVal.Key; + string strValue = dataReader[strKey].ToString(); + jsonString.Append("\"" + strKey + "\":"); + strValue = StringFormat(strValue, type); + jsonString.Append(strValue + ","); + } + jsonString.Remove(jsonString.Length - 1, 1); + jsonString.Append("},"); + } + dataReader.Close(); + jsonString.Remove(jsonString.Length - 1, 1); + jsonString.Append("]"); + return jsonString.ToString(); + } + #endregion + + + public static T DeserializeObject(this string entityString) + { + if (string.IsNullOrEmpty(entityString)) + { + return default(T); + } + if (entityString == "{}") + { + entityString = "[]"; + } + return JsonConvert.DeserializeObject(entityString); + } + + public static string Serialize(this object obj, JsonSerializerSettings formatDate = null) + { + if (obj == null) return null; + formatDate = formatDate ?? new JsonSerializerSettings + { + DateFormatString = "yyyy-MM-dd HH:mm:ss" + }; + return JsonConvert.SerializeObject(obj, formatDate); + } + + // + // 摘要: + // 字串反序列化成指定对象实体(列表) + // + // 参数: + // Json: + // 字串 + // + // 类型参数: + // T: + // 实体类型 + public static List ToList(this string Json) + { + return (Json == null) ? null : JsonConvert.DeserializeObject>(Json); + } + + } +} + diff --git a/Infrastructure/Extensions/DateTimeExtension.cs b/Infrastructure/Extensions/DateTimeExtension.cs new file mode 100644 index 0000000..83838a2 --- /dev/null +++ b/Infrastructure/Extensions/DateTimeExtension.cs @@ -0,0 +1,52 @@ +using System; + +namespace Infrastructure.Extensions +{ + public static class DateTimeExtension + { + /// + /// 实现由C# 的时间到 Javascript 的时间的转换 + /// returns the number of milliseconds since Jan 1, 1970 (useful for converting C# dates to JS dates) + /// + /// + /// + public static double UnixTicks(this DateTime dt) + { + DateTime d1 = new DateTime(1970, 1, 1); + DateTime d2 = dt.AddHours(8).ToUniversalTime(); + TimeSpan ts = new TimeSpan(d2.Ticks - d1.Ticks); + return ts.TotalMilliseconds; + } + + /// + /// 将毫秒值转成 C# DateTime 类型 + /// + /// + /// + public static DateTime ConvertTime(this long time) + { + DateTime timeStamp = new DateTime(1970, 1, 1); //得到1970年的时间戳 + long t = (time + 8 * 60 * 60) * 10000000 + timeStamp.Ticks; + DateTime dt = new DateTime(t); + return dt; + } + /// + /// 获取格式化字符串,不带时分秒,格式:"yyyy-MM-dd" + /// + /// + /// + public static string ToDateString(this DateTime? dateTime) + { + if (!dateTime.HasValue) + { + return string.Empty; + } + + return dateTime.Value.ToDateString(); + } + public static string ToDateString(this DateTime dateTime) + { + return dateTime.ToString("yyyy-MM-dd"); + } + } +} diff --git a/Infrastructure/Extensions/EntityProperties.cs b/Infrastructure/Extensions/EntityProperties.cs new file mode 100644 index 0000000..b300850 --- /dev/null +++ b/Infrastructure/Extensions/EntityProperties.cs @@ -0,0 +1,1349 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using Infrastructure.Const; +using Infrastructure.Utilities; + +namespace Infrastructure.Extensions +{ + public static class EntityProperties + { + public static string GetExpressionPropertyFirst(this Expression> properties) + { + string[] arr = properties.GetExpressionProperty(); + if (arr.Length > 0) + return arr[0]; + return ""; + } + + /// + /// 获取对象里指定成员名称 + /// + /// + /// > exp = x => new { x.字段1, x.字段2 };或x=>x.Name]]> + /// + public static string[] GetExpressionProperty(this Expression> properties) + { + if (properties == null) + return new string[] { }; + if (properties.Body is NewExpression) + return ((NewExpression) properties.Body).Members.Select(x => x.Name).ToArray(); + if (properties.Body is MemberExpression) + return new string[] {((MemberExpression) properties.Body).Member.Name}; + if (properties.Body is UnaryExpression) + return new string[] {((properties.Body as UnaryExpression).Operand as MemberExpression).Member.Name}; + throw new Exception("未实现的表达式"); + } + + public static string ValidateHashInEntity(this Type typeinfo, Dictionary dic) + { + return typeinfo.ValidateDicInEntity(dic, false); + } + + public static void RemoveNotExistColumns(this Type typeinfo, List cols) + { + } + + /// + /// 获取所有字段的名称 + /// + /// + /// + public static List GetAtrrNames(this Type typeinfo) + { + return typeinfo.GetProperties().Select(c => c.Name).ToList(); + } + + public static void IsExistColumns(this Type typeinfo) + { + } + + public static Dictionary GetColumType(this PropertyInfo[] properties) + { + return properties.GetColumType(false); + } + + public static Dictionary GetColumType(this PropertyInfo[] properties, bool containsKey) + { + Dictionary dictionary = new Dictionary(); + foreach (PropertyInfo property in properties) + { + if (!containsKey && property.IsKey()) + { + continue; + } + + var keyVal = GetColumnType(property, true); + dictionary.Add(keyVal.Key, keyVal.Value); + } + + return dictionary; + } + + private static readonly Dictionary entityMapDbColumnType = new Dictionary() + { + {typeof(int), SqlDbTypeName.Int}, + {typeof(int?), SqlDbTypeName.Int}, + {typeof(long), SqlDbTypeName.BigInt}, + {typeof(long?), SqlDbTypeName.BigInt}, + {typeof(decimal), "decimal(18, 5)"}, + {typeof(decimal?), "decimal(18, 5)"}, + {typeof(double), "decimal(18, 5)"}, + {typeof(double?), "decimal(18, 5)"}, + {typeof(float), "decimal(18, 5)"}, + {typeof(float?), "decimal(18, 5)"}, + {typeof(Guid), "UniqueIdentifier"}, + {typeof(Guid?), "UniqueIdentifier"}, + {typeof(byte), "tinyint"}, + {typeof(byte?), "tinyint"}, + {typeof(string), "nvarchar"} + }; + + /// + /// 返回属性的字段及数据库类型 + /// + /// + /// 是否包括后字段具体长度:nvarchar(100) + /// + public static KeyValuePair GetColumnType(this PropertyInfo property, bool lenght = false) + { + string colType = ""; + object objAtrr = property.GetTypeCustomAttributes(typeof(ColumnAttribute), out bool asType); + if (asType) + { + colType = ((ColumnAttribute) objAtrr).TypeName.ToLower(); + if (!string.IsNullOrEmpty(colType)) + { + //不需要具体长度直接返回 + if (!lenght) + { + return new KeyValuePair(property.Name, colType); + } + + if (colType == "decimal" || colType == "double" || colType == "float") + { + objAtrr = property.GetTypeCustomAttributes(typeof(DisplayFormatAttribute), out asType); + colType += "(" + (asType ? ((DisplayFormatAttribute) objAtrr).DataFormatString : "18,5") + ")"; + } + + //如果是string,根据 varchar或nvarchar判断最大长度 + if (property.PropertyType.ToString() == "System.String") + { + colType = colType.Split("(")[0]; + objAtrr = property.GetTypeCustomAttributes(typeof(MaxLengthAttribute), out asType); + if (asType) + { + int length = ((MaxLengthAttribute) objAtrr).Length; + colType += "(" + (length < 1 || length > (colType.StartsWith("n") ? 8000 : 4000) + ? "max" + : length.ToString()) + ")"; + } + else + { + colType += "(max)"; + } + } + + return new KeyValuePair(property.Name, colType); + } + } + + if (entityMapDbColumnType.TryGetValue(property.PropertyType, out string value)) + { + colType = value; + } + else + { + colType = SqlDbTypeName.NVarChar; + } + + if (lenght && colType == SqlDbTypeName.NVarChar) + { + colType = "nvarchar(max)"; + } + + return new KeyValuePair(property.Name, colType); + } + + /// + /// + /// + /// 将数组转换成sql语句 + /// 指定FieldType数据库字段类型 + /// + /// + public static string GetArraySql(this object[] array, FieldType fieldType) + { + if (array == null || array.Count() == 0) + { + return string.Empty; + } + + string columnType = string.Empty; + List arrrayEntityList = array.Select(x => new ArrayEntity {column1 = x.ToString()}).ToList(); + return arrrayEntityList.GetEntitySql(false, null, null, null, fieldType); + } + + /// + ///要执行的sql语句如:通过EntityToSqlTempName.Temp_Insert0.ToString()字符串占位,生成的的sql语句会把EntityToSqlTempName.Temp_Insert0.ToString()替换成生成的sql临时表数据 + /// string sql = " ;DELETE FROM " + typeEntity.Name + " where " + typeEntity.GetKeyName() + + /// " in (select * from " + EntityToSqlTempName.Temp_Insert0.ToString() + ")"; + /// + /// + /// + /// 指定生成的数组值的类型 + /// + public static string GetArraySql(this object[] array, FieldType fieldType, string sql) + { + if (array == null || array.Count() == 0) + { + return string.Empty; + } + + string columnType = string.Empty; + List arrrayEntityList = array.Select(x => new ArrayEntity {column1 = x.ToString()}).ToList(); + return arrrayEntityList.GetEntitySql(false, sql, null, null, fieldType); + } + + public static string GetArraySql(this object[] array, string sql) + { + return array.GetArraySql(typeof(T).GetFieldType(), sql); + } + + /// + /// 根据实体获取key的类型,用于update或del操作 + /// + /// + public static FieldType GetFieldType(this Type typeEntity) + { + FieldType fieldType; + string columnType = typeEntity.GetProperties().Where(x => x.Name == typeEntity.GetKeyName()).ToList()[0] + .GetColumnType(false).Value; + switch (columnType) + { + case SqlDbTypeName.Int: + fieldType = FieldType.Int; + break; + case SqlDbTypeName.BigInt: + fieldType = FieldType.BigInt; + break; + case SqlDbTypeName.VarChar: + fieldType = FieldType.VarChar; + break; + case SqlDbTypeName.UniqueIdentifier: + fieldType = FieldType.UniqueIdentifier; + break; + default: + fieldType = FieldType.NvarChar; + break; + } + + return fieldType; + } + + public static string GetEntitySql(this IEnumerable entityList, + bool containsKey = false, + string sql = null, + Expression> ignoreFileds = null, + Expression> fixedColumns = null, + FieldType? fieldType = null + ) + { + if (entityList == null || entityList.Count() == 0) return ""; + PropertyInfo[] propertyInfo = typeof(T).GetProperties().ToArray(); + if (propertyInfo.Count() == 0) + { + propertyInfo = entityList.ToArray()[0].GetType().GetGenericProperties().ToArray(); + } + + propertyInfo = propertyInfo.GetGenericProperties().ToArray(); + + string[] arr = null; + if (fixedColumns != null) + { + arr = fixedColumns.GetExpressionToArray(); + PropertyInfo keyProperty = typeof(T).GetKeyProperty(); + propertyInfo = propertyInfo + .Where(x => (containsKey && x.Name == keyProperty.Name) || arr.Contains(x.Name)).ToArray(); + } + + if (ignoreFileds != null) + { + arr = ignoreFileds.GetExpressionToArray(); + propertyInfo = propertyInfo.Where(x => !arr.Contains(x.Name)).ToArray(); + } + + Dictionary dictProperties = propertyInfo.GetColumType(containsKey); + if (fieldType != null) + { + string realType = fieldType.ToString(); + if ((int) fieldType == 0 || (int) fieldType == 1) + { + realType += "(max)"; + } + + dictProperties = new Dictionary + {{dictProperties.Select(x => x.Key).ToList()[0], realType}}; + } + + if (dictProperties.Keys.Count * entityList.Count() > 50 * 3000) + { + throw new Exception("写入数据太多,请分开写入。"); + } + + string cols = string.Join(",", dictProperties.Select(c => "[" + c.Key + "]" + " " + c.Value)); + StringBuilder declareTable = new StringBuilder(); + + string tempTablbe = "#" + EntityToSqlTempName.TempInsert.ToString(); + + declareTable.Append("CREATE TABLE " + tempTablbe + " (" + cols + ")"); + declareTable.Append("\r\n"); + + //参数总数量 + int parCount = (dictProperties.Count) * (entityList.Count()); + int takeCount = 0; + int maxParsCount = 2050; + if (parCount > maxParsCount) + { + //如果参数总数量超过2100,设置每次分批循环写入表的大小 + takeCount = maxParsCount / dictProperties.Count; + } + + int count = 0; + StringBuilder stringLeft = new StringBuilder(); + StringBuilder stringCenter = new StringBuilder(); + StringBuilder stringRight = new StringBuilder(); + + int index = 0; + foreach (T entity in entityList) + { + //每1000行需要分批写入(数据库限制每批至多写入1000行数据) + if (index == 0 || index >= 1000 || takeCount - index == 0) + { + if (stringLeft.Length > 0) + { + declareTable.AppendLine( + stringLeft.Remove(stringLeft.Length - 2, 2).Append("',").ToString() + + stringCenter.Remove(stringCenter.Length - 1, 1).Append("',").ToString() + + stringRight.Remove(stringRight.Length - 1, 1).ToString()); + + stringLeft.Clear(); + stringCenter.Clear(); + stringRight.Clear(); + } + + stringLeft.AppendLine("exec sp_executesql N'SET NOCOUNT ON;"); + stringCenter.Append("N'"); + + index = 0; + count = 0; + } + + stringLeft.Append(index == 0 ? "; INSERT INTO " + tempTablbe + " values (" : " "); + index++; + foreach (PropertyInfo property in propertyInfo) + { + if (!containsKey && property.IsKey()) + { + continue; + } + + string par = "@v" + count; + stringLeft.Append(par + ","); + stringCenter.Append(par + " " + dictProperties[property.Name] + ","); + object val = property.GetValue(entity); + if (val == null) + { + stringRight.Append(par + "=NUll,"); + } + else + { + stringRight.Append(par + "='" + val.ToString().Replace("'", "''''") + "',"); + } + + count++; + } + + stringLeft.Remove(stringLeft.Length - 1, 1); + stringLeft.Append("),("); + } + + if (stringLeft.Length > 0) + { + declareTable.AppendLine( + stringLeft.Remove(stringLeft.Length - 2, 2).Append("',").ToString() + + stringCenter.Remove(stringCenter.Length - 1, 1).Append("',").ToString() + + stringRight.Remove(stringRight.Length - 1, 1).ToString()); + + stringLeft.Clear(); + stringCenter.Clear(); + stringRight.Clear(); + } + + if (!string.IsNullOrEmpty(sql)) + { + sql = sql.Replace(EntityToSqlTempName.TempInsert.ToString(), tempTablbe); + declareTable.AppendLine(sql); + } + else + { + declareTable.AppendLine(" SELECT " + + (string.Join(",", fixedColumns?.GetExpressionToArray() ?? new string[] {"*"})) + + " FROM " + tempTablbe); + } + + + if (tempTablbe.Substring(0, 1) == "#") + { + declareTable.AppendLine("; drop table " + tempTablbe); + } + + return declareTable.ToString(); + } + + + /// + ///此方法适用于数据量少,只有几列数据,不超过1W行,或几十列数据不超过1000行的情况下使用 + /// 大批量的数据考虑其他方式 + /// 將datatable生成sql語句,替換datatable作為參數傳入存儲過程 + /// + /// + /// + public static string GetDataTableSql(this DataTable table) + { + Dictionary dictCloumn = new Dictionary(); + for (int i = 0; i < table.Columns.Count; i++) + { + dictCloumn.Add(table.Columns[i].ColumnName, " nvarchar(max)"); + } + + + //参数总数量 + int parCount = (dictCloumn.Count) * (table.Rows.Count); + int takeCount = 0; + int maxParsCount = 2050; + if (parCount > maxParsCount) + { + //如果参数总数量超过2100,设置每次分批循环写入表的大小 + takeCount = maxParsCount / dictCloumn.Count; + } + + if (dictCloumn.Keys.Count * table.Rows.Count > 50 * 3000) + { + throw new Exception("写入数据太多,请分开写入。"); + } + + string cols = string.Join(",", dictCloumn.Select(c => "[" + c.Key + "]" + " " + c.Value)); + StringBuilder declareTable = new StringBuilder(); + + string tempTablbe = "#Temp_Insert0"; + declareTable.Append("CREATE TABLE " + tempTablbe + " (" + cols + ")"); + declareTable.Append("\r\n"); + int count = 0; + StringBuilder stringLeft = new StringBuilder(); + StringBuilder stringCenter = new StringBuilder(); + StringBuilder stringRight = new StringBuilder(); + + int index = 0; + + foreach (DataRow row in table.Rows) + { + //每1000行需要分批写入(数据库限制每批至多写入1000行数据) + if (index == 0 || index >= 1000 || takeCount - index == 0) + { + if (stringLeft.Length > 0) + { + declareTable.AppendLine( + stringLeft.Remove(stringLeft.Length - 2, 2).Append("',").ToString() + + stringCenter.Remove(stringCenter.Length - 1, 1).Append("',").ToString() + + stringRight.Remove(stringRight.Length - 1, 1).ToString()); + + stringLeft.Clear(); + stringCenter.Clear(); + stringRight.Clear(); + } + + // sbLeft.AppendLine(" INSERT INTO @toInsert0"); + stringLeft.AppendLine("exec sp_executesql N'SET NOCOUNT ON;"); + stringCenter.Append("N'"); + + index = 0; + count = 0; + } + + stringLeft.Append(index == 0 ? "; INSERT INTO " + tempTablbe + " values (" : " "); + index++; + foreach (KeyValuePair keyValue in dictCloumn) + { + string par = "@v" + count; + stringLeft.Append(par + ","); + stringCenter.Append(par + " " + keyValue.Value + ","); + object val = row[keyValue.Key]; + if (val == null) + { + stringRight.Append(par + "=NUll,"); + } + else + { + stringRight.Append(par + "='" + val.ToString().Replace("'", "''''") + "',"); + } + + count++; + } + + stringLeft.Remove(stringLeft.Length - 1, 1); + stringLeft.Append("),("); + } + + + if (stringLeft.Length > 0) + { + declareTable.AppendLine( + stringLeft.Remove(stringLeft.Length - 2, 2).Append("',").ToString() + + stringCenter.Remove(stringCenter.Length - 1, 1).Append("',").ToString() + + stringRight.Remove(stringRight.Length - 1, 1).ToString()); + + stringLeft.Clear(); + stringCenter.Clear(); + stringRight.Clear(); + } + + declareTable.AppendLine(" SELECT * FROM " + tempTablbe); + if (tempTablbe.Substring(0, 1) == "#") + { + declareTable.AppendLine("; drop table " + tempTablbe); + } + + return declareTable.ToString(); + } + + + public static string GetKeyName(this Type typeinfo) + { + return typeinfo.GetProperties().GetKeyName(); + } + + public static string GetKeyType(this Type typeinfo) + { + string keyType = typeinfo.GetProperties().GetKeyName(true); + if (keyType == "varchar") + { + return "varchar(max)"; + } + else if (keyType != "nvarchar") + { + return keyType; + } + else + { + return "nvarchar(max)"; + } + } + + public static string GetKeyName(this PropertyInfo[] properties) + { + return properties.GetKeyName(false); + } + + /// + /// 获取key列名 + /// + /// + /// true获取key对应类型,false返回对象Key的名称 + /// + public static string GetKeyName(this PropertyInfo[] properties, bool keyType) + { + string keyName = string.Empty; + foreach (PropertyInfo propertyInfo in properties) + { + if (!propertyInfo.IsKey()) + continue; + if (!keyType) + return propertyInfo.Name; + var attributes = propertyInfo.GetCustomAttributes(typeof(ColumnAttribute), false); + //如果没有ColumnAttribute的需要单独再验证,下面只验证有属性的 + if (attributes.Length > 0) + return ((ColumnAttribute) attributes[0]).TypeName.ToLower(); + else + return GetColumType(new PropertyInfo[] {propertyInfo}, true)[propertyInfo.Name]; + } + + return keyName; + } + + /// + /// 获取主键字段 + /// + /// + /// + public static PropertyInfo GetKeyProperty(this Type entity) + { + return entity.GetProperties().GetKeyProperty(); + } + + public static PropertyInfo GetKeyProperty(this PropertyInfo[] properties) + { + return properties.Where(c => c.IsKey()).FirstOrDefault(); + } + + public static bool IsKey(this PropertyInfo propertyInfo) + { + object[] keyAttributes = propertyInfo.GetCustomAttributes(typeof(KeyAttribute), false); + if (keyAttributes.Length > 0) + return true; + return false; + } + + + private static string[] _userEditFields { get; set; } + + + /// + /// 判断是否包含某个属性 + /// public string MO {get; set; }包含Editable + /// + public static bool ContainsCustomAttributes(this PropertyInfo propertyInfo, Type type) + { + propertyInfo.GetTypeCustomAttributes(type, out bool contains); + return contains; + } + + public static List ContainsCustomAttributes(this Type obj, Type containType) + { + List proList = new List(); + foreach (PropertyInfo pro in obj.GetProperties()) + { + if (pro.GetTypeCustomAttributes(containType) != null) + { + proList.Add(pro); + } + } + + return proList; + } + + /// + /// 获取PropertyInfo指定属性 + /// + /// + /// + /// + public static object GetTypeCustomAttributes(this PropertyInfo propertyInfo, Type type, out bool asType) + { + object[] attributes = propertyInfo.GetCustomAttributes(type, false); + if (attributes.Length == 0) + { + asType = false; + return new string[0]; + } + + asType = true; + return attributes[0]; + } + + /// + /// 验证集合的属性 + /// + /// + /// + /// + /// + public static void ValidationEntityList(this List entityList, + Expression> expression = null) + { + WebResponseContent responseData = new WebResponseContent(); + foreach (T entity in entityList) + { + entity.ValidationEntity(expression); + } + } + + /// + /// 指定需要验证的字段 + /// + /// + /// + /// 对指定属性进行验证x=>{x.Name,x.Size} + /// + public static void ValidationEntity(this T entity, Expression> expression = null, + Expression> validateProperties = null) + { + ValidationEntity(entity, expression?.GetExpressionProperty(), + validateProperties?.GetExpressionProperty()); + } + + /// + /// specificProperties=null并且validateProperties=null,对所有属性验证,只验证其是否合法,不验证是否为空(除属性标识指定了不能为空外) + /// specificProperties!=null,对指定属性校验,并且都必须有值 + /// null并且validateProperties!=null,对指定属性校验,不判断是否有值 + /// + /// + /// + /// 验证指定的属性,并且非空判断 + /// 验证指定属性,只对字段合法性判断,不验证是否为空 + /// + public static void ValidationEntity(this T entity, string[] specificProperties, + string[] validateProperties = null) + { + if (entity == null) + { + throw new Exception("对象不能为null"); + } + + PropertyInfo[] propertyArray = typeof(T).GetProperties(); + //若T为object取不到属性 + if (propertyArray.Length == 0) + { + propertyArray = entity.GetType().GetProperties(); + } + + List compareProper = new List(); + + //只验证数据合法性,验证非空 + if (specificProperties != null && specificProperties.Length > 0) + { + compareProper.AddRange(propertyArray.Where(x => specificProperties.Contains(x.Name))); + } + + //只验证数据合法性,不验证非空 + if (validateProperties != null && validateProperties.Length > 0) + { + compareProper.AddRange(propertyArray.Where(x => validateProperties.Contains(x.Name))); + } + + if (compareProper.Count() > 0) + { + propertyArray = compareProper.ToArray(); + } + + foreach (PropertyInfo propertyInfo in propertyArray) + { + object value = propertyInfo.GetValue(entity); + //设置默认状态的值 + if (propertyInfo.Name == "Enable") + { + if (value == null) + { + propertyInfo.SetValue(entity, 0); + continue; + } + } + + //若存在specificProperties并且属性为数组specificProperties中的值,校验时就需要判断是否为空 + var reslut = propertyInfo.ValidationProperty(value, + specificProperties != null && specificProperties.Contains(propertyInfo.Name) ? true : false + ); + if (!reslut.Item1) + { + throw new Exception(reslut.Item2); + } + } + } + + /// + /// 获取数据库类型,不带长度,如varchar(100),只返回的varchar + /// + /// + /// + public static string GetSqlDbType(this PropertyInfo propertyInfo) + { + string dbType = propertyInfo.GetTypeCustomValue(x => new {x.TypeName}); + + if (string.IsNullOrEmpty(dbType)) + { + return dbType; + } + + dbType = dbType.ToLower(); + if (dbType.Contains(SqlDbTypeName.NVarChar)) + { + dbType = SqlDbTypeName.NVarChar; + } + else if (dbType.Contains(SqlDbTypeName.VarChar)) + { + dbType = SqlDbTypeName.VarChar; + } + else if (dbType.Contains(SqlDbTypeName.NChar)) + { + dbType = SqlDbTypeName.NChar; + } + else if (dbType.Contains(SqlDbTypeName.Char)) + { + dbType = SqlDbTypeName.Char; + } + + return dbType; + } + + /// + /// 验证数据库字段类型与值是否正确, + /// + /// propertyInfo为当字段,当前字段必须有ColumnAttribute属性, + /// 如字段:标识为数据库int类型[Column(TypeName="int")] public int Id { get; set; } + /// 如果是小数float或Decimal必须对propertyInfo字段加DisplayFormatAttribute属性 + /// + /// + /// IEnumerable<(bool, string, object)> bool成否校验成功,string校验失败信息,object,当前校验的值 + public static IEnumerable<(bool, string, object)> ValidationValueForDbType(this PropertyInfo propertyInfo, + params object[] values) + { + string dbTypeName = propertyInfo.GetTypeCustomValue(c => c.TypeName); + foreach (object value in values) + { + yield return dbTypeName.ValidationVal(value, propertyInfo); + } + } + + public static bool ValidationRquiredValueForDbType(this PropertyInfo propertyInfo, object value, + out string message) + { + if (value == null || value?.ToString()?.Trim() == "") + { + message = $"{propertyInfo.GetDisplayName()}不能为空"; + return false; + } + + var result = propertyInfo.GetProperWithDbType().ValidationVal(value, propertyInfo); + message = result.Item2; + return result.Item1; + } + + private static readonly Dictionary ProperWithDbType = new Dictionary() + { + {typeof(string), SqlDbTypeName.NVarChar}, + {typeof(DateTime), SqlDbTypeName.DateTime}, + {typeof(long), SqlDbTypeName.BigInt}, + {typeof(int), SqlDbTypeName.Int}, + {typeof(decimal), SqlDbTypeName.Decimal}, + {typeof(float), SqlDbTypeName.Float}, + {typeof(double), SqlDbTypeName.Double}, + {typeof(byte), SqlDbTypeName.Int}, //类型待完 + {typeof(Guid), SqlDbTypeName.UniqueIdentifier} + }; + + public static string GetProperWithDbType(this PropertyInfo propertyInfo) + { + bool result = ProperWithDbType.TryGetValue(propertyInfo.PropertyType, out string value); + if (result) + { + return value; + } + + return SqlDbTypeName.NVarChar; + } + + /// + /// 验证数据库字段类型与值是否正确, + /// + /// 数据库字段类型(如varchar,nvarchar,decimal,不要带后面长度如:varchar(50)) + /// 值 + /// 要验证的类的属性,若不为null,则会判断字符串的长度是否正确 + /// (bool, string, object)bool成否校验成功,string校验失败信息,object,当前校验的值 + public static (bool, string, object) ValidationVal(this string dbType, object value, + PropertyInfo propertyInfo = null) + { + if (string.IsNullOrEmpty(dbType)) + { + dbType = propertyInfo != null ? propertyInfo.GetProperWithDbType() : SqlDbTypeName.NVarChar; + } + + dbType = dbType.ToLower(); + string val = value?.ToString(); + //验证长度 + string reslutMsg = string.Empty; + if (dbType == SqlDbTypeName.Int || dbType == SqlDbTypeName.BigInt) + { + if (!StringExtension.IsInt(value)) + reslutMsg = "只能为有效整数"; + } + else if (dbType == SqlDbTypeName.DateTime + || dbType == SqlDbTypeName.Date + || dbType == SqlDbTypeName.SmallDateTime + || dbType == SqlDbTypeName.SmallDate + ) + { + if (!StringExtension.IsDate(value)) + reslutMsg = "必须为日期格式"; + } + else if (dbType == SqlDbTypeName.Float || dbType == SqlDbTypeName.Decimal || dbType == SqlDbTypeName.Double) + { + string formatString = string.Empty; + if (propertyInfo != null) + formatString = propertyInfo.GetTypeCustomValue(x => x.DataFormatString); + //if (string.IsNullOrEmpty(formatString)) + // throw new Exception("请对字段" + propertyInfo?.Name + "添加DisplayFormat属性标识"); + + if (!StringExtension.IsNumber(val, formatString)) + { + string[] arr = (formatString ?? "10,0").Split(','); + reslutMsg = $"整数{arr[0]}最多位,小数最多{arr[1]}位"; + } + } + else if (dbType == SqlDbTypeName.UniqueIdentifier) + { + if (!StringExtension.IsGuid(val)) + { + reslutMsg = propertyInfo.Name + "Guid不正确"; + } + } + else if (propertyInfo != null + && (dbType == SqlDbTypeName.VarChar + || dbType == SqlDbTypeName.NVarChar + || dbType == SqlDbTypeName.NChar + || dbType == SqlDbTypeName.Char + || dbType == SqlDbTypeName.Text)) + { + //默认nvarchar(max) 、text 长度不能超过20000 + if (val.Length > 20000) + { + reslutMsg = $"字符长度最多【20000】"; + } + else + { + int length = + StringExtension.GetInt( + propertyInfo.GetTypeCustomValue(x => new {x.Length})); + if (length == 0) + { + return (true, null, null); + } + //判断双字节与单字段 + else if (length < 8000 && + ((dbType.Substring(0, 1) != "n" + && Encoding.UTF8.GetBytes(val.ToCharArray()).Length > length) + || val.Length > length) + ) + { + reslutMsg = $"最多只能【{length}】个字符。"; + } + } + } + + if (!string.IsNullOrEmpty(reslutMsg) && propertyInfo != null) + { + reslutMsg = propertyInfo.GetDisplayName() + reslutMsg; + } + + return (reslutMsg == "" ? true : false, reslutMsg, value); + } + + public static string GetDisplayName(this PropertyInfo property) + { + string displayName = property.GetTypeCustomValue(x => new {x.Name}); + if (string.IsNullOrEmpty(displayName)) + { + return property.Name; + } + + return displayName; + } + + /// + /// 验证每个属性的值是否正确 + /// + /// + /// 属性的值 + /// 是否指定当前属性必须有值 + /// + public static (bool, string, object) ValidationProperty(this PropertyInfo propertyInfo, object objectVal, + bool required) + { + if (propertyInfo.IsKey()) + { + return (true, null, objectVal); + } + + string val = objectVal == null ? "" : objectVal.ToString().Trim(); + + string requiredMsg = string.Empty; + if (required) + { + var reuireVal = + propertyInfo.GetTypeCustomValues(x => new {x.AllowEmptyStrings, x.ErrorMessage}); + if (reuireVal != null && !Convert.ToBoolean(reuireVal["AllowEmptyStrings"])) + { + required = true; + requiredMsg = reuireVal["ErrorMessage"]; + } + } + + //如果不要求为必填项并且值为空,直接返回 + if (!required && string.IsNullOrEmpty(val)) + return (true, null, objectVal); + + if ((required && val == string.Empty)) + { + if (requiredMsg != "") return (false, requiredMsg, objectVal); + string propertyName = propertyInfo.GetTypeCustomValue(x => new {x.Name}); + return (false, + requiredMsg + (string.IsNullOrEmpty(propertyName) ? propertyInfo.Name : propertyName) + "不能为空", + objectVal); + } + + //列名 + string typeName = propertyInfo.GetSqlDbType(); + + //如果没有ColumnAttribute的需要单独再验证,下面只验证有属性的 + if (typeName == null) + { + return (true, null, objectVal); + } + + //验证长度 + return typeName.ValidationVal(val, propertyInfo); + } + + /// + /// 获取属性的指定属性 + /// + /// + /// + /// + public static object GetTypeCustomAttributes(this MemberInfo member, Type type) + { + object[] obj = member.GetCustomAttributes(type, false); + if (obj.Length == 0) return null; + return obj[0]; + } + + /// + /// 获取类的指定属性 + /// + /// + /// + /// + public static object GetTypeCustomAttributes(this Type entity, Type type) + { + object[] obj = entity.GetCustomAttributes(type, false); + if (obj.Length == 0) return null; + return obj[0]; + } + + /// + /// 获取类的多个指定属性的值 + /// + /// 当前类 + /// 指定的类 + /// 指定属性的值 格式 Expression<Func<entityt, object>> exp = x => new { x.字段1, x.字段2 }; + /// 返回的是字段+value + public static Dictionary GetTypeCustomValues(this MemberInfo member, + Expression> expression) + { + var attr = member.GetTypeCustomAttributes(typeof(TEntity)); + if (attr == null) + { + return null; + } + + string[] propertyName = expression.GetExpressionProperty(); + Dictionary propertyKeyValues = new Dictionary(); + + foreach (PropertyInfo property in attr.GetType().GetProperties()) + { + if (propertyName.Contains(property.Name)) + { + propertyKeyValues[property.Name] = (property.GetValue(attr) ?? string.Empty).ToString(); + } + } + + return propertyKeyValues; + } + + /// + /// 获取类的单个指定属性的值(只会返回第一个属性的值) + /// + /// 当前类 + /// 指定的类 + /// 指定属性的值 格式 Expression<Func<entityt, object>> exp = x => new { x.字段1, x.字段2 }; + /// + public static string GetTypeCustomValue(this MemberInfo member, + Expression> expression) + { + var propertyKeyValues = member.GetTypeCustomValues(expression); + if (propertyKeyValues == null || propertyKeyValues.Count == 0) + { + return null; + } + + return propertyKeyValues.First().Value ?? ""; + } + + /// + /// 判断hash的列是否为对应的实体,并且值是否有效 + /// + /// + /// + /// 移除不存在字段 + /// + public static string ValidateDicInEntity(this Type typeinfo, Dictionary dic, + bool removeNotContains, string[] ignoreFields = null) + { + return typeinfo.ValidateDicInEntity(dic, removeNotContains, true, ignoreFields); + } + + public static string ValidateDicInEntity(this Type type, List> dicList, + bool removeNotContains, bool removerKey, string[] ignoreFields = null) + { + PropertyInfo[] propertyInfo = type.GetProperties(); + string reslutMsg = string.Empty; + foreach (Dictionary dic in dicList) + { + reslutMsg = type.ValidateDicInEntity(dic, propertyInfo, removeNotContains, removerKey, ignoreFields); + if (!string.IsNullOrEmpty(reslutMsg)) + return reslutMsg; + } + + return reslutMsg; + } + + public static string ValidateDicInEntity(this Type type, Dictionary dic, bool removeNotContains, + bool removerKey, string[] ignoreFields = null) + { + return type.ValidateDicInEntity(dic, null, removeNotContains, removerKey, ignoreFields); + } + + /// + /// 判断hash的列是否为对应的实体,并且值是否有效 + /// + /// + /// + /// 移除不存在字段 + /// 移除主键 + /// + private static string ValidateDicInEntity(this Type typeinfo, Dictionary dic, + PropertyInfo[] propertyInfo, bool removeNotContains, bool removerKey, string[] ignoreFields = null) + { + if (dic == null || dic.Count == 0) + { + return "参数无效"; + } + + if (propertyInfo == null) + propertyInfo = typeinfo.GetProperties().Where(x => x.PropertyType.Name != "List`1").ToArray(); + + // 不存在的字段直接移除 + dic.Where(x => !propertyInfo.Any(p => p.Name == x.Key)).Select(s => s.Key).ToList().ForEach(f => + { + dic.Remove(f); + }); + string keyName = typeinfo.GetKeyName(); + //移除主键 + if (removerKey) + { + dic.Remove(keyName); + } + + foreach (PropertyInfo property in propertyInfo) + { + //忽略与主键的字段不做验证 + if (property.Name == keyName || (ignoreFields != null && ignoreFields.Contains(property.Name))) + continue; + + //不在编辑中的列,是否也要必填 + if (!dic.ContainsKey(property.Name)) + { + //移除主键默认为新增数据,将不在编辑列中的有默认值的数据设置为默认值 + //如果为true默认为添加功能,添加操作所有不能为空的列也必须要提交 + if (property.GetCustomAttributes(typeof(RequiredAttribute)).Count() > 0 + && property.PropertyType != typeof(int) + && property.PropertyType != typeof(long) + && property.PropertyType != typeof(byte) + && property.PropertyType != typeof(decimal) + ) + { + return property.GetTypeCustomValue(x => x.Name) + "为必须提交项"; + } + + continue; + } + + bool isEdit = property.ContainsCustomAttributes(typeof(EditableAttribute)); + //不是编辑列的直接移除,并且不是主键 + //removerKey=true,不保留主键,直接移除 + //removerKey=false,保留主键,属性与主键不同的直接移除 + // if (!isEdit && (removerKey || (!removerKey && property.Name != keyName))) + if (!isEdit) + { + if (property.GetCustomAttributes(typeof(RequiredAttribute)).Count() > 0) + { + return property.GetTypeCustomValue(x => x.Name) + "没有配置好Model为编辑列"; + } + + dic.Remove(property.Name); + continue; + } + + ////移除忽略的不保存的数据 + //if (property.ContainsCustomAttributes(typeof(JsonIgnoreAttribute))) + //{ + // hash.Remove(property.Name); + // continue; + //} + //验证数据类型,不验证是否为空 + var result = property.ValidationProperty(dic[property.Name], false); + if (!result.Item1) + return result.Item2; + + //将所有空值设置为null + if (dic[property.Name] != null && dic[property.Name].ToString() == string.Empty) + dic[property.Name] = null; + } + + return string.Empty; + } + + + private static object MapToInstance(this Type reslutType, object sourceEntity, PropertyInfo[] sourcePro, + PropertyInfo[] reslutPro, string[] sourceFilterField, string[] reslutFilterField, string mapType = null) + { + mapType = mapType ?? GetMapType(reslutType); + if (sourcePro == null) + { + sourcePro = sourceEntity.GetType().GetProperties(); + } + + if (reslutPro == null) + { + reslutPro = reslutType.GetProperties(); + ; + } + + object newObj = Activator.CreateInstance(reslutType); + + if (mapType == "Dictionary") + { + if (sourceFilterField != null && sourceFilterField.Length > 0) + { + sourcePro = sourcePro.Where(x => sourceFilterField.Contains(x.Name)).ToArray(); + } + + foreach (var property in sourcePro) + { + (newObj as System.Collections.IDictionary).Add(property.Name, property.GetValue(sourceEntity)); + } + + return newObj; + } + + if (reslutFilterField != null && reslutFilterField.Count() > 0) + { + reslutPro.Where(x => reslutFilterField.Contains(x.Name)); + } + + foreach (var property in reslutPro) + { + PropertyInfo info = sourcePro.Where(x => x.Name == property.Name).FirstOrDefault(); + if (!(info != null && info.PropertyType == property.PropertyType)) + continue; + property.SetValue(newObj, info.GetValue(sourceEntity)); + } + + return newObj; + } + + private static string GetMapType(Type type) + { + return typeof(Dictionary<,>) == type ? "Dictionary" : "entity"; + } + + /// + /// 将数据源映射到新的数据中,目前只支持List<TSource>映射到List<TResult>或TSource映射到TResult + /// 目前只支持Dictionary或实体类型 + /// + /// + /// + /// + /// 只映射返回对象的指定字段,若为null则默认为全部字段 + /// 只映射数据源对象的指定字段,若为null则默认为全部字段 + /// + public static TResult MapToObject(this TSource source, + Expression> resultExpression, + Expression> sourceExpression = null + ) where TResult : class + { + if (source == null) + return null; + string[] sourceFilterField = sourceExpression == null + ? typeof(TSource).GetProperties().Select(x => x.Name).ToArray() + : sourceExpression.GetExpressionProperty(); + string[] reslutFilterField = resultExpression?.GetExpressionProperty(); + if (!(source is System.Collections.IList)) + return MapToInstance(typeof(TResult), source, null, null, sourceFilterField, reslutFilterField) as + TResult; + + Type sourceType = null; + Type resultType = null; + System.Collections.IList sourceList = source as System.Collections.IList; + sourceType = sourceList[0].GetType(); + resultType = (typeof(TResult)).GenericTypeArguments[0]; + + System.Collections.IList reslutList = Activator.CreateInstance(typeof(TResult)) as System.Collections.IList; + PropertyInfo[] sourcePro = sourceType.GetProperties(); + PropertyInfo[] resultPro = resultType.GetProperties(); + + string mapType = GetMapType(resultType); + for (int i = 0; i < sourceList.Count; i++) + { + var reslutobj = MapToInstance(resultType, sourceList[i], sourcePro, resultPro, sourceFilterField, + reslutFilterField, mapType); + reslutList.Add(reslutobj); + } + + return reslutList as TResult; + } + + /// + /// 将一个实体的赋到另一个实体上,应用场景: + /// 两个实体,a a1= new a();b b1= new b(); a1.P=b1.P; a1.Name=b1.Name; + /// + /// + /// + /// + /// + /// 指定对需要的字段赋值,格式x=>new {x.Name,x.P},返回的结果只会对Name与P赋值 + public static void MapValueToEntity(this TSource source, TResult result, + Expression> expression = null) where TResult : class + { + if (source == null) + return; + string[] fields = expression?.GetExpressionToArray(); + PropertyInfo[] reslutPro = fields == null + ? result.GetType().GetProperties() + : result.GetType().GetProperties().Where(x => fields.Contains(x.Name)).ToArray(); + PropertyInfo[] sourcePro = source.GetType().GetProperties(); + foreach (var property in reslutPro) + { + PropertyInfo info = sourcePro.Where(x => x.Name == property.Name).FirstOrDefault(); + if (info != null && info.PropertyType == property.PropertyType) + { + property.SetValue(result, info.GetValue(source)); + } + } + } + } + + public class ArrayEntity + { + public string column1 { get; set; } + } + + public enum FieldType + { + VarChar = 0, + NvarChar, + Int, + BigInt, + UniqueIdentifier + } + + public enum EntityToSqlTempName + { + TempInsert = 0 + } +} \ No newline at end of file diff --git a/Infrastructure/Extensions/EnumTypeExtention.cs b/Infrastructure/Extensions/EnumTypeExtention.cs new file mode 100644 index 0000000..c618530 --- /dev/null +++ b/Infrastructure/Extensions/EnumTypeExtention.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Infrastructure.Extensions +{ + public static class EnumTypeExtention + { + + public static T GetEnumByName(this string name) + { + foreach (var memberInfo in typeof(T).GetMembers()) + { + foreach (var attr in memberInfo.GetCustomAttributes(true)) + { + var test = attr as DisplayAttribute; + + if (test == null) continue; + + if (test.Name == name) + { + var result = (T)Enum.Parse(typeof(T), memberInfo.Name); + + return result; + } + } + } + + return default(T); + } + + public static string GetEnumName(this T type, Enum enm) where T : Type + { + foreach (var memberInfo in type.GetMembers()) + { + foreach (var attr in memberInfo.GetCustomAttributes(true)) + { + var test = attr as DisplayAttribute; + + if (test == null) continue; + + if (memberInfo.Name == enm.ToString()) + { + return test.Name; + } + } + } + + return null; + } + + public static string GetDescription(this Enum val) + { + var field = val.GetType().GetField(val.ToString()); + var customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)); + if (customAttribute == null) { return val.ToString(); } + else { return ((DescriptionAttribute)customAttribute).Description; } + } + + } +} diff --git a/Infrastructure/Extensions/ExtensionsJson.cs b/Infrastructure/Extensions/ExtensionsJson.cs new file mode 100644 index 0000000..0d2901b --- /dev/null +++ b/Infrastructure/Extensions/ExtensionsJson.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json.Converters; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Infrastructure.Extensions +{ + public static class ExtensionsJson + { + //public static string ToJson(this object obj) + //{ + // IsoDateTimeConverter isoDateTimeConverter = new IsoDateTimeConverter + // { + // DateTimeFormat = "yyyy-MM-dd HH:mm:ss" + // }; + // return JsonConvert.SerializeObject(obj, isoDateTimeConverter); + //} + } +} diff --git a/Infrastructure/Extensions/GenericExtension.cs b/Infrastructure/Extensions/GenericExtension.cs new file mode 100644 index 0000000..8b9f20a --- /dev/null +++ b/Infrastructure/Extensions/GenericExtension.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace Infrastructure.Extensions +{ + /// + /// 泛型扩展 + /// + public static class GenericExtension + { + public static bool Equal(this T x, T y) + { + return ((IComparable)(x)).CompareTo(y) == 0; + } + + #region ToDictionary + /// + /// 将实体指定的字段写入字典 + /// + /// + /// + /// + /// + + public static Dictionary ToDictionary(this T t, Expression> expression) where T : class + { + Dictionary dic = new Dictionary(); + string[] fields = expression.GetExpressionToArray(); + PropertyInfo[] properties = expression == null ? t.GetType().GetProperties() : t.GetType().GetProperties().Where(x => fields.Contains(x.Name)).ToArray(); + + foreach (var property in properties) + { + var value = property.GetValue(t, null); + dic.Add(property.Name, value != null ? value.ToString() : ""); + } + return dic; + } + + public static Dictionary ToDictionary(this TInterface t, Dictionary dic = null) where T : class, TInterface + { + if (dic == null) + dic = new Dictionary(); + var properties = typeof(T).GetProperties(); + foreach (var property in properties) + { + var value = property.GetValue(t, null); + if (value == null) continue; + dic.Add(property.Name, value != null ? value.ToString() : ""); + } + return dic; + } + + #endregion + + + public static DataTable ToDataTable(this IEnumerable source, Expression> columns = null, bool contianKey = true) + { + DataTable dtReturn = new DataTable(); + if (source == null) return dtReturn; + + PropertyInfo[] oProps = typeof(T).GetProperties() + .Where(x => x.PropertyType.Name != "List`1").ToArray(); + if (columns != null) + { + string[] columnArray = columns.GetExpressionToArray(); + oProps = oProps.Where(x => columnArray.Contains(x.Name)).ToArray(); + } + //移除自增主键 + PropertyInfo keyType = oProps.GetKeyProperty();// oProps.GetKeyProperty()?.PropertyType; + if (!contianKey && keyType != null && (keyType.PropertyType == typeof(int) || keyType.PropertyType == typeof(long))) + { + oProps = oProps.Where(x => x.Name != keyType.Name).ToArray(); + } + + foreach (var pi in oProps) + { + var colType = pi.PropertyType; + + if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) + { + colType = colType.GetGenericArguments()[0]; + } + + dtReturn.Columns.Add(new DataColumn(pi.Name, colType)); + } + foreach (var rec in source) + { + var dr = dtReturn.NewRow(); + foreach (var pi in oProps) + { + dr[pi.Name] = pi.GetValue(rec, null) == null + ? DBNull.Value + : pi.GetValue + (rec, null); + } + dtReturn.Rows.Add(dr); + } + return dtReturn; + } + } +} diff --git a/Infrastructure/Extensions/LambdaExtensions.cs b/Infrastructure/Extensions/LambdaExtensions.cs new file mode 100644 index 0000000..5de78e6 --- /dev/null +++ b/Infrastructure/Extensions/LambdaExtensions.cs @@ -0,0 +1,504 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + using Infrastructure.Const; + + namespace Infrastructure.Extensions +{ + public static class LambdaExtensions + { + /// + /// 分页查询 + /// + /// + /// + /// + /// + /// + public static IQueryable TakePage(this IQueryable queryable, int page, int size = 15) + { + return queryable.TakeOrderByPage(page, size); + } + /// + /// 分页查询 + /// + /// + /// + /// + /// + /// + /// + public static IQueryable TakeOrderByPage(this IQueryable queryable, int page, int size = 15, Expression>> orderBy = null) + { + if (page <= 0) + { + page = 1; + } + return Queryable.Take(Queryable.Skip(queryable.GetIQueryableOrderBy(orderBy.GetExpressionToDic()), (page - 1) * size), size); + } + + /// + /// 创建lambda表达式:p=>true + /// + /// + /// + public static Expression> True() + { + return p => true; + } + + /// + /// 创建lambda表达式:p=>false + /// + /// + /// + public static Expression> False() + { + + return p => false; + } + + public static ParameterExpression GetExpressionParameter(this Type type) + { + + return Expression.Parameter(type, "p"); + } + /// + /// 创建lambda表达式:p=>p.propertyName + /// + /// + /// + /// + /// + public static Expression> GetExpression(this string propertyName) + { + return propertyName.GetExpression(typeof(T).GetExpressionParameter()); + } + /// + /// 创建委托有返回值的表达式:p=>p.propertyName + /// + /// + /// + /// + /// + public static Func GetFun(this string propertyName) + { + return propertyName.GetExpression(typeof(T).GetExpressionParameter()).Compile(); + } + + /// + /// 创建lambda表达式:p=>false + /// 在已知TKey字段类型时,如动态排序OrderBy(x=>x.ID)会用到此功能,返回的就是x=>x.ID + /// Expression> expression = x => x.CreateDate;指定了类型 + /// + /// + /// + public static Expression> GetExpression(this string propertyName, ParameterExpression parameter) + { + if (typeof(TKey).Name == "Object") + return Expression.Lambda>(Expression.Convert(Expression.Property(parameter, propertyName), typeof(object)), parameter); + return Expression.Lambda>(Expression.Property(parameter, propertyName), parameter); + } + /// + /// 创建lambda表达式:p=>false + /// object不能确认字段类型(datetime,int,string),如动态排序OrderBy(x=>x.ID)会用到此功能,返回的就是x=>x.ID + /// Expression> expression = x => x.CreateDate;任意类型的字段 + /// + /// + /// + public static Expression> GetExpression(this string propertyName) + { + return propertyName.GetExpression(typeof(T).GetExpressionParameter()); + } + + public static Expression> GetExpression(this string propertyName, ParameterExpression parameter) + { + return Expression.Lambda>(Expression.Convert(Expression.Property(parameter, propertyName), typeof(object)), parameter); + } + + + + /// + /// + /// + /// + /// 字段名 + /// 表达式的值 + /// 创建表达式的类型,如:p=>p.propertyName != propertyValue + /// p=>p.propertyName.Contains(propertyValue) + /// + public static Expression> CreateExpression(this string propertyName, object propertyValue, LinqExpressionType expressionType) + { + return propertyName.CreateExpression(propertyValue, null, expressionType); + } + + /// + /// + /// + /// + /// 字段名 + /// 表达式的值 + /// 创建表达式的类型,如:p=>p.propertyName != propertyValue + /// p=>p.propertyName.Contains(propertyValue) + /// + private static Expression> CreateExpression( + this string propertyName, + object propertyValue, + ParameterExpression parameter, + LinqExpressionType expressionType) + { + Type proType = typeof(T).GetProperty(propertyName).PropertyType; + //创建节点变量如p=>的节点p + // parameter ??= Expression.Parameter(typeof(T), "p");//创建参数p + parameter = parameter ?? Expression.Parameter(typeof(T), "p"); + + //创建节点的属性p=>p.name 属性name + MemberExpression memberProperty = Expression.PropertyOrField(parameter, propertyName); + if (expressionType == LinqExpressionType.In) + { + if (!(propertyValue is System.Collections.IList list) || list.Count == 0) throw new Exception("属性值类型不正确"); + + bool isStringValue = true; + List objList = new List(); + + if (proType.ToString() != "System.String") + { + isStringValue = false; + foreach (var value in list) + { + objList.Add(value.ToString().ChangeType(proType)); + } + list = objList; + } + + if (isStringValue) + { + //string 类型的字段,如果值带有'单引号,EF会默认变成''两个单引号 + MethodInfo method = typeof(System.Collections.IList).GetMethod("Contains"); + //创建集合常量并设置为常量的值 + ConstantExpression constantCollection = Expression.Constant(list); + //创建一个表示调用带参数的方法的:new string[]{"1","a"}.Contains("a"); + MethodCallExpression methodCall = Expression.Call(constantCollection, method, memberProperty); + return Expression.Lambda>(methodCall, parameter); + } + //非string字段,按上面方式处理报异常Null TypeMapping in Sql Tree + BinaryExpression body = null; + foreach (var value in list) + { + ConstantExpression constantExpression = Expression.Constant(value); + UnaryExpression unaryExpression = Expression.Convert(memberProperty, constantExpression.Type); + + body = body == null + ? Expression.Equal(unaryExpression, constantExpression) + : Expression.OrElse(body, Expression.Equal(unaryExpression, constantExpression)); + } + return Expression.Lambda>(body, parameter); + } + + // object value = propertyValue; + ConstantExpression constant = proType.ToString() == "System.String" + ? Expression.Constant(propertyValue) : Expression.Constant(propertyValue.ToString().ChangeType(proType)); + + UnaryExpression member = Expression.Convert(memberProperty, constant.Type); + Expression> expression; + switch (expressionType) + { + //p=>p.propertyName == propertyValue + case LinqExpressionType.Equal: + expression = Expression.Lambda>(Expression.Equal(member, constant), parameter); + break; + //p=>p.propertyName != propertyValue + case LinqExpressionType.NotEqual: + expression = Expression.Lambda>(Expression.NotEqual(member, constant), parameter); + break; + // p => p.propertyName > propertyValue + case LinqExpressionType.GreaterThan: + expression = Expression.Lambda>(Expression.GreaterThan(member, constant), parameter); + break; + // p => p.propertyName < propertyValue + case LinqExpressionType.LessThan: + expression = Expression.Lambda>(Expression.LessThan(member, constant), parameter); + break; + // p => p.propertyName >= propertyValue + case LinqExpressionType.ThanOrEqual: + expression = Expression.Lambda>(Expression.GreaterThanOrEqual(member, constant), parameter); + break; + // p => p.propertyName <= propertyValue + case LinqExpressionType.LessThanOrEqual: + expression = Expression.Lambda>(Expression.LessThanOrEqual(member, constant), parameter); + break; + // p => p.propertyName.Contains(propertyValue) + // p => !p.propertyName.Contains(propertyValue) + case LinqExpressionType.Contains: + case LinqExpressionType.NotContains: + MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); + constant = Expression.Constant(propertyValue, typeof(string)); + if (expressionType == LinqExpressionType.Contains) + { + expression = Expression.Lambda>(Expression.Call(member, method, constant), parameter); + } + else + { + expression = Expression.Lambda>(Expression.Not(Expression.Call(member, method, constant)), parameter); + } + break; + default: + // p => p.false + expression = False(); + break; + } + return expression; + } + + /// + /// 表达式转换成KeyValList(主要用于多字段排序,并且多个字段的排序规则不一样) + /// 如有多个字段进行排序,参数格式为 + /// Expression>> orderBy = x => new Dictionary() { + /// { x.ID, true }, + /// { x.DestWarehouseName, true } + /// }; + /// 返回的是new Dictionary(){{}}key为排序字段,bool为升降序 + /// + /// + /// + /// + public static IEnumerable> GetExpressionToPair(this Expression>> expression) + { + + foreach (var exp in ((ListInitExpression)expression.Body).Initializers) + { + yield return new KeyValuePair( + exp.Arguments[0] is MemberExpression ? + (exp.Arguments[0] as MemberExpression).Member.Name.ToString() + : ((exp.Arguments[0] as UnaryExpression).Operand as MemberExpression).Member.Name, + (QueryOrderBy)((exp.Arguments[1] as ConstantExpression).Value)); + } + } + + + /// + /// 表达式转换成KeyValList(主要用于多字段排序,并且多个字段的排序规则不一样) + /// 如有多个字段进行排序,参数格式为 + /// Expression>> orderBy = x => new Dictionary() { + /// { x.ID, QueryOrderBy.Desc }, + /// { x.DestWarehouseName, QueryOrderBy.Asc } + /// }; + /// 返回的是new Dictionary(){{}}key为排序字段,QueryOrderBy为排序方式 + /// + /// + /// + /// + public static Dictionary GetExpressionToDic(this Expression>> expression) + { + return expression.GetExpressionToPair().Reverse().ToList().ToDictionary(x => x.Key, x => x.Value); + } + /// + /// 解析多字段排序 + /// + /// + /// + /// string=排序的字段,bool=true降序/false升序 + /// + public static IQueryable GetIQueryableOrderBy(this IQueryable queryable, Dictionary orderBySelector) + { + string[] orderByKeys = orderBySelector.Select(x => x.Key).ToArray(); + if (orderByKeys == null || orderByKeys.Length == 0) return queryable; + + IOrderedQueryable queryableOrderBy = null; + // string orderByKey = orderByKeys[^1]; + string orderByKey = orderByKeys[orderByKeys.Length-1]; + queryableOrderBy = orderBySelector[orderByKey] == QueryOrderBy.Desc + ? queryableOrderBy = queryable.OrderByDescending(orderByKey.GetExpression()) + : queryable.OrderBy(orderByKey.GetExpression()); + + for (int i = orderByKeys.Length - 2; i >= 0; i--) + { + queryableOrderBy = orderBySelector[orderByKeys[i]] == QueryOrderBy.Desc + ? queryableOrderBy.ThenByDescending(orderByKeys[i].GetExpression()) + : queryableOrderBy.ThenBy(orderByKeys[i].GetExpression()); + } + return queryableOrderBy; + } + + /// + /// 获取对象表达式指定属性的值 + /// 如获取:Out_Scheduling对象的ID或基他字段 + /// + /// + /// 格式 Expression>sch=x=>new {x.v1,x.v2} or x=>x.v1 解析里面的值返回为数组 + /// + public static string[] GetExpressionToArray(this Expression> expression) + { + string[] propertyNames = null; + if (expression.Body is MemberExpression) + { + propertyNames = new string[] { ((MemberExpression)expression.Body).Member.Name }; + } + else + { + propertyNames = expression.GetExpressionProperty().Distinct().ToArray(); + } + return propertyNames; + } + + /// + /// 与下面and生成方式有所不同,如果直接用表达式1.2进行合并产会提示数据源不同的异常,只能使用下面的的and合并 + /// 此种合并是在使用的同一个数据源(变量),生成的sql语句同样有性能问题(本身可以索引扫描的,生成的sql语句的case when变成索引查找) + /// + /// 通过字段动态生成where and /or表达 + /// 如:有多个where条件,当条件成立时where 1=1 and/or 2=2,依次往后拼接 + /// + /// + /// + /// ExpressionParameters + /// 1、Field生成的字段 + /// 2、ExpressionType 表达式类型大于、小于、于大=、小于=、contains + /// 3、Value表达式的值 + /// + /// + public static Expression> And(List listExpress) + { + return listExpress.Compose(Expression.And); + } + /// + /// 同上面and用法相同 + /// + /// + /// + /// + public static Expression> Or(this List listExpress) + { + return listExpress.Compose(Expression.Or); + } + private static Expression> Compose(this List listExpress, Func merge) + { + ParameterExpression parameter = Expression.Parameter(typeof(T), "p"); + Expression> expression = null; + foreach (ExpressionParameters exp in listExpress) + { + if (expression == null) + { + expression = exp.Field.GetExpression(parameter); + } + else + { + expression = expression.Compose(exp.Field.GetExpression(parameter), merge); + } + } + return expression; + } + /// + /// https://blogs.msdn.microsoft.com/meek/2008/05/02/linq-to-entities-combining-predicates/ + /// 表达式合并(合并生产的sql语句有性能问题) + /// 合并两个where条件,如:多个查询条件时,判断条件成立才where + /// + /// + /// + /// + /// + public static Expression> And(this Expression> first, Expression> second) + { + return first.Compose(second, Expression.And); + } + public static Expression> Or(this Expression> first, Expression> second) + { + return first.Compose(second, Expression.Or); + } + public static Expression Compose(this Expression first, Expression second, Func merge) + { + // build parameter map (from parameters of second to parameters of first) + var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f); + // replace parameters in the second lambda expression with parameters from the first + var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body); + // apply composition of lambda expression bodies to parameters from the first expression + return Expression.Lambda(merge(first.Body, secondBody), first.Parameters); + } + + public static IQueryable GetQueryableSelect(this IQueryable queryable) + { + Expression> expression = CreateMemberInitExpression(); + return queryable.Select(expression); + } + + /// + /// 动态创建表达式Expression> expression = CreateMemberInitExpression(); + ///结果为Expression> expression1 = x => new User() { Age = x.Age, Species = x.Species }; + ///参照文档https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions.memberinitexpression?redirectedfrom=MSDN&view=netframework-4.8 + /// + /// + /// + /// + public static Expression> CreateMemberInitExpression(Type resultType = null) + { + resultType = resultType ?? typeof(Result); + ParameterExpression left = Expression.Parameter(typeof(Source), "p"); + NewExpression newExpression = Expression.New(resultType); + PropertyInfo[] propertyInfos = resultType.GetProperties(); + List memberBindings = new List(); + foreach (PropertyInfo propertyInfo in propertyInfos) + { + MemberExpression member = Expression.Property(left, propertyInfo.Name); + MemberBinding speciesMemberBinding = Expression.Bind(resultType.GetMember(propertyInfo.Name)[0], member); + memberBindings.Add(speciesMemberBinding); + } + MemberInitExpression memberInitExpression = Expression.MemberInit(newExpression, memberBindings); + Expression> expression = Expression.Lambda>(memberInitExpression, new ParameterExpression[] { left }); + return expression; + } + public static Expression> CreateMemberInitExpression(Type resultType) + { + return CreateMemberInitExpression(resultType); + } + /// + /// 属性判断待完 + /// + /// + /// + public static IEnumerable GetGenericProperties(this Type type) + { + return type.GetProperties().GetGenericProperties(); + } + /// + /// 属性判断待完 + /// + /// + /// + public static IEnumerable GetGenericProperties(this IEnumerable properties) + { + return properties.Where(x => !x.PropertyType.IsGenericType && x.PropertyType.GetInterface("IList") == null || x.PropertyType.GetInterface("IEnumerable", false) == null); + } + } + + public class ExpressionParameters + { + public string Field { get; set; } + public LinqExpressionType ExpressionType { get; set; } + public object Value { get; set; } + // public + } + public class ParameterRebinder : ExpressionVisitor + { + + private readonly Dictionary map; + public ParameterRebinder(Dictionary map) + { + this.map = map ?? new Dictionary(); + } + + public static Expression ReplaceParameters(Dictionary map, Expression exp) + { + return new ParameterRebinder(map).Visit(exp); + } + protected override Expression VisitParameter(ParameterExpression p) + { + ParameterExpression replacement; + if (map.TryGetValue(p, out replacement)) + { + p = replacement; + } + return base.VisitParameter(p); + } + } +} diff --git a/Infrastructure/Extensions/ObjectExtension.cs b/Infrastructure/Extensions/ObjectExtension.cs new file mode 100644 index 0000000..6f55cfe --- /dev/null +++ b/Infrastructure/Extensions/ObjectExtension.cs @@ -0,0 +1,1490 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Web; +using System.Xml; +using System.Xml.Linq; + +namespace Infrastructure.Extensions +{ + + public static class ObjectExtension + { + + public static bool DicKeyIsNullOrEmpty(this Dictionary dic, string key) + { + if (dic == null) + return true; + if (!dic.ContainsKey(key)) return true; + object value = dic[key]; + if (value == null || value.ToString() == "") + { + return true; + } + return false; + } + public static Dictionary ReaderToDictionary(this IDataReader Reader) + { + List> rowList = Reader.ReaderToDictionaryList(); + return rowList.Count() > 0 ? rowList[0] : null; + } + /// + /// IDataReader转换成DictionaryList + /// + /// + /// + public static List> ReaderToDictionaryList(this IDataReader Reader) + { + List> rowList = new List>(); + try + { + while (Reader.Read()) + { + Dictionary row = new Dictionary(StringComparer.OrdinalIgnoreCase); + for (var fieldCount = 0; fieldCount < Reader.FieldCount; fieldCount++) + { + row.Add(Reader.GetName(fieldCount), Reader[fieldCount]); + } + rowList.Add(row); + } + } + catch (Exception ex) { throw ex; } + finally + { + Reader.Close(); + Reader.Dispose(); + } + return rowList; + } + + public static T DicToEntity(this Dictionary dic) + { + return new List>() { dic }.DicToList().ToList()[0]; + } + public static List DicToList(this List> dicList) + { + return dicList.DicToIEnumerable().ToList(); + } + public static object DicToList(this List> dicList, Type type) + { + return typeof(ObjectExtension).GetMethod("DicToList") + .MakeGenericMethod(new Type[] { type }) + .Invoke(typeof(ObjectExtension), new object[] { dicList }); + } + + public static IEnumerable DicToIEnumerable(this List> dicList) + { + foreach (Dictionary dic in dicList) + { + T model = Activator.CreateInstance(); + foreach (PropertyInfo property in model.GetType() + .GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)) + { + if (!dic.TryGetValue(property.Name, out object value)) continue; + property.SetValue(model, value?.ToString().ChangeType(property.PropertyType), null); + } + yield return model; + } + } + /// + /// IDataReader转换成List + /// + /// + /// + /// + public static List ReaderToList(this IDataReader Reader) + { + List objectField = new List(Reader.FieldCount); + for (int i = 0; i < Reader.FieldCount; i++) + { + objectField.Add(Reader.GetName(i).ToLower()); + } + List objectList = new List(); + try + { + while (Reader.Read()) + { + T model = Activator.CreateInstance(); + foreach (PropertyInfo property in model.GetType() + .GetProperties(BindingFlags.GetProperty + | BindingFlags.Public + | BindingFlags.Instance)) + { + if (!objectField.Contains(property.Name.ToLower())) { continue; } + if (StringExtension.IsNullOrEmpty(Reader[property.Name])) { continue; } + property.SetValue(model, Reader[property.Name].ToString().ChangeType(property.PropertyType), null); + } + objectList.Add(model); + } + } + catch (Exception ex) + { + + throw ex; + } + finally + { + Reader.Close(); + Reader.Dispose(); + } + return objectList; + } + + // + // public static object ChangeType(this object convertibleValue, Type type) + // { + // if (null == convertibleValue) return null; + // + // try + // { + // if (type == typeof(Guid) || type == typeof(Guid?)) + // { + // string value = convertibleValue.ToString(); + // if (value == "") return null; + // return Guid.Parse(value); + // } + // + // if (!type.IsGenericType) return Convert.ChangeType(convertibleValue, type); + // if (type.ToString() == "System.Nullable`1[System.Boolean]" || type.ToString() == "System.Boolean") + // { + // if (convertibleValue.ToString() == "0") + // return false; + // return true; + // } + // Type genericTypeDefinition = type.GetGenericTypeDefinition(); + // if (genericTypeDefinition == typeof(Nullable<>)) + // { + // return Convert.ChangeType(convertibleValue, Nullable.GetUnderlyingType(type)); + // } + // } + // catch + // { + // return null; + // } + // return null; + // } + + + /// + /// 将集合转换为数据集。 + /// + /// 转换的元素类型。 + /// 集合。 + /// 是否生成泛型数据集。 + /// 数据集。 + public static DataSet ToDataSet(this IEnumerable list, bool generic = true) + { + return ListToDataSet(list, generic); + } + + /// + /// 将集合转换为数据集。 + /// + /// 集合。 + /// 是否生成泛型数据集。 + /// 数据集。 + public static DataSet ToDataSet(this IEnumerable list, bool generic = true) + { + return ListToDataSet(list, generic); + } + + /// + /// 将集合转换为数据集。 + /// + /// 转换的元素类型。 + /// 集合。 + /// 是否生成泛型数据集。 + /// 数据集。 + public static DataSet ToDataSet(this IEnumerable list, bool generic = true) + { + return ListToDataSet(list, typeof(T), generic); + } + + /// + /// 将实例转换为集合数据集。 + /// + /// 实例类型。 + /// 实例。 + /// 是否生成泛型数据集。 + /// 数据集。 + public static DataSet ToListSet(this T o, bool generic = true) + { + if (o is IEnumerable) + { + return ListToDataSet(o as IEnumerable, generic); + } + else + { + return ListToDataSet(new T[] { o }, generic); + } + } + + /// + /// 将可序列化实例转换为XmlDocument。 + /// + /// 实例类型。 + /// 实例。 + /// XmlDocument。 + public static XmlDocument ToXmlDocument(this T o) + { + XmlDocument xmlDocument = new XmlDocument + { + InnerXml = o.ToListSet().GetXml() + }; + return xmlDocument; + } + + /// + /// 将集合转换为数据集。 + /// + /// 集合。 + /// 转换的元素类型。 + /// 是否生成泛型数据集。 + /// 转换后的数据集。 + private static DataSet ListToDataSet(IEnumerable list, Type t, bool generic) + { + DataSet ds = new DataSet("Data"); + if (t == null) + { + if (list != null) + { + foreach (var i in list) + { + if (i == null) + { + continue; + } + t = i.GetType(); + break; + } + } + if (t == null) + { + return ds; + } + } + ds.Tables.Add(t.Name); + //如果集合中元素为DataSet扩展涉及到的基本类型时,进行特殊转换。 + if (t.IsValueType || t == typeof(string)) + { + ds.Tables[0].TableName = "Info"; + ds.Tables[0].Columns.Add(t.Name); + if (list != null) + { + foreach (var i in list) + { + DataRow addRow = ds.Tables[0].NewRow(); + addRow[t.Name] = i; + ds.Tables[0].Rows.Add(addRow); + } + } + return ds; + } + //处理模型的字段和属性。 + var fields = t.GetFields(); + var properties = t.GetProperties(); + foreach (var j in fields) + { + if (!ds.Tables[0].Columns.Contains(j.Name)) + { + if (generic) + { + ds.Tables[0].Columns.Add(j.Name, j.FieldType); + } + else + { + ds.Tables[0].Columns.Add(j.Name); + } + } + } + foreach (var j in properties) + { + if (!ds.Tables[0].Columns.Contains(j.Name)) + { + if (generic) + { + ds.Tables[0].Columns.Add(j.Name, j.PropertyType); + } + else + { + ds.Tables[0].Columns.Add(j.Name); + } + } + } + if (list == null) + { + return ds; + } + //读取list中元素的值。 + foreach (var i in list) + { + if (i == null) + { + continue; + } + DataRow addRow = ds.Tables[0].NewRow(); + foreach (var j in fields) + { + MemberExpression field = Expression.Field(Expression.Constant(i), j.Name); + LambdaExpression lambda = Expression.Lambda(field, new ParameterExpression[] { }); + Delegate func = lambda.Compile(); + object value = func.DynamicInvoke(); + addRow[j.Name] = value; + } + foreach (var j in properties) + { + MemberExpression property = Expression.Property(Expression.Constant(i), j); + LambdaExpression lambda = Expression.Lambda(property, new ParameterExpression[] { }); + Delegate func = lambda.Compile(); + object value = func.DynamicInvoke(); + addRow[j.Name] = value; + } + ds.Tables[0].Rows.Add(addRow); + } + return ds; + } + + /// + /// 将集合转换为数据集。 + /// + /// 转换的元素类型。 + /// 集合。 + /// 是否生成泛型数据集。 + /// 数据集。 + private static DataSet ListToDataSet(IEnumerable list, bool generic) + { + return ListToDataSet(list, typeof(T), generic); + } + + /// + /// 将集合转换为数据集。 + /// + /// 集合。 + /// 是否转换为字符串形式。 + /// 转换后的数据集。 + private static DataSet ListToDataSet(IEnumerable list, bool generic) + { + return ListToDataSet(list, null, generic); + } + + /// + /// 获取DataSet第一表,第一行,第一列的值。 + /// + /// DataSet数据集。 + /// 值。 + public static object GetData(this DataSet ds) + { + if ( + ds == null + || ds.Tables.Count == 0 + ) + { + return string.Empty; + } + else + { + return ds.Tables[0].GetData(); + } + } + + /// + /// 获取DataTable第一行,第一列的值。 + /// + /// DataTable数据集表。 + /// 值。 + public static object GetData(this DataTable dt) + { + if ( + dt.Columns.Count == 0 + || dt.Rows.Count == 0 + ) + { + return string.Empty; + } + else + { + return dt.Rows[0][0]; + } + } + + /// + /// 获取DataSet第一个匹配columnName的值。 + /// + /// 数据集。 + /// 列名。 + /// 值。 + public static object GetData(this DataSet ds, string columnName) + { + if ( + ds == null + || ds.Tables.Count == 0 + ) + { + return string.Empty; + } + foreach (DataTable dt in ds.Tables) + { + object o = dt.GetData(columnName); + if (!string.IsNullOrEmpty(o.ToString())) + { + return o; + } + } + return string.Empty; + } + + /// + /// 获取DataTable第一个匹配columnName的值。 + /// + /// 数据表。 + /// 列名。 + /// 值。 + public static object GetData(this DataTable dt, string columnName) + { + if (string.IsNullOrEmpty(columnName)) + { + return GetData(dt); + } + if ( + dt.Columns.Count == 0 + || dt.Columns.IndexOf(columnName) == -1 + || dt.Rows.Count == 0 + ) + { + return string.Empty; + } + return dt.Rows[0][columnName]; + } + + /// + /// 将object转换为string类型信息。 + /// + /// object。 + /// 默认值。 + /// string。 + public static string ToString(this object o, string t) + { + string info = string.Empty; + if (o == null) + { + info = t; + } + else + { + info = o.ToString(); + } + return info; + } + + /// + /// 将DateTime?转换为string类型信息。 + /// + /// DateTime?。 + /// 标准或自定义日期和时间格式的字符串。 + /// 默认值。 + /// string。 + public static string ToString(this DateTime? o, string format, string t) + { + string info = string.Empty; + if (o == null) + { + info = t; + } + else + { + info = o.Value.ToString(format); + } + return info; + } + + /// + /// 将TimeSpan?转换为string类型信息。 + /// + /// TimeSpan?。 + /// 标准或自定义时间格式的字符串。 + /// 默认值。 + /// string。 + public static string ToString(this TimeSpan? o, string format, string t) + { + string info = string.Empty; + if (o == null) + { + info = t; + } + else + { + info = o.Value.ToString(format); + } + return info; + } + + + + /// + /// 将object转换为byte类型信息。 + /// + /// object。 + /// 默认值。 + /// byte。 + public static byte ToByte(this object o, byte t = default(byte)) + { + if (!byte.TryParse(o.ToString(string.Empty), out byte info)) + { + info = t; + } + return info; + } + + public static byte[] ToBytes(this object obj) + { + if (obj == null) + return null; + var bf = new BinaryFormatter(); + using (var ms = new MemoryStream()) + { + bf.Serialize(ms, obj); + return ms.ToArray(); + } + } + + public static object ToObject(this byte[] source) + { + using (var memStream = new MemoryStream()) + { + var bf = new BinaryFormatter(); + memStream.Write(source, 0, source.Length); + memStream.Seek(0, SeekOrigin.Begin); + var obj = bf.Deserialize(memStream); + return obj; + } + } + + /// + /// 将object转换为char类型信息。 + /// + /// object。 + /// 默认值。 + /// char。 + public static char ToChar(this object o, char t = default(char)) + { + if (!char.TryParse(o.ToString(string.Empty), out char info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为int类型信息。 + /// + /// object。 + /// 默认值。 + /// int。 + public static int ToInt(this object o, int t = default(int)) + { + if (!int.TryParse(o.ToString(string.Empty), out int info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为double类型信息。 + /// + /// object。 + /// 默认值。 + /// double。 + public static double ToDouble(this object o, double t = default(double)) + { + double info; + if (!double.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为decimal类型信息。 + /// + /// object。 + /// 默认值。 + /// decimal。 + public static decimal ToDecimal(this object o, decimal t = default(decimal)) + { + decimal info; + if (!decimal.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为float类型信息。 + /// + /// object。 + /// 默认值。 + /// float。 + public static float ToFloat(this object o, float t = default(float)) + { + if (!float.TryParse(o.ToString(string.Empty), out float info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为long类型信息。 + /// + /// object。 + /// 默认值。 + /// long。 + public static long ToLong(this object o, long t = default(long)) + { + long info; + if (!long.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为bool类型信息。 + /// + /// object。 + /// 默认值。 + /// bool。 + public static bool ToBool(this object o, bool t = default(bool)) + { + bool info; + if (!bool.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为sbyte类型信息。 + /// + /// object。 + /// 默认值。 + /// sbyte。 + public static sbyte ToSbyte(this object o, sbyte t = default(sbyte)) + { + sbyte info; + if (!sbyte.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为short类型信息。 + /// + /// object。 + /// 默认值。 + /// short。 + public static short ToShort(this object o, short t = default(short)) + { + short info; + if (!short.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为ushort类型信息。 + /// + /// object。 + /// 默认值。 + /// ushort。 + public static ushort ToUShort(this object o, ushort t = default(ushort)) + { + ushort info; + if (!ushort.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为ulong类型信息。 + /// + /// object。 + /// 默认值。 + /// ulong。 + public static ulong ToULong(this object o, ulong t = default(ulong)) + { + ulong info; + if (!ulong.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为Enum[T]类型信息。 + /// + /// object。 + /// 默认值。 + /// Enum[T]。 + public static T ToEnum(this object o, T t = default(T)) + where T : struct + { + if (!System.Enum.TryParse(o.ToString(string.Empty), out T info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为DateTime类型信息。 + /// + /// object。 + /// 默认值。 + /// DateTime。 + public static DateTime ToDateTime(this object o, DateTime t = default(DateTime)) + { + if (t == default(DateTime)) + { + t = new DateTime(1753, 1, 1); + } + DateTime info; + if (!DateTime.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为TimeSpan类型信息。 + /// + /// object。 + /// 默认值。 + /// TimeSpan。 + public static TimeSpan ToTimeSpan(this object o, TimeSpan t = default(TimeSpan)) + { + if (t == default(TimeSpan)) + { + t = new TimeSpan(0, 0, 0); + } + TimeSpan info; + if (!TimeSpan.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + /// + /// 将object转换为Guid类型信息。 + /// + /// object。 + /// 默认值。 + /// Guid。 + public static Guid ToGuid(this object o, Guid t = default(Guid)) + { + Guid info; + if (!Guid.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + return info; + } + + private static Regex BoolRegex = new Regex("(?(true|false))", RegexOptions.IgnoreCase | RegexOptions.Singleline); + + /// + /// 从object中获取bool类型信息。 + /// + /// object。 + /// bool。 + public static bool GetBool(this string value) + { + bool.TryParse(value, out bool result); + return result; + } + + private static Regex IntRegex = new Regex("(?-?\\d+)", RegexOptions.IgnoreCase | RegexOptions.Singleline); + + + + private static Regex DecimalRegex = new Regex("(?-?\\d+(\\.\\d+)?)", RegexOptions.IgnoreCase | RegexOptions.Singleline); + + /// + /// 从object中获取decimal类型信息。 + /// + /// object。 + /// decimal。 + public static decimal? GetDecimal(this object o) + { + decimal info; + if (!decimal.TryParse(DecimalRegex.Match(o.ToString(string.Empty)).Groups["info"].Value, out info)) + { + return null; + } + return info; + } + + + + /// + /// 从object中获取正数信息。 + /// + /// object。 + /// decimal。 + public static decimal? GetPositiveNumber(this object o) + { + decimal info; + if (!decimal.TryParse(DecimalRegex.Match(o.ToString(string.Empty)).Groups["info"].Value, out info)) + { + return null; + } + return Math.Abs(info); + } + + private static Regex DateTimeRegex = new Regex("(?(((\\d+)[/年-](0?[13578]|1[02])[/月-](3[01]|[12]\\d|0?\\d)[日]?)|((\\d+)[/年-](0?[469]|11)[/月-](30|[12]\\d|0?\\d)[日]?)|((\\d+)[/年-]0?2[/月-](2[0-8]|1\\d|0?\\d)[日]?))(\\s((2[0-3]|[0-1]\\d)):[0-5]\\d:[0-5]\\d)?)", RegexOptions.IgnoreCase | RegexOptions.Singleline); + + /// + /// 从object中获取DateTime?类型信息。 + /// + /// object。 + /// DateTime?。 + public static DateTime? GetDateTime1(this object o) + { + DateTime info; + if (!DateTime.TryParse(DateTimeRegex.Match(o.ToString(string.Empty)).Groups["info"].Value.Replace("年", "-").Replace("月", "-").Replace("/", "-").Replace("日", ""), out info)) + { + return null; + } + return info; + } + + private static Regex TimeSpanRegex = new Regex("(?-?(\\d+\\.(([0-1]\\d)|(2[0-3])):[0-5]\\d:[0-5]\\d)|((([0-1]\\d)|(2[0-3])):[0-5]\\d:[0-5]\\d)|(\\d+))", RegexOptions.IgnoreCase | RegexOptions.Singleline); + + /// + /// 从object中获取TimeSpan?类型信息。 + /// + /// object。 + /// TimeSpan?。 + public static TimeSpan? GetTimeSpan(this object o) + { + TimeSpan info; + if (!TimeSpan.TryParse(TimeSpanRegex.Match(o.ToString(string.Empty)).Groups["info"].Value, out info)) + { + return null; + } + return info; + } + + private static Regex GuidRegex = new Regex("(?\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})", RegexOptions.IgnoreCase | RegexOptions.Singleline); + + /// + /// 从object中获取Guid?类型信息。 + /// + /// object。 + /// Guid?。 + public static Guid? GetGuid(this object o) + { + Guid info; + if (!Guid.TryParse(GuidRegex.Match(o.ToString(string.Empty)).Groups["info"].Value, out info)) + { + return null; + } + return info; + } + + /// + /// 将object转换为SqlServer中的DateTime?类型信息。 + /// + /// object。 + /// 默认值。 + /// DateTime?。 + public static DateTime? GetSqlDateTime(this object o, DateTime t = default(DateTime)) + { + DateTime info; + if (!DateTime.TryParse(o.ToString(string.Empty), out info)) + { + info = t; + } + if (info < new DateTime(1753, 1, 1) || info > new DateTime(9999, 12, 31)) + { + return null; + } + return info; + } + + /// + /// 读取XElement节点的文本内容。 + /// + /// XElement节点。 + /// 默认值。 + /// 文本内容。 + public static string Value(this XElement xElement, string t = default(string)) + { + if (xElement == null) + { + return t; + } + else + { + return xElement.Value; + } + } + + /// + /// 获取与指定键相关的值。 + /// + /// 键类型。 + /// 值类型。 + /// 表示键/值对象的泛型集合。 + /// 键。 + /// 默认值。 + /// 值。 + public static TValue GetValue(this IDictionary dictionary, TKey key, TValue t = default(TValue)) + { + TValue value = default(TValue); + if (dictionary == null || key == null) + { + return t; + } + if (!dictionary.TryGetValue(key, out value)) + { + value = t; + } + return value; + } + + /// + /// 获取与指定键相关或者第一个的值。 + /// + /// 键类型。 + /// 值类型。 + /// 表示键/值对象的泛型集合。 + /// 键。 + /// 默认值。 + /// 值。 + public static TValue GetFirstOrDefaultValue(this IDictionary dictionary, TKey key, TValue t = default(TValue)) + { + TValue value = default(TValue); + if (dictionary == null || key == null) + { + return t; + } + if (!dictionary.TryGetValue(key, out value)) + { + if (dictionary.Count() == 0) + { + value = t; + } + else + { + value = dictionary.FirstOrDefault().Value; + } + } + return value; + } + + /// + /// 获取具有指定 System.Xml.Linq.XName 的第一个(按文档顺序)子元素。 + /// + /// XContainer。 + /// 要匹配的 System.Xml.Linq.XName。 + /// 是否返回同名默认值。 + /// 与指定 System.Xml.Linq.XName 匹配的 System.Xml.Linq.XElement,或者为 null。 + public static XElement Element(this XContainer xContainer, XName xName, bool t) + { + XElement info; + if (xContainer == null) + { + info = null; + } + else + { + info = xContainer.Element(xName); + } + if (t && info == null) + { + info = new XElement(xName); + } + return info; + } + + /// + /// 按文档顺序返回此元素或文档的子元素集合。 + /// + /// XContainer。 + /// 是否返回非空默认值。 + /// System.Xml.Linq.XElement 的按文档顺序包含此System.Xml.Linq.XContainer 的子元素,或者非空默认值。 + public static IEnumerable Elements(this XContainer xContainer, bool t) + { + IEnumerable info; + if (xContainer == null) + { + info = null; + } + else + { + info = xContainer.Elements(); + } + if (t && info == null) + { + info = new List(); + } + return info; + } + + /// + /// 按文档顺序返回此元素或文档的经过筛选的子元素集合。集合中只包括具有匹配 System.Xml.Linq.XName 的元素。 + /// + /// XContainer。 + /// 要匹配的 System.Xml.Linq.XName。 + /// 是否返回非空默认值。 + /// System.Xml.Linq.XElement 的按文档顺序包含具有匹配System.Xml.Linq.XName 的 System.Xml.Linq.XContainer 的子级,或者非空默认值。 + public static IEnumerable Elements(this XContainer xContainer, XName xName, bool t) + { + IEnumerable info; + if (xContainer == null) + { + info = null; + } + else + { + info = xContainer.Elements(xName); + } + if (t && info == null) + { + info = new List(); + } + return info; + } + + /// + /// 删除html标签。 + /// + /// 输入的字符串。 + /// 没有html标签的字符串。 + public static string RemoveHTMLTags(this string html) + { + return Regex.Replace(Regex.Replace(Regex.Replace((html ?? string.Empty).Replace(" ", " ").Replace("\r\n", " ").Replace("\n", " ").Replace("\r", " ").Replace("\t", " "), "<\\/?[^>]+>", "\r\n"), "(\r\n)+", "\r\n"), "(\\s)+", " ").Trim(); + } + + /// + /// 字符串转换为文件名。 + /// + /// 字符串。 + /// 文件名。 + public static string ToFileName(this string s) + { + return Regex.Replace(s.ToString(string.Empty), @"[\\/:*?<>|]", "_").Replace("\t", " ").Replace("\r\n", " ").Replace("\"", " "); + } + + + /// + /// 获取默认非空字符串。 + /// + /// 首选默认非空字符串。 + /// 依次非空字符串可选项。 + /// 默认非空字符串。若无可选项则返回string.Empty。 + public static string DefaultStringIfEmpty(this string s, params string[] args) + { + if (string.IsNullOrEmpty(s)) + { + return string.Empty; + } + foreach (string i in args) + { + if (!string.IsNullOrEmpty(i) && !string.IsNullOrEmpty(i.Trim())) + { + return i; + } + } + + return (s ?? string.Empty); + } + + /// + /// 对 URL 字符串进行编码。 + /// + /// 要编码的文本。 + /// 匹配要编码的文本。 + /// 指定编码方案的 System.Text.Encoding 对象。 + /// 一个已编码的字符串。 + public static string ToUrlEncodeString(this string s, Regex regex = default(Regex), Encoding encoding = null) + { + if (encoding == null) + { + encoding = Encoding.UTF8; + } + if (regex == null) + { + return HttpUtility.UrlEncode(s, encoding); + } + List l = new List(); + foreach (char i in s) + { + string t = i.ToString(); + l.Add(regex.IsMatch(t) ? HttpUtility.UrlEncode(t, encoding) : t); + } + return string.Join(string.Empty, l); + } + + /// + /// 对 URL 字符串进行编码。 + /// + /// 要编码的文本。 + /// 匹配要编码的文本。 + /// 指定编码方案的 System.Text.Encoding 对象。 + /// 一个已编码的字符串。 + public static string ToUrlEncodeString(this string s, string regex, Encoding encoding = null) + { + return ToUrlEncodeString(s, new Regex(regex), encoding); + } + + /// + /// 将日期转换为UNIX时间戳字符串 + /// + /// + /// + public static string ToUnixTimeStamp(this DateTime date) + { + DateTime startTime = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1)); + string timeStamp = date.Subtract(startTime).Ticks.ToString(); + return timeStamp.Substring(0, timeStamp.Length - 7); + } + + private static readonly Regex MobileRegex = new Regex("^1[3|4|5|7|8][0-9]\\d{4,8}$"); + private static readonly Regex EmailRegex = new Regex("^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\\.[a-zA-Z0-9_-]{2,3}){1,2})$"); + + /// + /// 判断当前字符串是否是移动电话号码 + /// + /// + /// + public static bool IsMobile(this string mobile) + { + return MobileRegex.IsMatch(mobile); + } + + /// + /// 判断当前字符串是否为邮箱 + /// + /// + /// + public static bool IsEmail(this string email) + { + return EmailRegex.IsMatch(email); + } + + + /// + /// 将 DateTimeOffset 转换成 DateTime + /// + /// + /// + public static DateTime ConvertToDateTime(this DateTimeOffset dateTime) + { + if (dateTime.Offset.Equals(TimeSpan.Zero)) + return dateTime.UtcDateTime; + else if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))) + return DateTime.SpecifyKind(dateTime.DateTime, DateTimeKind.Local); + else + return dateTime.DateTime; + } + + /// + /// 将 DateTime 转换成 DateTimeOffset + /// + /// + /// + public static DateTimeOffset ConvertToDateTimeOffset(this DateTime dateTime) + { + return DateTime.SpecifyKind(dateTime, DateTimeKind.Local); + } + + /// + /// 判断是否是富基元类型 + /// + /// 类型 + /// + internal static bool IsRichPrimitive(this Type type) + { + // 处理元组类型 + if (type.IsValueTuple()) return false; + + // 处理数组类型,基元数组类型也可以是基元类型 + if (type.IsArray) return type.GetElementType().IsRichPrimitive(); + + // 基元类型或值类型或字符串类型 + if (type.IsPrimitive || type.IsValueType || type == typeof(string)) return true; + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) return type.GenericTypeArguments[0].IsRichPrimitive(); + + return false; + } + + /// + /// 合并两个字典 + /// + /// + /// 字典 + /// 新字典 + /// + internal static Dictionary AddOrUpdate(this Dictionary dic, Dictionary newDic) + { + foreach (var key in newDic.Keys) + { + if (dic.ContainsKey(key)) + dic[key] = newDic[key]; + else + dic.Add(key, newDic[key]); + } + + return dic; + } + + /// + /// 判断是否是元组类型 + /// + /// 类型 + /// + internal static bool IsValueTuple(this Type type) + { + return type.ToString().StartsWith(typeof(ValueTuple).FullName); + } + + /// + /// 判断方法是否是异步 + /// + /// 方法 + /// + internal static bool IsAsync(this MethodInfo method) + { + return method.ReturnType.IsAsync(); + } + + /// + /// 判断类型是否是异步类型 + /// + /// + /// + internal static bool IsAsync(this Type type) + { + return type.ToString().StartsWith(typeof(Task).FullName); + } + + /// + /// 判断类型是否实现某个泛型 + /// + /// 类型 + /// 泛型类型 + /// bool + internal static bool HasImplementedRawGeneric(this Type type, Type generic) + { + // 检查接口类型 + var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType); + if (isTheRawGenericType) return true; + + // 检查类型 + while (type != null && type != typeof(object)) + { + isTheRawGenericType = IsTheRawGenericType(type); + if (isTheRawGenericType) return true; + type = type.BaseType; + } + + return false; + + // 判断逻辑 + bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type); + } + + /// + /// 判断是否是匿名类型 + /// + /// 对象 + /// + internal static bool IsAnonymous(this object obj) + { + var type = obj.GetType(); + + return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false) + && type.IsGenericType && type.Name.Contains("AnonymousType") + && (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$")) + && type.Attributes.HasFlag(TypeAttributes.NotPublic); + } + + /// + /// 获取所有祖先类型 + /// + /// + /// + internal static IEnumerable GetAncestorTypes(this Type type) + { + var ancestorTypes = new List(); + while (type != null && type != typeof(object)) + { + if (IsNoObjectBaseType(type)) + { + var baseType = type.BaseType; + ancestorTypes.Add(baseType); + type = baseType; + } + else break; + } + + return ancestorTypes; + + static bool IsNoObjectBaseType(Type type) => type.BaseType != typeof(object); + } + + /// + /// 获取方法真实返回类型 + /// + /// + /// + internal static Type GetRealReturnType(this MethodInfo method) + { + // 判断是否是异步方法 + var isAsyncMethod = method.IsAsync(); + + // 获取类型返回值并处理 Task 和 Task 类型返回值 + var returnType = method.ReturnType; + return isAsyncMethod ? (returnType.GenericTypeArguments.FirstOrDefault() ?? typeof(void)) : returnType; + } + + /// + /// 首字母大写 + /// + /// + /// + internal static string ToTitleCase(this string str) + { + return Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(str); + } + + /// + /// 将一个对象转换为指定类型 + /// + /// + /// + /// + internal static T ChangeType(this object obj) + { + return (T)ChangeType(obj, typeof(T)); + } + + /// + /// 将一个对象转换为指定类型 + /// + /// 待转换的对象 + /// 目标类型 + /// 转换后的对象 + internal static object ChangeType(this object obj, Type type) + { + if (type == null) return obj; + if (obj == null) return type.IsValueType ? Activator.CreateInstance(type) : null; + + var underlyingType = Nullable.GetUnderlyingType(type); + if (type.IsAssignableFrom(obj.GetType())) return obj; + else if ((underlyingType ?? type).IsEnum) + { + if (underlyingType != null && string.IsNullOrWhiteSpace(obj.ToString())) return null; + else return Enum.Parse(underlyingType ?? type, obj.ToString()); + } + // 处理DateTime -> DateTimeOffset 类型 + else if (obj.GetType().Equals(typeof(DateTime)) && (underlyingType ?? type).Equals(typeof(DateTimeOffset))) + { + return ((DateTime)obj).ConvertToDateTimeOffset(); + } + // 处理 DateTimeOffset -> DateTime 类型 + else if (obj.GetType().Equals(typeof(DateTimeOffset)) && (underlyingType ?? type).Equals(typeof(DateTime))) + { + return ((DateTimeOffset)obj).ConvertToDateTime(); + } + else if (typeof(IConvertible).IsAssignableFrom(underlyingType ?? type)) + { + try + { + return Convert.ChangeType(obj, underlyingType ?? type, null); + } + catch + { + return underlyingType == null ? Activator.CreateInstance(type) : null; + } + } + else + { + var converter = TypeDescriptor.GetConverter(type); + if (converter.CanConvertFrom(obj.GetType())) return converter.ConvertFrom(obj); + + var constructor = type.GetConstructor(Type.EmptyTypes); + if (constructor != null) + { + var o = constructor.Invoke(null); + var propertys = type.GetProperties(); + var oldType = obj.GetType(); + + foreach (var property in propertys) + { + var p = oldType.GetProperty(property.Name); + if (property.CanWrite && p != null && p.CanRead) + { + property.SetValue(o, ChangeType(p.GetValue(obj, null), property.PropertyType), null); + } + } + return o; + } + } + return obj; + } + + } + + + + /// + /// 标记。 + /// + public enum Flag + { + /// + /// 默认。 + /// + Default, + + /// + /// 真。 + /// + True, + + /// + /// 假。 + /// + False + } +} diff --git a/Infrastructure/Extensions/SecurityEncDecryptExtension.cs b/Infrastructure/Extensions/SecurityEncDecryptExtension.cs new file mode 100644 index 0000000..80efa8c --- /dev/null +++ b/Infrastructure/Extensions/SecurityEncDecryptExtension.cs @@ -0,0 +1,86 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace Infrastructure.Extensions +{ + public static class SecurityEncDecryptExtensions + { + private static byte[] Keys = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; + /// + /// DES加密字符串 + /// + /// 待加密的字符串 + /// 加密密钥,要求为16位 + /// 加密成功返回加密后的字符串,失败返回源串 + + public static string EncryptDES(this string encryptString, string encryptKey) + { + try + { + byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 16)); + byte[] rgbIV = Keys; + byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString); + + using (var DCSP = DES.Create()) + { + using (MemoryStream mStream = new MemoryStream()) + { + using (CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write)) + { + cStream.Write(inputByteArray, 0, inputByteArray.Length); + cStream.FlushFinalBlock(); + return Convert.ToBase64String(mStream.ToArray()).Replace('+', '_').Replace('/', '~'); + } + } + } + } + catch (Exception ex) + { + throw new Exception("密码加密异常" + ex.Message); + } + } + + /// + /// DES解密字符串 + /// + /// 待解密的字符串 + /// 解密密钥,要求为16位,和加密密钥相同 + /// 解密成功返回解密后的字符串,失败返源串 + + public static string DecryptDES(this string decryptString, string decryptKey) + { + byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey.Substring(0, 16)); + byte[] rgbIV = Keys; + byte[] inputByteArray = Convert.FromBase64String(decryptString.Replace('_', '+').Replace('~', '/')); + using (var DCSP = DES.Create()) + { + using (MemoryStream mStream = new MemoryStream()) + { + using (CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write)) + { + byte[] inputByteArrays = new byte[inputByteArray.Length]; + cStream.Write(inputByteArray, 0, inputByteArray.Length); + cStream.FlushFinalBlock(); + return Encoding.UTF8.GetString(mStream.ToArray()); + } + } + } + } + + public static bool TryDecryptDES(this string decryptString, string decryptKey, out string result) + { + result = ""; + try + { + result = DecryptDES(decryptString, decryptKey); + return true; + } + catch + { + return false; + } + } + } +} \ No newline at end of file diff --git a/Infrastructure/Extensions/ServerExtension.cs b/Infrastructure/Extensions/ServerExtension.cs new file mode 100644 index 0000000..844fcf8 --- /dev/null +++ b/Infrastructure/Extensions/ServerExtension.cs @@ -0,0 +1,28 @@ +using Infrastructure.Extensions.AutofacManager; +using Infrastructure.Provider; + +namespace Infrastructure.Extensions +{ + public static class ServerExtension + { + /// + /// 返回的路径后面不带/,拼接时需要自己加上/ + /// + /// + /// + public static string MapPath(this string path) + { + return MapPath(path, false); + } + /// + /// + /// + /// + /// 获取wwwroot路径 + /// + public static string MapPath(this string path,bool rootPath) + { + return AutofacContainerModule.GetService().MapPath(path,rootPath); + } + } +} diff --git a/Infrastructure/Extensions/StringExtension.cs b/Infrastructure/Extensions/StringExtension.cs new file mode 100644 index 0000000..6663277 --- /dev/null +++ b/Infrastructure/Extensions/StringExtension.cs @@ -0,0 +1,867 @@ +using System; +using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; +using Infrastructure.Const; +using Microsoft.International.Converters.PinYinConverter; + +namespace Infrastructure.Extensions +{ + public static class StringExtension + { + public static bool _windows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + /// + /// 自动调整windows/linux下面文件目录斜杠的处理 + /// + /// + /// + public static string ReplacePath(this string path) + { + if (string.IsNullOrEmpty(path)) + return ""; + if (_windows) + return path.Replace("/", "\\"); + return path.Replace("\\", "/"); + + } + + /// + /// 把一个字符串转成驼峰规则的字符串 + /// + /// + /// + public static string ToCamelCase(this string str) + { + if(!string.IsNullOrEmpty(str) && str.Length > 1) + { + return Char.ToLowerInvariant(str[0]) + str.Substring(1); + } + return str; + } + + private static DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0); + + private static long longTime = 621355968000000000; + + private static int samllTime = 10000000; + /// + /// 获取时间戳 + /// + /// + /// + public static long GetTimeStamp(this DateTime dateTime) + { + return (dateTime.ToUniversalTime().Ticks - longTime) / samllTime; + } + /// + /// 时间戳转换成日期 + /// + /// + /// + public static DateTime GetTimeSpmpToDate(this object timeStamp) + { + if (timeStamp == null) return dateStart; + DateTime dateTime = new DateTime(longTime + Convert.ToInt64(timeStamp) * samllTime, DateTimeKind.Utc).ToLocalTime(); + return dateTime; + } + + + public static bool IsUrl(this string str) + { + if (string.IsNullOrEmpty(str)) + return false; + string Url = @"(http://)?([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?"; + return Regex.IsMatch(str, Url); + + } + /// + /// 判断是不是正确的手机号码 + /// + /// + /// + public static bool IsPhoneNo(this string input) + { + if (string.IsNullOrEmpty(input)) + return false; + if (input.Length != 11) + return false; + + if (new Regex(@"^1[3578][01379]\d{8}$").IsMatch(input) + || new Regex(@"^1[34578][01256]\d{8}").IsMatch(input) + || new Regex(@"^(1[012345678]\d{8}|1[345678][0123456789]\d{8})$").IsMatch(input) + ) + return true; + return false; + } + + public static string GetDBCondition(this string stringType) + { + string reslut = ""; + switch (stringType?.ToLower()) + { + case HtmlElementType.droplist: + case HtmlElementType.selectlist: + case HtmlElementType.textarea: + case HtmlElementType.checkbox: + reslut = HtmlElementType.Contains; + break; + case HtmlElementType.thanorequal: + reslut = HtmlElementType.ThanOrEqual; + break; + case HtmlElementType.lessorequal: + reslut = HtmlElementType.LessOrequal; + break; + case HtmlElementType.gt: + reslut = HtmlElementType.GT; + break; + case HtmlElementType.lt: + reslut = HtmlElementType.lt; + break; + case HtmlElementType.like: + reslut = HtmlElementType.like; + break; + default: + reslut = HtmlElementType.Equal; + break; + } + return reslut; + } + + public static LinqExpressionType GetLinqCondition(this string stringType) + { + LinqExpressionType linqExpression; + switch (stringType) + { + case HtmlElementType.Contains: + linqExpression = LinqExpressionType.In; + break; + case HtmlElementType.ThanOrEqual: + linqExpression = LinqExpressionType.ThanOrEqual; + break; + case HtmlElementType.LessOrequal: + linqExpression = LinqExpressionType.LessThanOrEqual; + break; + case HtmlElementType.GT: + linqExpression = LinqExpressionType.GreaterThan; + break; + case HtmlElementType.lt: + linqExpression = LinqExpressionType.LessThan; + break; + case HtmlElementType.like: + linqExpression = LinqExpressionType.Contains; + break; + default: + linqExpression = LinqExpressionType.Equal; + break; + } + return linqExpression; + } + + public static bool GetGuid(this string guid, out Guid outId) + { + Guid emptyId = Guid.Empty; + return Guid.TryParse(guid, out outId); + } + + public static bool IsGuid(this string guid) + { + Guid newId; + return GetGuid(guid, out newId); + } + + public static bool IsInt(this object obj) + { + if (obj == null) + return false; + bool reslut = Int32.TryParse(obj.ToString(), out int _number); + return reslut; + + } + public static bool IsDate(this object str) + { + return IsDate(str, out _); + } + public static bool IsDate(this object str, out DateTime dateTime) + { + dateTime = DateTime.Now; + if (str == null || str.ToString() == "") + { + return false; + } + return DateTime.TryParse(str.ToString(), out dateTime); + } + /// + /// 根据传入格式判断是否为小数 + /// + /// + /// 18,5 + /// + public static bool IsNumber(this string str, string formatString) + { + if (string.IsNullOrEmpty(str)) + return false; + int precision = 32; + int scale = 5; + try + { + if (string.IsNullOrEmpty(formatString)) + { + precision = 10; + scale = 2; + } + else + { + string[] numbers = formatString.Split(','); + precision = Convert.ToInt32(numbers[0]); + scale = numbers.Length == 0 ? 2 : Convert.ToInt32(numbers[1]); + } + } + catch { }; + return IsNumber(str, precision, scale); + } + /**/ + /// + /// 判断一个字符串是否为合法数字(指定整数位数和小数位数) + /// + /// 字符串 + /// 整数位数 + /// 小数位数 + /// + public static bool IsNumber(this string str, int precision, int scale) + { + if ((precision == 0) && (scale == 0)) + { + return false; + } + string pattern = @"(^\d{1," + precision + "}"; + if (scale > 0) + { + pattern += @"\.\d{0," + scale + "}$)|" + pattern; + } + pattern += "$)"; + return Regex.IsMatch(str, pattern); + } + + + public static bool IsNullOrEmpty(this object str) + { + if (str == null) + return true; + return str.ToString() == ""; + } + + + public static int GetInt(this object obj) + { + if (obj == null) + return 0; + int.TryParse(obj.ToString(), out int _number); + return _number; + + } + + /// + /// 获取 object 中的枚举值 + /// + /// + /// + /// + public static long GetLong(this object obj) + { + if (obj == null) + return 0; + + try + { + return Convert.ToInt64(Convert.ToDouble(obj)); + } + catch + { + return 0; + } + } + + /// + /// 获取 object 中的 float + /// + /// + /// + + public static float GetFloat(this object obj) + { + if (System.DBNull.Value.Equals(obj) || null == obj) + return 0; + + try + { + return float.Parse(obj.ToString()); + } + catch + { + return 0; + } + } + + public static double GetDouble(this object obj) + { + if (System.DBNull.Value.Equals(obj) || null == obj) + return 0; + + try + { + return Convert.ToDouble(obj); + } + catch + { + return 0; + } + } + /// + /// 获取 object 中的 decimal + /// + /// + /// + /// + public static decimal GetDecimal(this object obj) + { + if (System.DBNull.Value.Equals(obj) || null == obj) + return 0; + + try + { + return Convert.ToDecimal(obj); + } + catch + { + return 0; + } + } + + /// + /// 获取 object 中的 decimal + /// + /// + /// + /// + public static dynamic GetDynamic(this object obj) + { + if (System.DBNull.Value.Equals(obj) || null == obj) + return null; + + try + { + string str = obj.ToString(); + if (IsNumber(str, 25, 15)) return Convert.ToDecimal(obj); + else return str; + } + catch + { + return string.Empty; + } + } + + public static DateTime? GetDateTime(this object obj) + { + if (System.DBNull.Value.Equals(obj) || null == obj) + return null; + bool result = DateTime.TryParse(obj.ToString(), out DateTime dateTime); + if (!result) + return null; + return dateTime; + } + + + + public static object ParseTo(this string str, string type) + { + switch (type) + { + case "System.Boolean": + return ToBoolean(str); + case "System.SByte": + return ToSByte(str); + case "System.Byte": + return ToByte(str); + case "System.UInt16": + return ToUInt16(str); + case "System.Int16": + return ToInt16(str); + case "System.uInt32": + return ToUInt32(str); + case "System.Int32": + return ToInt32(str); + case "System.UInt64": + return ToUInt64(str); + case "System.Int64": + return ToInt64(str); + case "System.Single": + return ToSingle(str); + case "System.Double": + return ToDouble(str); + case "System.Decimal": + return ToDecimal(str); + case "System.DateTime": + return ToDateTime(str); + case "System.Guid": + return ToGuid(str); + } + throw new NotSupportedException(string.Format("The string of \"{0}\" can not be parsed to {1}", str, type)); + } + + public static sbyte? ToSByte(this string value) + { + sbyte value2; + if (sbyte.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static byte? ToByte(this string value) + { + byte value2; + if (byte.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static ushort? ToUInt16(this string value) + { + ushort value2; + if (ushort.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static short? ToInt16(this string value) + { + if (short.TryParse(value, out short value2)) + { + return value2; + } + return null; + } + + public static uint? ToUInt32(this string value) + { + uint value2; + if (uint.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static ulong? ToUInt64(this string value) + { + ulong value2; + if (ulong.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static long? ToInt64(this string value) + { + long value2; + if (long.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static float? ToSingle(this string value) + { + float value2; + if (float.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static double? ToDouble(this string value) + { + double value2; + if (double.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static decimal? ToDecimal(this string value) + { + decimal value2; + if (decimal.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static bool? ToBoolean(this string value) + { + bool value2; + if (bool.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + + + public static Guid? ToGuid(this string str) + { + Guid value; + if (Guid.TryParse(str, out value)) + { + return value; + } + return null; + } + + public static DateTime? ToDateTime(this string value) + { + DateTime value2; + if (DateTime.TryParse(value, out value2)) + { + return value2; + } + return null; + } + + public static int? ToInt32(this string input) + { + if (string.IsNullOrEmpty(input)) + { + return null; + } + int value; + if (int.TryParse(input, out value)) + { + return value; + } + return null; + } + + /// + /// 替换空格字符 + /// + /// + /// 替换为该字符 + /// 替换后的字符串 + public static string ReplaceWhitespace(this string input, string replacement = "") + { + return string.IsNullOrEmpty(input) ? null : Regex.Replace(input, "\\s", replacement, RegexOptions.Compiled); + } + + private static char[] randomConstant ={ + '0','1','2','3','4','5','6','7','8','9', + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' + }; + /// + /// 生成指定长度的随机数 + /// + /// + /// + public static string GenerateRandomNumber(this int length) + { + System.Text.StringBuilder newRandom = new System.Text.StringBuilder(62); + Random rd = new Random(); + for (int i = 0; i < length; i++) + { + newRandom.Append(randomConstant[rd.Next(62)]); + } + return newRandom.ToString(); + } + public static string MaxSubstring(this string origin, int maxLength) + { + return origin.Length >= maxLength ? origin.Substring(0, maxLength) : origin; + } + + public static string ToMd5(this string origin) + { + if (string.IsNullOrWhiteSpace(origin)) + { + return string.Empty; + } + + var md5Algorithm = MD5.Create(); + var utf8Bytes = Encoding.UTF8.GetBytes(origin); + var md5Hash = md5Algorithm.ComputeHash(utf8Bytes); + var hexString = new StringBuilder(); + foreach (var hexByte in md5Hash) + { + hexString.Append(hexByte.ToString("x2")); + } + return hexString.ToString(); + } + + + // + // 摘要: + // 把汉字转换成拼音(全拼) + // + // 参数: + // text: + // 汉字字符串 + // + // 返回结果: + // 转换后的拼音(全拼)字符串 + public static string ConvertPinYin(string text) + { + string text2 = string.Empty; + for (int i = 0; i < text.Length; i++) + { + char ch = text[i]; + try + { + ChineseChar chineseChar = new ChineseChar(ch); + if (chineseChar.Pinyins.Count > 0 && chineseChar.Pinyins[0].Length > 0) + { + string text3 = chineseChar.Pinyins[0].ToString(); + text2 += text3.Substring(0, text3.Length - 1); + } + } + catch (Exception) + { + text2 += ch; + } + } + + return text2; + } + + + // + // 摘要: + // 获取汉字的拼音简码,即首字母缩写,范例:中国,返回zg + // + // 参数: + // chineseText: + // 汉字文本,范例: 中国 + public static string PinYin(string chineseText) + { + if (string.IsNullOrWhiteSpace(chineseText)) + { + return string.Empty; + } + + StringBuilder stringBuilder = new StringBuilder(); + foreach (char text in chineseText) + { + stringBuilder.AppendFormat("{0}", ResolvePinYin(text)); + } + + return stringBuilder.ToString().ToLower(); + } + + // + // 摘要: + // 解析单个汉字的拼音简码 + // + // 参数: + // text: + // 单个汉字 + private static string ResolvePinYin(char text) + { + byte[] bytes = Encoding.Default.GetBytes(text.ToString()); + if (bytes[0] <= 127) + { + return text.ToString(); + } + + ushort unicode = (ushort)(bytes[0] * 256 + bytes[1]); + string text2 = ResolvePinYinByCode(unicode); + if (!string.IsNullOrWhiteSpace(text2)) + { + return text2; + } + + return ResolvePinYinByFile(text.ToString()); + } + + + // + // 摘要: + // 使用字符编码方式获取拼音简码 + private static string ResolvePinYinByCode(ushort unicode) + { + if (unicode >= 45217 && unicode <= 45252) + { + return "A"; + } + + if (unicode >= 45253 && unicode <= 45760 && unicode != 45464) + { + return "B"; + } + + if (unicode >= 45761 && unicode <= 46317) + { + return "C"; + } + + if (unicode >= 46318 && unicode <= 46825) + { + return "D"; + } + + if (unicode >= 46826 && unicode <= 47009) + { + return "E"; + } + + if (unicode >= 47010 && unicode <= 47296) + { + return "F"; + } + + if (unicode >= 47297 && unicode <= 47613) + { + return "G"; + } + + if (unicode >= 47614 && unicode <= 48118) + { + return "H"; + } + + if (unicode >= 48119 && unicode <= 49061) + { + return "J"; + } + + if (unicode >= 49062 && unicode <= 49323) + { + return "K"; + } + + if (unicode >= 49324 && unicode <= 49895) + { + return "L"; + } + + if (unicode >= 49896 && unicode <= 50370) + { + return "M"; + } + + if (unicode >= 50371 && unicode <= 50613) + { + return "N"; + } + + if (unicode >= 50614 && unicode <= 50621) + { + return "O"; + } + + if (unicode >= 50622 && unicode <= 50905) + { + return "P"; + } + + if (unicode >= 50906 && unicode <= 51386) + { + return "Q"; + } + + if (unicode >= 51387 && unicode <= 51445) + { + return "R"; + } + + if (unicode >= 51446 && unicode <= 52217) + { + return "S"; + } + + if (unicode >= 52218 && unicode <= 52697) + { + return "T"; + } + + if (unicode >= 52698 && unicode <= 52979) + { + return "W"; + } + + if (unicode >= 52980 && unicode <= 53640) + { + return "X"; + } + + if (unicode >= 53689 && unicode <= 54480) + { + return "Y"; + } + + if (unicode >= 54481 && unicode <= 55289) + { + return "Z"; + } + + return string.Empty; + } + + + // + // 摘要: + // 从拼音简码文件获取 + // + // 参数: + // text: + // 单个汉字 + public static string ResolvePinYinByFile(string text) + { + int num = "丂k丄s丅x丆m丏m丒c丗s丢d丠q両l丣y并b丩j丮j丯j丱g丳c丵z丷b丼j乀f乁y讈l乆j乑y乕h乗c乚h乛w乢g乣j乤h乧d乨s乪n乫g乬g乭d乮m乯o乲c乴x乵y乶p乷s乸n乹q乺s乻e乼z乽z乿z亀g亁q乱l亃l亄y亅j亇m亊s亐y亖s亗s亘g亜y亝q亚y亣d亪y亯x亰j亱y亴y亶d亷l亸d亹m亼j亽j亾w仈b仌b仏f仐j仒e仚x仛t仜h仢b仦c仧c仩c仭r仮f仯c仱q仴w仸y仹f仺c仼w仾d伀z伂p伃y伄d伅d伆w伇y伈x汲j伌a伒j伓p伔d伖t伜c伝y伡c伣q伨x伩x伬c伭x伮n伱n伳x伵x伷z伹q伻b伾p伿z佀s佁a佄h佅m伫z布b佉q佊b佋z佌c佒y占z佖b佡x佢q佦s佨b徊h佫h佭x佮g佱f佲m佷h佸h佺q佽c侁s侂t侅g来l侇y侊g侌y侎m侐x侒a侓l侕e仑l侘c侙c侚x侜z侞r侟c価s侢d侤t侫n侭j侰j侱c侲z侳z侴h侣l局j侸s侹t侺s侻t侾x俀t俣y系j俆x俇g俈k俉w俋y俌f俍l俒h俓j俔q俕s俖p俙x俛f侠x俢x俤d俥c俧z俫l俬s俰h俲x俴j俵b俶c俷f俹y俻b俼y俽x俿h伥c倁z倂b倃j倅c俩l倇w倈l仓c倊z个g倎t倐s们m倓t倕c幸x倗p倛q倝g倞j倠s倢j仿f値z倧z伦l倯s倰l倱h倲d倳z倴b倵w倶j倷n倸c倹j倻y倽s倿n偀y偁c偂q偄r偅z偆c伟w偊y偋b偍t偐y偑f偒t偓w偔e偖c偗s偘k偙d偛c偝b偞x偠y偡z偢c偣a偦x偧z偨c偩f偪b偫z偭m偮j偯y偰x偱x偲c偳d侧c侦z偸t偹b咱z偼j伪w傁s傂z傃s傄x傆y傇r傉n傊y傋j傌m傎d傏t傐h杰j傒x傓s傔q傕j伧c傗c伞s备b傚x傛r傜y傝t傞s傟y傠f傡b家j傤z傦g傪c傫l佣y傮z偬z傰p傱s传c伛y债z伤s傹j傼h傽z倾q傿y僀d僁x偻l僃b僄b仅j僆l戮l僈m佥q僊x僋t僌y働d僎z僐s侨q僒j僓t僔z仆p僗l僘c僙g僛q僜d僝c僞w僟j僠b僡h僢c僣t僤d侥j偾f僩x僪y僫e僯l僰b雇g僲x僴x僶m僷y僸j价j僺q僼f僽z僾a僿s仪y儁j侬n儃c亿y当d侩k俭j儊c儌j儍s儎z儏c傧b儑a儓t俦c侪c儖l儗y尽j儙q儚m儛w儜n儝q儞n偿c儠l儢l儣k儤b儥y儦b儧z儨z儩s优y儫h儬q儭c儮l儯t儰w儱l储c儳c儴x儵s儶h俪l罗l儹z傩n傥t俨y儽l儾n兂z凶x兊d兑d兎t兏c児e儿e兖y兘s兟s兡b兤h兦w内n两l兪y兯h兲t兾j兿y冃m冄r円y冇m册c冋j冎g冏j冐m胄z冓g冔x冘y冚k冝y冞s冟s冡m冣z冦k冧l冨f冩x幂m冭t冮g冴y冸p冹f冺m冾q冿j凁s凂m凃t凅g净j凊q冻d凎g凐y凒a凓l凔c凕m凖z凗c凘s凙d凚j凛l凞x凟d凢f凣f凥j処c凧y凨f凩k凪n凬f凮f凯k凲g凴p凷k凾h刄r刅c刉j刋q刌c刏j刐d刓w刔j刕l刜f刞q刟d刡m刢l刣z别b刦j刧j删s刬c刯g刱c刲k刴d刵e刼j刾c刭j剅d剆l则z剈y剉c克k刹c剒c剓l剕f剗c剘q剙c剚z刚g剥b剟d剠q剢d剣j剤j剦y剨h剫d剬z剭w剐g剰s剱j剳d剀k创c剶c铲c剸t剹l剺l剻p剼s剾k劀g划h劄z劅z劆l剧j刘l刽g劋j刿g剑j劎j劏t剂j劒j劔j劕z劖c劗z劘m劙l劚z劜y劤j劥k劦x劧z劮y劯z劰m労l劵j劶k劷y劸w効x劺m匡k劼j劽l勀k劲j勂g勄m勅c勆l勈y勊k勌j勍q勎l勏b勑c勓k勔m动d勖x务w勚y勋x勜w胜s劳l勠l勡p势s积j勥j剿c勧q勨x勪q勫f勬j勭t勮j勯d劢m勲x勳x勴l励l勶c勷x劝q匀y勼j勽b匁m匂x匃g匄g匇y匉p匊j匋t匌g匎e匑g匒d匓j匔g匘n匛j匜y匞j匟k匢h匤q匥f匧q匨z匩k匫h匬y匦g汇h匰d匮k匲l匳l匴s匵d匶j匷j匸x匼k匽y区o卂x卄n卆z卋s卌x卍w卐w协x単d卙j卛s卝g卥x卨x卪j卬a卭q卲s卶c恤x却q卼w卽j卾e厀x厁s厃w厇z厈h厊y厎d厏z厐p厑y厒q厓y厔z厖m厗t厍s厛t厜z厞f厡y厤l厧d厪j厫a厬g厌y厯l厰c厱q厉l厳y厣y厵y厷g厸l厹r厺q厼k厽l厾d叀z参c叄c叅c叆a叇d収s叏g叐b叒r叓l叕z叚j叜s叝j叞w叡r丛c叧g叴q叺c叾d叿h吀m吂m吅x吇z寸c吔y吘o吙h吚y吜c吢q吤j吥b吪e吰h吴w呐n吷x吺d吽h吿g呁j吕l呄g呅w呇q呉w呌j呍h尺c呏s呑t呚h呝e呞s呟j呠p呡w呣m呥r呧d呪z呫t呬x呭y呮q呯p呰z呴g呹y呺x呾d呿q咁x咃t咅p咇b咈f咉y咊h咍h咑d咓w咗z咘b咜t咞x咟h咠q咡e咢e咥d咮z咰s咲x咵k咶g咷t咹e咺x呙g咾l哃t哅x哊y哋d哖n哘x哛p哠h员y哢l哣p哤m哫z哬h哯x哰l哱b哴l哵b哶m哸s哹f哻h哾c唀y唂g唃g呗b含h唈y唊j唋t唌d唍w唎l唒q唓c唕z唖y唗d唘q唙d唚q唜m唝g唞d唟g唡l唥l唦s唨z唩w唫j唭q唲e唴q唵a唶j念n唹y唺t唻l唽x啀a啂g啇d啈h啋c啌q啍z啎w问w啑s啒g啓q啔q啗d啘w啚b啝h哑y启q啠z啢l衔x啨q啩g啫z啯g啰l啱y啲d啳q啴c啹j啺t啽a啿d喅y喆z喌z喍c喎w喐h喒z喓y喕m喖h喗y唤h喛h喞j喠z喡w喢s喣x喤h喥d喦y喨l喩y丧s吃c乔q喭y单c喯p喰c哟y喴w営y喸p喺x喼j喿z嗀h嗁t嗂y嗃h呛q啬s嗈y嗊g嗋x吗m嗏c嗐h嗕r嗗w嗙p呜w嗛q嗞z嗠l嗢w嗧j唢s嗭z嗮s嗰g嗱n嗴q哔b嗸a嗹l嗺z嗻z嗼m嗿t嘂j嘃c嘄j嘅k叹t嘇s嘊a嘋x喽l嘐x嘑h嘒h呕o嘕x啧z尝c嘙p嘚d唛m嘝h嘠g嘡t嘢y嘥s嘦j嘨x哗h嘪m嘫r唠l啸x叽j嘳k哓x嘷h呒m嘺q嘼c嘽t嘾d噀x恶e噂z噃f噄c噅h噆z噇c噈c噉d噊j噋t噏x噐q噑h噒l嘘s噕h噖y噚x噛n噝s噞y噟y哒d噡z噣z哝n哕y噧x噭j噮y嗳a噰y哙k噳y喷p噷x吨d噺h噽p噾y噿z咛n嚁d嚂l嚃t嚄h吓h嚈y嚉d嚊x嚋z哜j嚑x嚔t噜l嚖h嚗b嚘y啮n嚚y嚛h嚜m嚝h嚞z嚟l嚠l嚡x嚢n嚤m咽y呖l嚧l咙l嚩p嚪d嚫c嚬p嚭p向x嚰m嚱x嚲d喾k严y嚵c嘤y嚸d嚹l嚺t嚻x嚽c嚾h嚿h啭z嗫n嚣a囃z冁c囆c囇l呓y囋z苏s囍x囎z囏j囐y嘱z囒l囓n囕r囖l囘h囙y囜n団t囥k囦y囧j囨p囩y囱c囬h囮e囯g囲w図t囶g囷q囸r囼t圀g圁y圂h圅h囵l国g圌c围w圎y圏q圐k圑p园y圆y圔y圕t图t圗t团t圙l圚h圛y圝l圞l圠y圡t圢t圤p圥l圦k圧y圫y圱q圲q圴z圵d圶q圷x圸s圼n圽m圿j坁z坃x坄y坅q坆m坈r坉t坋b坒b坓j坔d坕j坖j坘d坙j坢b坣t坥q坧z坬g坮t垧s坱y坲f坴l坵q坸g坹x坽l坾z坿f垁z垇a垈d垉p垊m垍j垎h垏l垐c垑c垔y垕h垖d垗z垘f垙g垚y垜d垝g垞c垟y垥x垨s垪b垬h垯d垰k垱d垳h垵a垶x垷x垹b垺p垻b垼y垽y垾h垿x埀c埁c埄b埅d埆q埇y埈j埉x埊d埌l埍j埐q埑z埓l埖h埗b埛j埜y埞d垭y埢q埣s埥q埦w埧j埨l埩z埪k埫c埬d埮t埰c埲b埳x埵d执z埻z埼q埾j埿n堁k堃k堄n坚j堈g堉y垩e堌g堎l堏f堐y堒k堓a堔s堖n堗t堘c堚h堛b堜l埚g堟z堢b堣y堥m堦j堧r堨a堩g堫z堬y堭h堮e尧y报b堲j堳m场c堶t堷y堸f堹z堺j堻j堼f堽g堾c碱j塀p塁l塂j塃h塅d塆w塇x塉j块k茔y塎y垲k塐s埘s塓m塕w塖c涂t塙q塚z塛l塜p塝b塟z塠d塡t坞w塣z埙x塦z塧a塨g塩y塪x塭w塮x塯l塰h塱l塲c塳p塴b尘c塶l塷l塸o堑q塺m塻m塼z塽s塿l墂b墄q墆z墇z墈k垫d墋c墌z墍x墎g墏q墐j墒s墔c墕y墖t増z墘q墛w坠z墝q墠s墡s墢f墣p墤k墥t墦f墧q墪d墫c墬d墭s堕d墯d墰t墱d墲w墴h墵t墶d墷y墸z墹j墺a墙q垦k墿y壀p壂d壃j壄y壆x坛t壈l壉j壊h壋d壌r壍q壏x壐x壒a压y壖r壗j垒l圹k垆l壛y壜t壝w坏h垄l壠l壡r坜l壣l壥c壦x壧y壨l坝b壪w壭s壮z壱y売m壴z壵z壷h壸k壶h壻x壼k寿s壾m壿d夀s夁y夃g夅j夆f夈z変b夊s夋q夌l夎c夐x夑x夒n夓x夗y夘w夛d夝q夞y够g夡q梦m夣m夦c夨c夬g夰g夲b夳t夵y夶b夻h夽y夹g夿b奀e奃d奅p奆j奊x奌d奍q奂h奒k奓z奙b奛h奜f奝d奞x奟b奡a奣w奤h奦w奥a奨j奁l夺d奫y奬j奭s奋f奯h奰b奱l奲d奵d奷q奺j奻n奼c奾x奿f妀j妅h妉d妋f妎h妏w妐z妑p妔k妕z妘y妚f妜y妆z妟y妠n妡x妦f妧w妬d妰z妱z你n妴y妵t妶x妷z妸e妺m妼b妽s妿e姀h姁x姂f姄m姅b姇f姈l姉z姌r姗s姎y姏g姕z姖j姙r姛d姞j姟g姠x姡h姢j姤g奸j姧j姩n侄z姫z姭x姮h姯g姰j姱h姲y姳m姴l姵p姶y姷y姸y姺x姼s姽g姾q娀s娂h娋s娍c娎x娏m娐f娒m娔k娕c娖c娗t娙x娚n娱y娝b娞n娡z娢h娤z娦p娧t娨m娪w娫y娬w娭a娮y娯y娰s娳l娵j娷s娸q娹x娺z娻d娽l娾a娿e娄l婃c婄p婅j婇c婈l婋x婌s婍q婎h婏f婐w婑w婒t婓f婔f婖t婗n婘j婙j婛j婜q婝d婞x婟h婠w婡l婣y婤z婥c妇f婨l婩a婫h婬y娅y婮j婯l婰d婱x婳h婸d婹y婻n婼c婽j婾t媀y媁w媂d媃r媄m媅d媆r媇q媈h媉w媊q媋c媌m媍f媎j媏d媐y媓h媔m媕a媖y媗x媘j媙w媜z媞t媟x媠d媢m媣r媤s媥p媦w娲w媨c媩h媫j媬b媭x媮t妫g媰c媱y媴y媶r媷r媹l媺m媻p媪a妈m媿k嫀q嫃z嫄y嫅j嫆r嫇m嫈y嫊s嫋n嫍t嫎p嫏l嫐n嫑b嫓p嫕y妪y嫙x嫚m嫛y嫝k嫞y嫟n嫢g嫤j嫥z嫧z嫨h嫪l嫬z嫭h嫮h嫯a嫰n嫲m嫳p嫴g妩w嫶q嫷t嫸z嫹m嫺x娴x嫼m嫽l嫾l嬀g嬁d嬂z嬄y嬅h嬆x嬇k娆r嬊y婵c娇j嬍m嬎f嬏f嬐x嬑y嬒h嬔f嬕s嬘s嫱q嬚l嬛h袅n嬞d嬠c嫒a嬢n嬣n嬷m嬥t嬦c嬧j嬨c嬩y嫔p嬫r嬬r嬭n嬮y嬯t婴y嬱q嬳y嬵m嬶k婶s嬹x嬺n嬻d嬼l嬽y嬾l嬿y孁l孂j娘n孄l孅x孆y孇s孈x孉h孊m孋l娈l孍y孎z孏l孖m孞x孠s孡t孧y孙s孭m孮c孯q孲y孴n孷l学x孹b孻n孼n孾y孪l宂r宆q宊t宍r宎y宐y宑j宒z宔z宖h実s宧y宨t宩s宬c宭q宫g宯x宱z宲b宷c宺h宻m宼k寀c寁z寃y寈q寉h寊z寋j寍n寎b寏h寑q寔s寕n寖j寗n寘z寙y寚b寛k寜n寠j寝q寣h实s宁n审s寪w写x宽k寭h寯j寱y寲y寳b寴q宠c宝b寷f寽l対d尀p専z尃f将j专z寻x尌s对d导d尐j尒e尓e尗s尙s尛m尞l尟x尠x尡h尣w尦l尨m尩w尪w尫w尭y尮d尯k尰z尲g尳g尵t尶g尴g屃x届j屇t屌d屍s屒z屓x屔n屖x屘m屚l屛p屉t扉f屟x屡l层c屧x屦j屩j屪l屫j属s屭x屰n屲w屳x屴l屵a屶h屷h屸h屻r屼w屽h屾s岀c岃y岄y岆y岇a岉w岊j岋e岏w岒q岓q岕j岝z岞z岠j冈g岤x岥p岦l迢t岨j岮t岯p岰a岲k岴q岶p岹t岺l岻d岼p峀x峂t峃x峅b峆h峇b峈l峉e峌d峍l峎e峏e峐g峑q峓y峔m峕s峖a峗w峘h峚m峛l峜f峝t峞w峟y峠q峢l峧j峩e峫x峬b峯f峱n峲l峳y岘x峵r岛d峷s峸c峹t峺g峼g峡x峿w崀l崁k崄x崅q崈c崉t崊l崋h崌j崃l崏m崐k崑k崒z崓g崕y岗g崘l崚l崜d崝z崟y岽d崡h峥z崣w崥p崨j崪z崫j崬d崯y崰z崱z崲h嵛y崵y崶f崷q崸y崹t崺y崻z崼s崿e嵀z嵁k嵂l嵃y嵄m嵅h嵆j嵈h嵉t嵍w嵎y嵏z岚l嵑k岩y嵓y嵔w嵕z嵖c嵗s嵙k嵚q嵜q嵞t嵟c嵠x嵡w嵢c嵣d嵤r嵥j嵦k嵧l嵨w嵪k嵭b嵮d嵰q嵱y嵲n嵳c嵵s嵶r嵷s嵸z嵹j嵺l嵻k嵼y嵾c嵿d嶀t嵝l嶃z崭z嶅a嶆c岖q嶉w嶊z嶋d嶌d嶍x嶎y嶏p嶐l嶑x嶒c嶓b嶔q嶕j嶖y崂l嶘z嶚l嶛l嶜q嶞t嶟z峤j嶡j嶢y嶣j嶤y嶥j嶦z峄y嶨x嶩n嶫y嶬y嶭n嶮x嶯j嶰x嶱k嶲g嶳d嶴a嶵z嶶w嵘r嶹d岭l嶻j屿y岳y嶾y嶿r巀j巁l巂x巃l巄l巇x巈j巉c巊y岿k巌y巎n巐c漓l峦l巓d巅d巕n巗y巘y巙k巚y巜k巟h巠j巣c巤l巪g巬p巭b巯q巵z巶z巸y卺j巺x巻j巼p巿f帀z帄d帇n帊p帋z帍h帎d帒d帓m帗f帞m帟y帠y帡p帢q帣j帤r帅s帨s帩q帪z师s帬q帯d帰g帲p帐z帴j帵w带d帹s帺q帾z帿h帧z幁z帏w幆y幇b幈p幉d幊g幋p幍t幎m幏j幐t幑h幒z幓s幖b帼g帻z幙m幚b幜j幝c帜z幠h币b幤b幦m幧q幨c蒙m帮b帱c幭m幮c幰x幱l幵j幷b干g几j庁t仄z広g庈q庉d庌y庍b庎j庒z庘y庛c庝t庡y庢z庣t庤z庨x庩t庪g库k庬m庮y庯b庰b庱c庲l庴j庻s庼q庽y庿m廀s厕c厢x廃f厩j廅e廆h廇l厦s廋s廌z廍b廎q廏j廔l廕y廗d廘l廙y厨c廜t厮s廞x庙m厂a庑w废f广a廤k廥k廦b廧q廪l廫l庐l廭j廮y廯x廰t痈y廲l厅t廵x廸d廹p廻h廼n廽h弆j弇y弉z弌y弍e弎s弑s吊d弖h弙w弚t弜j弝b弡j弢t弣f弤d弨c弫z弬y弮j弰s弲x弪j弴d张z弶j强j弸p弻b弽s弾d弿j彁g彂f彃b彄k彅j彇x弹d彉g彋h弥m彍g弯w彏j彑j彔l彚h彛y彜y彞y彟h彠h彣w彦y彧y彨c雕d彮y彯p彲c彴z彵t彶j彸z彺w彽d彾l佛f徃w徆x徍w徎c徏z径j従c徔c徖c徝z从c徟z徕l徢x徣j徤j徥s徧b复f旁p徯x徰z徱p徲t徳d徶b彻c徺j徻h徾m徿l忀x忁b忂q忈r忊d忋g忎r忓h忔y忕s忚x忛f応y忞m忟m忢w忣j忥x忦j忨w忩c忬y忯q忰c忲t忳d忴q忶h忷x忹w忺x忼k怇j怈y怉b怋m怌p怐j怑b怗t怘h怚c怞y怟d怢t怣y怤f怬x怮y怰x怲b怳h怴x怶b怷s怸x怹t怺y怽m恀s恄x恅l恒h恇k恈m恉z恊x恌y恏h恑g恓x恔x恖s恗h恘q恛h恞y恟x恠g恡l耻c恦s恮z恱y恲p恴d恵h恷q恾m悀y悁j悂p悦y悆y悇t悈j悊z悋l悎h悏q悐t悑b悓q悕x悗m悘y悙h悜c悞w悡l悢l悤c悥y悧l悩n悪e悮w悰c悳d怅c闷m悷l悹g悺g凄q悾k悿t惀l惁x惂k惃g惄n惇d惈g惉z惌y惍j惎j惏l惐y惒h惓q惔t惖t惗n啜c惛h惞x惢s惣z惤j惥y惪d恼n恽y惵d惷c惸q恻c惼b惽m惾z惿t愃x愄w愅g愇w愊b愋x愌h愐m愑y愒q愓d愔y愖c愗m愘k愙k爱a惬q愝y愞n愡c愢s愥y悫q愩g愬s愭q愮y愯s愰h愱j愳j怆c愵n愶x恺k愸z愹y愺c愻x愼s愽b忾k慀x慁h慂y栗l慅s慆t殷y慉x态t愠y慏m慐g慒c慓p慔m慖g慗c惨c惭c慛c慜m慞z恸t慠a慡s惯g慤q慥z慦j慩l怄o怂s慬q慭y虑l慯s慱t慲m悭q慴s庆q慸d慹z慺l慻j戚q慽q欲y慿p憀l憁c忧y憃c憄z憅t憆c憇q憈q惫b憌q憍j憏c怜l凭p愦k憓h憕c憖y憗y憘x憙x惮d憛t憞d憟s憠j憢x憣f愤f憥l憦l憪x悯m憭l怃w憯c憰j憱c宪x憳t憴s憵p忆y憸x憹n憺d憻t憼j憽s懀w懁x懃q懄q懅j懆s恳k应y怿y檩l懎s懐h懓a懕y懖g懗x懘c懙y懚y懛d懜m懝a怼d懠q懢l懑m懤c懥z懧n恹y懩y懪b懫z懬k懭k懮y懯f懰l懱m惩c懳h懴c懒l怀h悬x懹r忏c懻j惧j懽h慑s恋l戁n戂m戃t戄j戅g戆g钺y戓g戋j戙d戜d戝z戞j戠z戣k戦z戗q戨g戬j戫y戭y戯x战z戱x戏h户h戸h戹e戺s戻t戼m扂d扄s扅y扆y扊y扏q仂l払f扖h扗z扙z扚d扜y扝y扞h扟s叉c扡t扦q扤w扥d扨s扱c扲q扴j扵y扷b扸x抵d扻z扽d抁y抂k拚p抅j擦c抇h抈y抋q抌d抍z殒y抏w抐n抔p抙p抜b抝a択z抣y抦b抧z抩n抪p抭y抮z抰y抲h抳n曳y抶c抷p抸j抺m抾q拀z拁j拃z抛p拏n拑q拕t拝b拞d拠j拡k拤q拪q拫h拰n拵c拸y拹x拺c拻h挀b挃z挄k挅d挆d挊n挋z挍j挏d挐n挒l挓z挔l挕d挗j挘l挙j挜y挦x挧y挩t挬b挭g挮t挰c挱s挳k挴m挵n挷b挸j挻s挼r挟x挿c捀p捁j捄j捇h捈t捊p捑z捒s捓y捔j捖w捗b捘z捙y捚z捛l捜s捝t捠b捤w捥w捦q舍s捪m扪m捬f捯d捰w卷j捳y捴z捵c捸t捹b捼r捽z捾w捿q掁c扫s抡l掅q掆g掋d掍h掑q掓s掔q掕l掗y挣z掚l挂g掜y掝h掞y掟z采c掦t掫z掯k掱p掲j掵m掶j掹m掻s掽p掿n拣j揁z揂j揃j揅y揇n揈h揊p揋w揌z揑n揓s揔z揕z揗x揘h揙b扬y换h揜y揝z揟x揢k揤j揥d揦l揧l揨c揫j揬t挥h揯g揰c揱x揳x揵q揷c背b揺y揻w揼b揾w搃z搄g构g搇q搈r搉q搊c损s搎s搑r搒b搕k摇y捣d搘z搙n搚l搝q擀g搢j搣m搤e搥c搧s搨t搩j搫p搯t搰h搱z搲w搳h搵w抢q搷t搸z搹e搻n搼q搾z摂s摃g摉s摋s摌c摍s摎n摏c摐c掴g摓f摕d摗s摙l摚c摛c掼g摝l搂l摠z摡g摢h摣z摤q摥t摦h摨z摪j摫g摬y摮a挚z摰n摱m摲c抠k摴c摵s抟t摷j掺c摼k摽b摿y撀g撁q撃j撆p捞l撉d撊x撋r撌g撍z撎y撏x撑c挠n撔h撗h搭d捻n撛l撜z撝h挢j撠j撡c掸d拨b撦c撨x撪b抚f撯z撱w扑p揿q撴d撶h撹j挞t撽j挝w捡j拥y擃n掳l擆z择z擈p擉c击j挡d擌s擏q擑j擓k担d擕x擖y擙a据j擛y擜e擝m挤j擡t擥l擧j擨y擩r擪y擫y拟n擭h擮j摈b拧n搁g掷z擳z扩k擵m擶j撷x擸l擹t摆b擞s撸l擽l扰r攁y攃c摅s攅z撵n攇x攈j攊l攋l攌h攍y攎l隆l攐q攑q攓q拦l攕x撄y攗m搀c撺c携x摄s攞l攟j攠m攡c攒c挛l摊t攦l攧d攨w攩d搅j揽l攭l攰g攱g攲q攳x考k攼g攽b敀p敁d敂k敃m敄w敆h敇c敊c敋g敍x敎j敐c敒s敓d敔y败b叙x敚d敜n敟d敠d敡y敤k敥y敧q敨t敩x敪d敭y敮x敯m敱a敳a敌d敶c数s敹l敺q敻x敼y敽j敾s敿j斀z斁d敛l毙b斄l斅x斆x斈x斉q斊q斍j斎z斏l斒b斔y斓l斖w斘s斚j斝j斞y斠j斢t斣d斦y斨q斪q斩z斱z斲z斴l斵z斶c断d斸z斺c斻h斾p斿l旀m旗q旇p旈l旉f旊f旍j旐z旑y旓s旔j旕e旘z旙f旚p旛f旜z旝k旞s旟y旡j旣j旪x旫t旲t旳d旴x旵c旸y旹s旻m旼m旽t旾c旿w昁b昄b昅j升s昈h昉f昋g昍x昑q昒h昖y昗z昘f昚s昛j昜y昞b昡x昢p昣z昤l昦h昩m昪b昫x昬h昮z昰s昲f昳d昷w昸d昹a昺b昻a昽l昿k晀t时s晄h晅x晆k晈j晋j晊z晍t晎h晐g晑x晘h晙j晛x晜k昼z曦x晠s晢z晣z晥w晧h晩w晪t晫z晭z晱s晳x晵q晸z晹y晻a晼w晽l晿c暀w暁x暃f暅g暆y晕y晖h暊x暋m暍y暏s暐w暒q暓m暕j阳y暙c暚y暛s暜p暞j暟k暠g暡w畅c暣q暤h暥y暦l暩j暪m暂z暬x暯m暰c昵n暲z暳h暵h暶x暷c了l暺t暻j暼p暽l暿x曀y曁j曂h曃d晔y曅y历l昙t曈t晓x曊f曋s曍h曎y曏x曐x曑s曒j曓b曔j曕y暧a曘r曚m曞l曟c旷k曡d曣y曤h曥l曧r曨l曪l曫l晒s曭t曮y曯z曱y曵y曶h书s曺c曽z朁c朂x会g朄y朅q朇b朎l朏k朒g朓t朖l朘j朙m朚h朜t朞j朠y朡z朢w朣t朤l朥l胧l术s朰t朲r朳b朶d朷d朸l朹q朻j朼b朾c朿c杁r杄q杅y圬w杊x杋f杍z杒r杔t杕d杗m杘c杙y杚g杛g杝t杢j杣m杤w杦j杧m杫s杬y杮f东d杴x杶c杸s杹h杺x杻c杽c枀s枂w枃j枅j枆m枊a枍y枎f枏n枑h枒y枓d枔x枖y栀z枛z枟y枠h枡s枤d枦l枩s枬z枮x枱s枲x拐g枹b枺m枻y枼y枽y枾s枿n柀b柂d柅n柆l柇h柈b柉f柊z柋d柌c柍y柎f柕m柖s柗s柟n柡y柣z柤z柦d柧g柪a柫f柭b柮w柲b栅s柶s柷z柹s柺g査c柼y柾j栁l栂m栃l栄r栆z栍s栐y栒x栔q栕c栘y栙x栚z栛l栜s栞k栟b栠r栢b栣r栤b栥z栦c栧y栨c栫j栬z栮e栯y栰f栱g栴z栵l栶y栺z栻s栿f桇r桋y桍k桏q桒s桖x桘c桙y桚z桛k桝j桞l桟z桪x桬s桭c桮b桯t桰g桱j桲b桳b桵r桸x桹l桺l桻f桼q桽w桾j杆g梀s梂q梄y梇l梈p梉z梊d梋x梌t梎a梐b梑d梒h梕r梖b梘j梙h梚w梛n梜j条t梞j枭x梠l梡k梣c梥s里l梪d梬y梮j梱k梲z梴c梶w梷j梸l梹b梺x梻x梼d梽z梾l梿l棁z弃q棅b棆l棈q棊q棌c棎c棏d棐f棑p棓b棔h枨c枣z棙l棛y棜y棝g棞j栋d棡g棢w棤q棥f棦c栈z棨q棩y棪y棫y棬j棭y棯s栖q棳z棴f棶l棷z棸z棻f棽c棾q棿n椀w椂l椄j椆c椇j椈j椉c椊z椌k桠y椑b椓z椔z椕b椖p椗d椙c椚m椛h検j椝g椞x椡d椢g椣d椥z椦q椧m椨f椩g椪p椫s椬y椮s椯d椱f椲h椳w椵j椶z椷j椸y椺x椻y椼y椾j楀y楁h楃w楄p楅b楆y楇g楈x楉r杨y楋l楌y楍b楎h楏k楐j楑k楒s枫f楘m楙m楛h楜h楟t楢y楤c楥x楧y桢z楩p楪d楬j业y楯d楰y楲w楳m楴d极j楶j楺r楻h楽l楾h楿k榁m榃t榅w榊s榋c榌b榎j榏y榑b榒n榓m榖g榗j榚y榝s榞y榟z榠m榡s榢j榣y榤j榥h榩q杩m榬y荣r榯s榰z榲w榳t榵r榶t榸z榹s榺s榼k榽x榾g桤q槂s盘p槄t槅g槆c槇d槈n槉j枪q槏q槑m槒x杠g槕z槖t様y槙d槚j槜z槝d槞l槡s槢x槣j槤l槥h槦r椠q椁g槩g槪g槫t槬h槮s槯c槰p槱y桨j槴h槵h槶g槷n槹g槺k槻g槼g槾m樀d桩z樃l樄c枞c樆l樇x樈q樉s樋t樌g樍z樎s樏l梁l樒m楼l樔c樕s樖k标b樚l樛l樜z樝z枢s樠m樢n样y樤t樥p樦z樧s権q樫j樬c樭j樮y樰x樲e樳x樴z樶z樷c朴p树s桦h樻g橀x橁c橂d橃f橅m橆w桡r橉l橊l桥q橌x橍r橎f橏j橑l橒y橓s橔t橕c橖t橗m橚s橜j橝t橞h机j橠n椭t橣n橤r橦t橧z橪y横h橬q橭g橮l橯l橰g橲x橳s橴z橵z橶j橷d橸j橺x橻c橽t橾s橿j檃y檅h檆s檇z檈x柽c檊g檋j檌z檍y檏p檒f檓h档d檕j檖s檘p檙c檚c檛z桧g檝j檞j檟j檡z检j樯q檤d檥y檦b檧s檨s檭y檮c台t檰m檱q檲t槟b檴h檵j檶q檷n柠n檹y檺g槛j檼y檽n檿y櫀q櫁m櫂z柜g櫄c櫅j櫆k櫇p櫉c櫊g櫋m櫌y櫍z櫎h櫏q櫑l櫒s橹l櫔l櫕c櫖l櫗m櫘h櫙o榈l栉z櫜g椟d橼y栎l櫠f櫡z櫣l櫤j橱c櫦q槠z栌l櫩y枥l櫫z榇c櫭j櫮e櫯s櫰h櫱n櫲y栊l櫵q櫶x櫷g榉j櫹x棂l樱y櫼j櫽y櫾y欀x欁n栏l欅j欆s欇s欈w欉c权q欋q欌z欍j欎y椤l欐l欑c栾l欓d欔q欕e榄l欗l欘z欙l欚l欛b欜n欝y欥y欨x欩c欪c欫q欬k欭y欮j欯x欰x欱h欳k欴l欵k欶s欸a欻c欼c钦q欿k歀k歁k歂c歄g歅y歈y歊x歋y歍w歏j欧o歑h歒t歓h歔x歕p歖x歗x歘x歚s歛l歜c歝y欤y歠c欢h歨b歩b歫j歭z歮s歯c歰s歱z岁s歳s歴l歵z歶y归g歺d歽z歾m殁m殀y殅s殈x殌j殎q殐s殑j殔y殕f殗y残c殙h殜d殝z殟w殠c殢t殣j殇s殥y殦c殧j殨k殩c殚d殬d殓l殡b殰d殱j歼j殶z殸q殹y杀s殻k壳k殽x殾x毁h毃q毄j殴o毇h毈d毉y毊x毋w毎m毐a毑j毘p毚c毞b毟m毠j毢s毣m毤t毦e毧r毨x毩j球q毭d毰p毱j毲d毴b毶s毷m毸s毺s毻t毼h毾t毵s氀l氁m氂m氃t氄r毡z氉s氊z氋m氇l氎d氒j気q氜y氝n氞n氠s气q氥x氢q氩y氭d氱y氲y氶z氷b氹d氺s氻l氼n泛f氿g汃p汄z汅m汈d汋z汌c丸w汏d汑t汒m汓q汖p汘q污w汚w汢t汣j汥z汧q汫j汬j汭r汮j汯h汱t汳b汵g汷z汸f决j汼n汿x沀x沄y沇y沊d沋y沍h沎h沑n没m冲c沗h沘b沚z沜p沝z沞z沠p沢z沨f沬m沯z沰t沴l沵m沶y沷f沺t泀s况k泂j泃j泆y泇j泋h泍b泎z泏c泑y泒g泙p泚c泜z泝s泟c泤s泦j泧y泩s泬j泭f泲j泴g泹d洀p洃h洅z洆c洈w洉h洊j洍s洏e洐x洑f洓s洔z洕y洖w洘k洝a洟y洠s洡l洢y洣m洤q洦p洨x泄x洬s洭k洯q洰j洴p汹x洷z洸g洺m洿w浀q浂y浄j浉s浌p浐c浕j浖l浗q浘w浛h浝m浟y浡b浢d浤h浥y浧y浨l浫h浭g浱c浳y浵t浶l浃j浺c浻j浽s浾c浿p涀x涁s涃k涄p涆h泾j涊n涋t涍x涏t涐e涒t涗s涘s涙l涚s涢y涥h涬x涭s涰c涱z涳n涴w涷d涹w涺j涻s凉l涽h涾t淁q淂d淈g淉g淊y淍z淎p淏h淐c淓f淔z淕l淗j泪l淛z淜p淟t淢y淣n渌l淧m淩l沦l淭q淯y淰n淲b淴h渊y涞l淸q浅j淽z淾y淿b渀b渁y渂w渃r渄f渆y渇k済j渉s渋s渏y渒p渓x渕y渘r涣h减j渞q渟t渢f涡g渧t渨w渪r测c渮h渰y渱h渳m渵m渶y渷y渹q渻s渼m渽z浑h渿n湀g湁c湂e湅l湆q湇q湈m湉t凑c湋w湌c湏h湐p湑x湒j湗f湙y湚y湜s湝j浈z湠t湡y湢b湣m湤s湥t湦s涌c湨j湩d湪t湬q湭q汤s湰l湱h湳n湴b湵y湶q湷z湸l湹c湺x湻c湼n湽z満m溁y溂l溄f溇l沩w溊b溋y溌h溍j溎y溑s溒y溓l溔y溕m准z溗c溙t溚t溛w沟g溞s溠z溡s溣l溤m溦w溨z溩w温w溬q溭z溮s溰a溵y溸s溹s湿s溾a溿p滀c滃w沧c灭m滆g滈h滉h滊q涤d滍z荥x滐j滒g滘j滙h滛y滝l滣c滧y滪y滫x沪h滭b滮b滞z滰j滱k渗s滳s滶a卤l浒h滺y滻c滼f滽y滚g满m漀q渔y漃j漄y漅c漇x漈j漊l漋l漌j漍g漎c漑g漒q漖j漗c漘c漙t沤o漛t漜y漝x漞m漟t漡s汉h涟l漥w漦c漧g漨f渍z漮k漰p涨z漴c漵x漷h渐j漺s漻l漼c漽t浆j潀c潂h潃x潄s潅g潈z潉k潊x潌z潏y潐j泼p潒d潓h洁j潕w潖p潗j潙w潚s潜q潝x泻x潠s潡d润r潥s潧z潨c潩y潪z潫w潬t浔x溃k潱y潳t潵s潶h滗b潹c潻s潽p潾l涠w涩s澁s澂c澃j澅h浇a涝l澊c澋j澏h澐y澑l澒h澓f澔h澕h澖x涧j澘s澙x澛l澝n澞y澟l渑m澢d澣h泽d澥x澦y澨s泶x澪l澫w澬z澭y浍k澯c澰l淀d澲y澴h澷m澸g澺y澻s澼p澽j澾t澿q浊z浓n濄g濅j濆p濇s濈j濊h濋c濌t濍s濎d濏s濐z濓l濔m濖s濗m泞n濙y濚y濜j濝q济j濢c濣w涛t濥y濦y濧d濨c濩h濪q滥l濬j濭a潍w滨b濲g濳q濴y濶k濷f濹b溅j濻w泺p濽z滤l濿l瀁y瀂l瀃s瀄z滢y渎d瀈h瀊p渖s瀌b瀍c瀎m浏l瀒s瀓c瀔g濒b瀖h瀗x泸l瀙q瀜r沥l瀞j潇x潆y瀡s瀢w瀤h瀥x瀦z泷l濑l瀩d瀪f瀫h瀬l瀭s瀮l瀯y瀱j潋l瀳j瀴y瀶l瀷y瀸j瀺c瀻d瀼r瀽j澜l瀿f灀s灁y灂z沣f滠s灅l灆l灇c灈q灉y灊q灋f灍j灎y灐y洒s灒z灓l灔y灖m灗s滩t灙d灚j灛c灏h灟z灠l灡l灢n湾w滦l灥x灦x灧y灨g灪y灮g灱x灲x灳h灴h灷z灹z灺x灻c灾z炁q炂z炄n炆w炇p炈y炋p炌k炐p炑m炘x炚g炛g炞b炟d炠x炡z炢z炣k炤z炥f炦b炧x炨x炩l炪z炰p炴y炵t炶s为w炿z烄j烅x烆h烇q烉h烋x烌x烍x烎y乌w烐z烑y烒s烓w烔t烕m烖z烗k烚x烜x烝z烠h烡g烢c烣h烥c烰f烱j烲x烳p烃t烵z烶t烸h烺l烻y烼x烾c烿r焀h焁x焂s焃h焄x焅k焆j焇x焈x焋z焌j焍d焎x焏j焒l焔y焗j焛l焜k焝h焞t焟x焠c无m焢h焣j焤f焥w焧z焨f焩p焪q焫r焬x焮x焳j焴y焵g焸x焹g焻c焼s焽x焾n焿g煀q煁c煂h煃k煄z煆x煇h煈f炼l煋x煍j煏b煐y煑z炜w煓t煔s煕x煖n煗n煘c烟y煚j煛j煝m煟w煠y煡j茕q煣r焕h烦f煪q煫s炀y煭l煯j煰z煱g煴y煵n煶s煷h煹g煻t煼c煾e煿b熀h熁x熂x熃w熅y熆h熇h熈x熉y熋x熌s熍q熎y熐m熑l荧y熓w熕g熖y炝q熚b熛b熜c熝l熞j熡l熢p熣s熤y熥t熦j熧z熩h熪y熫z熭w熮l熯h熰o热r熲j熴k熶c熷z熸j熺x熻x熼y熽x炽c熿h燀c烨y燂t焰y燅x燆q燇j灯d炖d燊s燋q燍s燏y磷l燑t烧s燖x燗l燘m烫t燚y燛j焖m燝z营y燡y燣l燤t灿c燨x燩q燪z燫l烛z燯l燱y燲x燳z烩h燵t燶n燷l燸x燺h燻x烬j燽c焘d燿y爀h爂b爃r爄l爅m爇r爈l爉l爊a爋x爌k烁s爎l爏l炉l爑j爒l爓y爔x爕x爖l爘c爚y烂l爜c爞c爟g爡c爢m爣t爤l爦l爧l爩y爫z争z爮p爯c爲w爳h爴j爷y爼z尔e牀c牁k牂z牃d牄q牅y牉p牊c牋j牎c牏y牐z牑b牓b牕c牗y牍d牚c牜n牞j它t牣r牤m牥f牨g瘪b牫g牬b牭s牰y牱k牳m牶q牷q牸z牻m牼k牵q犂l犃p犅g犆z犇b犈q犉c犌j犎f犐k犑j犓c犔x犕b荦l犗j犘m犙s犚w犁l犜d犝t犞q犠x犡l犊d犣l犤b犥p犦b牺x犨c犩w犪k犫c犮q犱j犲c犳z犵g犺k犻p犼h犽y犾y犿h状z狅k狆z狇m狉p狊j狋y狌s狏t狑l狓p狕y狖y狘x狛b狜k狝x狟h狢h狣z狤j狥x狦s狧t狪t狫l狵m狶x狭x狈b狾z狿y猀s猂h猄j猅p猆f猇x猈b猉q猋b猌y猐q猑k猒y猔z猘z狰z猚y猟l猠c猣z猤g猦f猧w猨y猭c猯t猰y猲h猳j猵p犹y猺y狲s猼b獀s獁m獂h獃d狱y狮s獆h獇q獈y獊c獋h獌m奖j獏m獑c獓a獔h獕s獘b獙b獚h獛p獜l獝x獞t獟y獡s獢x獣s獤d獥j獦g獧j独d獩h狯k猃x猕m狞n獱b获h獳r獴m猎l獶n犷g兽s獭t献x獽r獿n猡l玁x玂q玃j玅m兹c玈l玊s玌q玍g玏l玐b玒h玓d玔c玕g玗y玘q玙y玚c玜h玝w玞f玠j玡y玣b玤b玥y玦j玧m珏j玪j玬d玭p玱q玴y玵a玶p玸f玹x玼c玽g玾j玿s珁c珃r珄s珅s珆y珇z珋l珌b珎z珒j珓j珔j珕l珖g珗x珘z珚y珛x珜y珝x珟s珡q珢y珣x珤b珦x珨x珪g珫c珬x佩p珯l珰d珱y珳w珴e珵c珶d珷w珸w珹c珺j珻m珼b珽t现x珿c琀h琁x琂y琄x琇x琈f琋x琌l琍l琎j琑s琒f琓w琔d琕p琖z琗c琘m琙y琜l琝m琞s琟w琠t琡s琣b琤c琧e琩c琫b琭l琯g琱d琲b琷q琸z琹q珐f琻j琽d琾j珲h瑀y瑂m瑃c瑄x瑅t瑆x瑇d瑈r瑉m玮w瑌r瑍h瑎x瑏c瑐j瑑z瑒y瑓l瑔q瑖d瑝h瑠l瑡s瑢r琐s瑶y瑥w瑧z瑨j莹y玛m瑫t瑬l瑮l琅l瑱t瑲q瑳c瑴j瑵z瑹t瑺c瑻k瑼z瑽c瑿y璂q璄j璅s璆q璈a琏l璌y璍y璏z璑w璒d璓x璔z璕x璖q璗d璘l璙l璚j璛s璝g璟j璡j璢l玑j璤h璥j瑷a璪z璫d璬j璭g璮t璯h环h璱s璲s璳t璴c璵y璶j璷l璸b璹s璻z璼l玺x璾j璿x瓀r瓁w瓂g瓃l瓄d瓅l瓆z瓇r瓈l瓉z琼q瓋t瓌g瓍s瓎l珑l瓐l瓑l瓓l璎y瓕m镶x瓗q瓘g瓙d瓒z瓛h瓝b瓟b瓡z瓥l瓨x瓩q瓪b瓫p瓬f瓭d瓳h瓵y瓸b瓹j瓺c瓻c瓽d瓾w甀z甁p甂b甃z甅l甆c甈q甉x甊l甋d瓯o甎z甐l甒w甔d瓮w甖y甗y甛t甝h甞c甠q甡s产c産c甤r甧s甪l甮f甴y甶f甹p甼t甽z甿m畁b畂m畃x畆m畇y畉f畊g畍j畐f畑t畒m畓d畕j畖w畗d畘n亩m畟j畠t畡g毕b畣d畤z畨f畩y画h畲s畭s畮m畯j异y畱l畳d畵h畷z畺j畻c畽t畾l疀c疁l疂d疄l疅j畴c疈p疉d叠d疌j疍d疎s疐z疓n疕b疘g疛z疞x疢c疦j疧q疨y疩c疭z疶x疷z疺f疻z痱f痀g痁d痆n痋t痌t痎j痏w痐h痑t痓z痗m痉j痚x痜t痝m酸s痡f痥d痩s痬y痮z痯g麻m痵j痶t痷a痸c痹b痻m痽d痾k瘂y瘄c瘆s瘇z瘈z瘉y疯f疡y瘎c瘏t瘑g瘒w痪h瘔k瘖y瘚j瘜x瘝g瘗y疮c瘣h疟n瘨d瘬z瘮s瘯c瘱y瘲z瘶s瘷s瘘l瘻l瘽q疗l癄q癅l痨l痫x癈f瘅d癋h癎x癏g癐g癑n癒y癓w癕y癗l疠l癙s癚d癛l癝l癠j痴c痒y疖j症z癧l癨h癞l癪j癣x瘿y瘾y瘫t癫d癳l癴l癵l癶b癹b発f发f癿q皀b皁z皃m皅p皉c皊l皌m皍j皏p皐g皒e皔h皕b皗c皘q皑a皛x皜h皝h皞h皟z皠c皡h皢x皣y皥h皦j皧a皨x皩h皪l皫p皬h皭j皯g疱p皳q皵q皶z皷g皲j皹j皱z隳h皼g皽z皾d盀q盁y盃b啊a阿a埃a挨a哎a哀a癌a蔼a矮a艾a碍a隘a鞍a氨a安a俺a按a暗a岸a胺a案a肮a昂a盎a凹a敖a熬a翱a袄a傲a懊a澳a芭b捌b扒b叭b吧b笆b八b疤b巴b拔b跋b靶b把b耙b霸b罢b爸b白b柏b百b佰b拜b稗b斑b班b搬b扳b般b颁b板b版b扮b拌b伴b瓣b半b办b绊b邦b梆b榜b膀b绑b棒b磅b蚌b镑b傍b谤b苞b胞b包b褒b盄d盇h盉h盋b盌w盓y盕f盙f盚q盗d盝l盏z盠l盢x监j盦a卢l盨x盩z荡d盫a盬g盭l盰g盳m盵q盷x盺x盻x盽f盿m眀m眂s眃y眅p眆f眊m県x眎s眏y眐z眑y眒s眓h眔d眕z眖k眗j眘s眛m眜m眝z眞z眡s眤n眦z眧c眪b眫p眬l眮t眰d眱d眲n眳m眴s眹z眻y眽m众z眿m睂m睄s睅h睆h睈c睉c睊j睋e睌m睍x睎x困k睒s睓t睔g睕w睖l睗s睘q睙l睁z薄b雹b保b堡b饱b抱b暴b豹b鲍b爆b杯b碑b悲b卑b北b辈b贝b钡b倍b焙b被b奔b本b笨b崩b绷b甭b泵b蹦b迸b逼b鼻b比b鄙b笔b彼b碧b蓖b蔽b毖b庇b闭b敝b弊b必b辟b壁b臂b避b陛b鞭b边b编b贬b扁b便b变b卞b辨b辩b辫b遍b彪b膘b表b鳖b憋b彬b斌b宾b兵b冰b柄b丙b秉b饼b炳b睝l睐l睟s睠j睤b睧h睩l睾g睭z睮y睯h睰m睱x睲x睳h睴h睵z睶c睷j睸m睺h睻x睼t瞁x瞂f瞃w瞆g眯m瞉k瞊d瞋c瞐m瞕z瞖y瞗d瞘k瞙m瞚s瞛c瞜l瞝c瞒m瞡g瞣w瞤s瞦x瞨p瞫s瞮c瞯x瞱y瞲x瞴w瞶g瞷j瞸y瞹a瞺h睑j瞾z矀w矁c矂s矃n矄x矅y矆h矈m矉p矋l矌k矎x矏m矐h矑l矒m矔g矕m矖x矘t矙k瞩z矝j矞y矟s矠z矡j矤s病b玻b菠b播b钵b波b博b勃b搏b铂b箔b伯b帛b舶b脖b膊b渤b泊b驳b捕b卜b哺b补b埠b不b步b簿b部b怖b猜c裁c材c才c财c睬c踩c彩c菜c蔡c餐c蚕c苍c舱c藏c操c糙c槽c曹c草c策c蹭c插c茬c茶c查c碴c搽c察c岔c差c诧c拆c柴c豺c蝉c馋c谗c缠c阐c颤c昌c猖c矦h矨y矪z矫j矰z矱y矴d矵q矷z矹w矺z矻k矼g砃d砄j砅l砆f砇m砈e砊k砋z砎j砏p砐e砓z砕s砙w砛j砞m砠j砡y砢l砤t砨e砪m砫z砮n砯p砱l炮b砳l砵b砶p砽y砿k硁k硂q朱z硄k硆e硈q硉l硊w硋a硍k硏y硑p硓l硔h硘q硙w硚q硛c硜k硞q硟c硠l硣x硖x硥m硦l硧y砗c硩c砚y硰s硱k硲y硳z硴h硵l硶c硹s硺z硻k硽y硾z硿k碀c碁q碂z碃q常c长c肠c敞c唱c倡c超c抄c钞c朝c嘲c潮c巢c吵c炒c车c扯c撤c掣c澈c郴c臣c辰c晨c忱c沉c陈c趁c衬c称c城c橙c成c呈c乘c程c澄c诚c承c逞c骋c秤c持c匙c池c迟c弛c驰c齿c侈c赤c翅c斥c充c虫c崇c抽c酬c踌c稠c愁c筹c仇c绸c瞅c丑c臭c初c出c躇c锄c雏c滁c除c楚c碄l碅j碆b碈m碊j碋h碏x碒y碔w碕q碖l碙n碝r碞y碠d碢t碤y碦k碨w硕s碪z碫d碬x砀d碮t碯n碵t碶q碷d碸f确q码m碿s磀e磃s磄t磆h磇p磈k磌t磍x磎x磏l磑w磒y磓d磖l磗z磘y砖z磛c磜q磝a磞p磟l磠l磡k磢c碜c磤y磥l磦b碛q磩z磪c磫z磮l矶j磱l磳z磵j磶x磸d磹d磻b磼j硗q磾d磿l礀j礂x礄q礆j礇y礈z礉h礊k礋z礌l础c矗c搐c触c处c揣c川c穿c椽c船c喘c串c窗c幢c床c闯c吹c炊c捶c锤c垂c春c椿c醇c唇c淳c纯c蠢c戳c绰c疵c茨c磁c雌c辞c慈c瓷c词c此c刺c赐c次c聪c葱c匆c粗c醋c簇c促c蹿c篡c窜c摧c崔c催c脆c瘁c粹c淬c翠c村c存c磋c撮c搓c措c挫c错c达d答d瘩d打d大d呆a歹d傣d戴d殆d代d贷d袋d待d逮d礍j礏y礐q礑d礒y礔p礕p礖y礗p礘e礚k礛j礜y礝r礟p礠c礡b礢y礣m礥x矿k礧l礨l礩z砺l砾l矾f礭q礮p礯y礰l砻l礲l礳m礵s礷j礸c礹y礽r礿y祂t祃m祄x祆x只z祊b祋d祌z祎y祏s佑y祑z祒t祔f秘b祙m祡c祣l祤y祦w祩z祪g祫x祬z祮g祰g祲j祳s祴g祵k祹t祻g祼g祽z祾l禄l禂d禃z禆b禇c禉y禋y禌z祸h禐y禑x禒x怠d耽d丹d郸d胆d旦d氮d但d淡d诞d蛋d党d刀d蹈d倒d祷d到d稻d悼d道d德d得d的d蹬d登d等d瞪d凳d邓d堤d低d滴d迪d笛d狄d翟d嫡d底d地d蒂d第d帝d弟d递d缔d颠d掂d滇d碘d点d典d靛d电d佃d甸d店d惦d奠d殿d碉d叼d凋d刁d掉d钓d调d跌d爹d碟d蝶d迭d谍d禓s禔z禕y禖m禗s禘d禙b禛z禜y禝j禞g禟t禠s禡m禢t禣f禤x禥q御y禨j禩s禅c禫d禬g禭s礼l禯n祢m禲l禴y禵t禶z禷l禸r禼x秃t秂r秄z秅c秇y籼x秊n秌q秏h秐y秓z秔j秖z秗y秙k秚b秛p秜n秝l秞y秠p秡b秥n秨z秪d秬j秮h秱t秲s秳h秴h秵y秶z秷z秹r秺d秼z秾n秿f稁g稄x税s稇k秆g稉j稊t稌s稏y稐l稑l稒g稓z稕z稖b稘j稙z稛k棱l丁d盯d叮d钉d顶d鼎d锭d定d订d冬d董d懂d侗d恫d洞d兜d抖d陡d豆d逗d痘d都d督d毒d读d堵d睹d赌d杜d镀d肚d度d渡d妒d端d短d锻d段d缎d堆d队d墩d蹲c敦d顿d囤d钝d盾d遁d掇d哆d多d垛d躲d朵d跺d舵d剁d惰d蛾e峨e鹅e俄e额e讹e娥e厄e扼e遏e鄂e饿e恩e而e耳e饵e洱e二e稝p禀b稡z稢y稤l稦y稧x稨b稩j稪f稫p稭j种c稯z稰x稲d稴x稵z稶y稺z稾g谷g穁r穂s穃r穄j穅k穇c穈m穊j穋l稣s颖y穏w穐q穒k穓y穔h穕q穖j穘x穚j穛z穜t穝z穞l穟s穑s秽h穣r穤n穥y穦p穧j穨t稳w穪c穬k穭l穮b穯s穱z穲l穳c穵w穻y穼s穽j穾y窂l窅y窇b窉b窊w窋z窌j窎d窏w窐w窓c窔y窙x窚c窛k窞d窡z窢h贰e罚f筏f伐f乏f阀f法f藩f帆f番f翻f樊f钒f繁f凡f反f返f范f贩f犯f饭f芳f方f肪f房f防f妨f访f纺f放f菲f非f啡f飞f肥f匪f诽f吠f肺f沸f费f芬f酚f吩f氛f分f纷f焚f汾f粉f份f忿f粪f丰f封f蜂f峰f锋f风f烽f逢f冯f缝f讽f奉f凤f否f敷f肤f孵f扶f拂b辐f幅f氟f符f伏f俘f服f窣s窤g窝w洼w窫y穷q窑y窰y窱t窲c窴t窵d窭j窷l窸x窹w窥k窻c窼c窾k竀c竁c竂l竃z窍q竆q窦d竈z竉l窃q竍s竎f竏q竐c竑h竒q竓h竔s竗m竘q竚z竛l竜l竝b竡b竢s竤h竧j竩y竫j竬q竮p竰l竱z竲c竳d竴c竵w竞j竷k竻l竼p竾c笀m笁z笂w笅j笇s笉q笌y笍z笎y笐h笒c笓b笖y笗d笘s笚d笜z笝n笟g笡q笢m笣b笧c笩f笭l浮f涪f福f袱f弗f甫f辅f俯f釜f斧f脯f腑f府f腐f赴f副f覆f赋f傅f付f阜f父f腹f负f富f讣f附f缚f咐f噶g嘎g该g改g概g钙g盖g溉g甘g柑g竿g肝g赶g感g敢g赣g钢g缸g肛g纲g港g篙g皋g高g膏g羔g糕g搞g镐g稿g哥g歌g戈g鸽g胳g疙g割g革g葛g格g蛤g阁g隔g铬g各g给g根g跟g耕g更g庚g羹g笯n笰f笲f笴g笵f笶s笷m笹t筇q笽m笿l筀g筁q筂c筃y筄y筈k筊j笋s筎r筓j筕h筗z筙l筜d筞c筟f筡t筣l筤l筥j筦g笕j筨h筩t筪x筫z筬c筭s筯z筰z筶g筸g筺k筼y筽o筿x箁p箂l箃z箅b箆b箉g箊y笺j箌z箎c筝z箑s箒z箓l箖l箘q箙f箚z箛g箞q箟j箠c箣c箤z箥p箮x箯b箰s箲x箳p箵x箶h箷s箹y箺c箻l箼w箽d箾s箿j节j篂x篃m埂g耿g梗g工g攻g功g恭g龚g供g躬g公g弓g巩g汞g拱g贡g共g钩g勾g苟g狗g垢g购g辜g菇g咕g箍g估g沽g孤g姑g鼓g古g蛊g骨g股g故g顾g固g刮g瓜g寡g褂g乖g怪g棺g关g官g冠g观g管g馆g罐g灌g贯g光g逛g瑰g规g圭g硅g闺g轨g鬼g诡g癸g桂g跪g贵g辊g棍g锅g郭g果g裹g过g哈h篅c篈f筑z篊h箧q篍q篎m篏q篐g篔y篕h篖t篗y篘c篛r篜z篞n篟q筱x篢l篣p笃d篧z篨c筛s篫z篬q篭l篯j篰b篲h筚b篴z篵c篶y篸c篹s篺p篽y篿t箦z簁s簂g簃y簄h簅c簆k簈p簉z簊j篓l簎c簐n蓑s簒c簓s簔s簕l簗z簘x簙b簚m簛s簜d簝l箪d簠f简j簢m篑k簤d簥j簨z簩l箫x簬l簭s簮z簯q簰p簱q簲p簳g簴j簵l簶l檐y簹d簺s簻z簼g签q帘l籂s骸h孩h海h氦h亥h害h骇h酣h憨h邯h韩h涵h寒h函h喊h罕h翰h撼h捍h旱h憾h悍h焊h汗h夯b杭h航h壕h嚎h豪h毫b郝h好h耗h号h浩h呵h喝h荷h菏h核h禾h和h何h合g盒h貉h阂h河h涸h赫h褐h鹤h贺h嘿h黑h痕h很h狠h恨h亨h衡h轰h哄h烘h虹h鸿h洪h宏h弘h红g喉h侯h猴h吼h厚h候h后h呼h乎h忽h瑚h葫h胡h蝴h狐h糊h湖h篮l籄k籅y籆y籇h籈z籉t籊t籎y籏q藤t籑z籒z籓f籔s籕z籖q籗z籘t籙l籚l籛j箨t籝y籞y籁l笼l籡s籢l籣l龠y仠g籦z籧j籨l笾b簖d籫z篱l籭s箩l籯y籰y籱z吁x籵f籶s籷z籸s籹n籺h籾n籿c粀z粁q粂z粃b粄b粅w粆s粇k粈r粊b粋c粌y粍z佂z粏t粐h佹g侀x粔j粖y粙z粚c粛s粠h侼b侽n粣c粦l粨b粩l粫e粬q粭h粯x粰f粴l粤y粶l粷j粸q粺b粻z弧h虎h唬h护h互h花h华h猾h滑h化h话h槐h淮h桓h还h缓h患h豢h宦h幻h荒h慌h黄h磺h蝗h簧h皇h凰h惶h煌h晃h幌h恍h谎h灰h辉h徽h恢h蛔h回h悔h慧h卉h惠h晦h贿h讳h诲h绘h荤h昏h婚h魂h混h豁h活h伙h火h或h惑h霍h货h圾j基j畸j稽j箕j粿g糀h倄y糃t糄b糆m糉z糋j糎l糏x糐f糑n糒b糓g糔x糘j糚z糁s糡j馍m糣s糤s糥n糦x粮l糩k糪b糫h糬s糭z糮x糱n粝l糳z籴d糵n粜t糷l糹s糺j糼g糽z纠j纪j紁c纣z紃x约y纡y纥g纨w纫r纹w紌q纳n紎z紏t纽n紑f紒j纾s纰p紖z纱s紘h纸z级j纭y紝r紞d紟j紣c紥z紦h紨f紩z紪q紬c紭h扎z细x绂f绁x绅s紴b紵z紶q偟h肌j饥j迹j激j讥j鸡j姬j绩j缉j吉j棘j辑j籍j集j及j急j疾j即j嫉j脊j己j蓟j技j偤y冀j季j伎j祭j悸j寄j寂j计j记j既j忌j际j妓j继j嘉j枷j佳j加j荚j颊j贾g甲j钾j假j稼j架j驾j嫁j尖j间j煎j兼j肩j艰j缄j茧j柬j硷j剪j荐j鉴j践j贱j见j键j箭j件j紷l紸z绍s绀g紻y绋f紽t紾z绐d绌c絁s终z弦x组z絅j絇q絈m絉s絊z絋k経j絍r绗h絏x傶q结j絑z絒c傸c絓g絔b绝j絖k絗h絘c絙h絚g绦t絜j絝k绞j絟q絠g络l绚x絣p絤x絥f絧t绒r絩t絪y絫l絬x絭j絯g絰d统t丝s絴x絵h絶j絸j绢j絺c絻w絼z絽l絿q綀s綂t绡x綄h綅q绠g綇x绨t綉x綊x綋h綌x綍f綎t绥s綐d捆k綒f经j綔h綕z綖y綗j綘f健j舰j饯j建j僵j姜j江j疆j蒋j讲j匠j酱j降j蕉j椒j礁j焦j胶j交j郊j骄j嚼j铰j脚j狡j角j饺j缴j教j酵j轿j较j叫j窖j揭j接j皆j秸j街j阶j截j劫j桔j捷j睫j竭j姐j戒j藉j芥g界j借j介j疥j诫j巾j筋j斤j金j兠d今j津j襟j紧j锦j谨j进j靳j禁j近j浸j継j続x综z綝c缍d綟l绿l綡j绻q綤s綧z綨j綩w綪q綫x绶s维w綯t绾w网w綳b缀z綶g綷c纶g绺l绮q绽z綼b绫l绵m緀q緁j緂t緃z绲g緅z緆x缁z緈x緉l绯f緌r緍m緎y総z緐f緑l绪x緓y緔s緕z緖x缃x缂k线x緜m緟c缗m緢m缘y緤x緥b缌s緧q緪g緫z缅m緭w緮f纬w緰x缑g缈m緳x练l緵z缏b緷g緸y缇t緺g荆j兢j茎j睛j晶j鲸j京j惊j精j粳j井j警j景j颈g静j境j敬j镜j靖j竟j炯j窘j揪j究j玖j韭j久j灸j九j酒j救j旧j臼j舅j咎j就j疚j鞠j拘j狙j疽j居j驹j菊j咀j矩j举j沮j聚j拒j巨j具j距j剏c踞j锯j俱j句g炬j捐j鹃j娟j倦j眷j撅j攫j抉j掘j倔j爵j觉j诀j均j菌j钧j军j君j峻j致z緼w緽c緾c緿d縀x縁y縂z縃x縄s縅o縆g縇s萦y缙j缢y缒z縌n縍b縎g縏p绉z缣j縒c縓q縔s縕y縖x縗c縘x縙r縜y缜z缟g缛r縠h縡z縢t县x縤s縥z縦z縧t縨h縩c縪b縬c缡l缩s演y縰x纵z缧l纤q缦m絷z缕l縸m缥p縺l縼x总z縿s繀s繂l繄y缫s缪m襁q繉s繊x繋j繌z繍x繎r繐s缯z繓z织z缮s繖s繗l繘j繙f缭l繛c繜z勩y俊j竣j浚j郡j骏j喀k咖g卡k咯g开k揩k楷j慨k刊k堪k勘k坎k砍k看k康k慷k糠k扛g抗k亢g炕k拷k烤k靠k坷k苛k柯k棵k磕k颗k科k咳h可k渴k刻k客k课k肯k啃k坑k吭h空k恐k孔k控k口k扣k寇k枯k哭k窟k苦k酷k裤k夸k垮k挎k跨k胯k筷k快k款k筐k狂k框k眶k亏k盔k葵k奎k魁k傀g绕r繟c繠r绣x缋h繣h繤z繥x繦q繧w繨d绳s繬s繮j缳h缲q繱c繲x繴b繵d繶y繷n繸s绎y繺s繻x缤b缱q繿l纀p纁x纃z纅y纆m纇l缬x纉z纩k续x累l纎x纐k纑l纒c缨y厠c纗z缵z纙l缆l纝l纞l纮h纴r纻z纼z绖d绤x绬y绹t缊w缐x缞c缷x缹f缻f缼q缾p罀z罁g罃y罆g罇z罉c罊q罋w罂y罍l罎t罏l罒w罓w馈k愧k坤k昆k括g廓k阔k垃l拉l喇l蜡l腊l辣l啦l莱l赖l蓝l婪l阑l兰l谰l览l榔l狼l廊l郎l朗l浪l牢l老l佬l姥l酪l烙l勒l雷l镭l蕾l磊l儡l肋l类l楞l冷l厘l梨l黎l狸l离l理l李l鲤l莉l荔l吏l丽l利l傈l例l俐l罙s罛g罜z罝j罞m罠m罣g罤t罥j罦f罧s罫g罬z罭y罯a罳s骂m罶l罸f罺c呩s罻w罼b罽j罿c羀l羂j羃m羄z罴p羇j羁j羉l羍d羏y羐l羑y羓b羕y羖g羗q羙m羠y羢r羟q羡x义y羬x羱y羴s羺n羾h翀c翃h翆c翇f翈x翉b翋l翍p翏l翐z翑q习x翓x翖x翗k翙h翚h翛x翜s翝h翞j翢d翣s哷l痢l立l粒l隶l力l璃l哩l联l莲l连l镰l廉l脸l链i啅z粱l良l辆l量l晾l亮l谅l撩l聊l僚l燎l寥l辽l潦l撂l镣l廖l料l列l烈l劣l琳l林l霖l临l邻l鳞l淋l赁l啙z啛c吝l拎l玲l菱l零l龄l铃l伶l羚l凌l灵l陵l领l另l令l溜l琉l榴l硫l馏l留l瘤l流l柳l六l龙l聋l窿l翤c翧x翨c翪z翫w翬h翯h翲p翴l翵h翶a翷l翸p翘q翽h翾x翿d耂l耇g耈g耉g耊d耎n耏n耓t耚p嗘j耝q耞j耟j耡c耣l耤j耫z耧l耭j耮l耯h耰y耲h耴y耹q耺y耼d耾h聀z聄z聅c聇z聈y聉w聏e聐y聑t聓x聕h圣s聗l聙j聛b聜d聝g闻w聟x聠p聡c聢x聣n聤t聥j聦c聧k聨l聫l聬w聭k聮l声s耸s聴t聩k聂n职z聸d聍n聺q聻n嘓g聼t听t拢l陇l漏l陋l芦l颅l虏l鲁l麓l碌l露l路l赂l鹿l潞l录l陆l驴l铝l旅l履l氯l律l率l卵l掠l略l轮l噵d论l萝l螺l逻l锣l骡l裸g落l洛l嚍j骆l嚒m蚂m马m嘛m埋m买m麦m卖m迈m脉m馒m蛮m蔓m曼m慢m漫m肁z肂s肃s肈z肊y肍q肎k肏c肐g肑d囄l肔c肕r肗r肙y肞c肣q肦b肧p肨p肬y肰r肳w肵q肶p肹x肻k胅d胇b胈b胉b胊q坺f垀h胏z胐f胒n胓p胔z胕f胘x胟m胠q胢q胣c胦y胮p胵c胷x胹e埱c埶y胾z胿g脀z脁t脃c脄m胁x脇x脋x脌n脕w脗w脙x胫j脜r脝h脟l脠s脡t脢m脤s脥j塈x睃s脨c修x脪x脱t脭c脮n脰d脳n脴p脵g脷l胀z脼l脽s脿b谩m芒m墽q茫m盲m氓m壔d忙m莽m猫m茅m锚m毛m矛m铆m卯m茂m冒m帽m貌m贸m么m玫m枚m梅m酶m霉m煤m眉m媒m镁m每m美m昧m寐m妹m媚m门m萌m檬m盟m锰m猛m孟m醚m靡m糜m迷m谜m米m觅m泌b蜜m密m棉m眠m冕m免m勉m娩m面m苗m妌j描m瞄m藐m秒m妛c妭b渺m妙m蔑m民m抿m皿m敏m姃z闽m明m螟m鸣m铭m名m命m谬m摸m腀l腁p腂g腃j腄c腅d腇n腉n腍r肾s腏z腒j腖d腗p腘g腛w腜m腝r腞z娊x脶l腢o腣d腤a脑n腨s腪y肿z腬r腯t腲w腵j婂m腶d腷b膁q腽w膄s膅t膆s膇z膉y膋l膌j膍p膎x膐l膒o膓c膔l膕g膖p膗c膙j膞z膟l膡y膢l膤x膥c膧t腻n膫l膬c膭k膮x媑z膯t膰f膱z膲j膴h媝q媡l膵c膶r膷x膸s膼z脍k脓n臄j臅c臇j臈l臋t脐q臎c膑b臐x臑n嫿h嬃x嬓j臓z摹m蘑m模m嬜x膜m磨m摩m嬟y魔m抹m末m莫m墨m默m沫m漠m寞m陌m谋m牟m某m拇m牡m姆m母m墓m暮m幕m募m慕m木m目m孨z睦m牧m穆m拿n哪n孶z钠n那n娜n氖n乃n奶n耐n奈n南n男n难n囊n闹n淖n呢n馁n嫩n能n妮n霓n倪n泥n尼n匿n逆n溺n蔫n拈n年n碾n酿n鸟d尿n捏n孽n镊n镍n涅n您n凝n臔x臕b臖x臗k臙y胪l臛h臜z臝l臞q脏z脔l臡n臢z卧w臦g臩g臫j臮j臯g臰c岅b臲n臵g臶j臷d臸z臹x岟y臽x臿c舃x与y兴x岪f岾z峊f舎s舏j舑t峣y舓s舕t铺p舗p峮q舘g舙h舚t舝x舠d舤f舥p舦t舧f舩c舮l舲l舼q峾y舽p艀f艁z艂f艃l艅y艆l艊b艌n艍j艎h艐k艑b艒m艓d艔d嵽d嶈q艖c艗y艛l艜d艝s艞y艠d艡d艢q舣y艥j艧h艩q牛m扭n钮n嶪y农n弄l奴n努n怒n女n暖n虐n挪n懦n糯n诺n哦e巆y鸥o藕o偶o巏q啪p趴p爬p帕p怕p琶p拍p排p牌p徘p湃p派p攀p潘f磐p盼p畔p判p叛p乓p庞p耪p胖p咆p刨b袍p跑p泡p呸p胚p培p裴p赔p陪p配p沛b盆p砰p抨p烹p澎p彭p蓬p棚p硼p篷p膨p朋p鹏p捧p碰p坯p砒p霹p批p披p劈p琵p毗p艪l舻l艬c艭s艵p艶y艳y艹a艻l艼d幯j庅m庺s芃p芅y芆c芇m廐j芉g芌y苄b芓z芔h芕s弐e芚t芛w芞q芠w芢r芣f芧x芲l弞s芵j芶g芺a刍c芼m芿r苀h苂c苃y苅y苆s苉p苐d苖d苙l苝b苢y苎z苨n苩p苪b苬x苭y苮x苰h徛j苲z徦j苳d苵d苶n苸h苺m苼s苽g苾b苿w徴z茀f徸z茊z茋z茐c茒y茓x茖g茘l忇l茙r茝c茞c怓n茠h茡z茢l茣w茤j茥g茦c茩h茪g茮j怱c茷f茻m茽z啤p脾p疲p皮p匹p恎d痞p僻p屁p譬p篇p偏p片p骗p恜c飘p瓢p票p撇p瞥p拼p频p贫p品p聘p乒p坪p苹p萍p平p瓶p评p屏b坡p颇p婆p破p魄b迫p粕p剖p莆p葡p菩p蒲p埔b圃b普p浦p谱p曝b瀑b期j欺q妻q七q漆q柒q沏q其j棋q奇j歧q畦q崎q愂b齐j祈q祁q起q岂q乞q企q契q器q迄q汽q泣q愪y讫q掐q茾q茿z荁h荂f荄g荅d愲g荈c荋e荌a荍q荎c荓p荕j荖l荗s荘z荙d荝c荢z慃y荰d荱w荲l荳d荴f荵r荶y荹b荺y荾s荿c莀c莁w莂b莃x莄g莇z莈m庄z莋z莌t莏s莐c莑p莔m莕x憉p莗c莙j莚y莝c莟h莡c莣w莤s莥n莦s憜d苋x莬w莭j莮n憡c莯m莵t莻n莾m莿c菂d菃q菄d菆c菈l菉l菋w菍n菎k菐p菑z菒g菓g菕l菗c憿j菙c菚z菛m菞l菢b菣q菤j菦q菧d菨j菫j懏j菬q菭t恰q洽q钎q铅q千q懡m迁q仟q谦q乾q黔q钱q钳q前q遣q谴q嵌k欠q歉q腔q羌q蔷q橇q锹q敲q悄q瞧q巧q鞘q撬q峭q俏q切q茄j且j怯q戵q侵q亲q秦q琴q勤q芹q擒q禽q沁q青q轻q卿q清q擎q晴q氰q情q顷q请q秋q丘q邱q求q囚q抯z酋q泅q趋q蛆q曲q躯q屈q驱q渠q菮g菳q庵a菵w拲g菶b菷z菺j挌g菼t菾t菿d萀h萅c苌c萈h萉f萐s萒y萓y萔t萕q萖w萗c萙k萚t萛j萞b萟y萠p萡b萢p萣d萩q萪k萫x万m萭y萮y萯f萰l萲x萳n萴c掤b莴w萶c萷s萹b萺m萻a萾y葀k葁j葂m葃z葄z葅z葇r葈x叶x葊a葋q葌j葍f葎l葏j葐p荭h葓h搮l摀w葕x葖t葘z葝q葞m葟h葠s葢g葤z摖q葥q苇w葧b葨w葪j葮d药y葰j葲q葴z摾j葹s葻l葼z取q娶q龋q趣q去q圈j颧q醛q泉q全q痊q拳q犬q券q撧j缺q炔g瘸q鹊q榷q裙q群q然r燃r冉r染r瓤r壤r攘r嚷r让r饶r惹r壬r擟m仁r人r忍r韧r任r认r刃r妊r扔r仍r日r戎r茸r擿t攂l蓉r融r熔r溶r攚w容r冗r揉r柔r肉r茹r蠕r儒r孺r如r辱r乳r汝r攺y入r褥r软r阮r蕊r瑞r锐r闰r若r弱r撒s萨s腮s鳃s塞s赛s三s叁s葽y葾y葿m蒀y蒁s蒃z蒄g蒅s蒆x蒍w蒏y蒐s蒑y蒒s蒓c莳s蒕y蒖z蒘r蒚l蒛q蒝y莅l蒟j蒠x蒢c蒣x蒤t蒥l蒦h蒧d蒨q蒩z蒪p蒫c蒬y蒭c蒮y蒰p蒱p蒳n斮z蒵x斳q蒷y蒻r蒾m荪s蓂m蓃s蓅l蓆x蓇g蓈l蓌c蓎t蓏l蓒x蓔y蓕g蓗z蓘g蓙g蓚t蓛c蓜p蓞d蓡s旤h蓢l蓤l蓧d蓨t蓩m蓪t蓫z蓭a苁c蓱p蓲q蓳j蓴c蓵j蓶w蓷t蓸c蓹y蓺y蓻z荜b蓾l蔀b蔁z蔂l散s桑s嗓s搔s骚s嫂s瑟s色s森s僧s莎s砂s沙s傻s啥s晇x煞s珊s苫s杉s山s煽s衫s闪s陕s擅s赡s膳s善s汕s晬z扇s商s赏s晌s上s尚s裳c梢s捎s稍s芍s勺s韶s少s哨s邵s奢s赊s蛇s舌s赦s射s涉s社s设s砷s申s呻s伸s身s深s娠s神s沈s暎y暔n甚s慎s生s甥s牲s蔃q暭h蔄m蔅y蔇j蔈b蔉g蔊h蔋d蔍l蔎s蔏s蔐d蔒h蔕d蔖c蔘s蔙x蔛h蔜a曌z曗y曻s蒌l蔠z蔢p蔤m茑n蔧h蔩y蔪j荫y蔮g蔯c蔰h蔱s蔲k蔳q枈p蔵z蔶z蔾l蔿w蕀j荨q蕂s蕄m蕅o蒇c蕇d蕋r蕌l蕍y荞q蕏z蕐h蕑j芸y蕔b莸y蕗l柛s荛r蕚e蕛t蕜f蕝j蕟f蕠r柨b蒉k蕣s蕥y蕦x蕧f柸b芜w蕫d蕬s萧x栭e蕯s蕰y蕱s蕳j蕵s蕶l蓣y蕸x桗d蕼s蕽n蕿x薀y薁y桜y省s盛c剩s失s施s诗s尸s虱s十s石d拾s什s梍z食s蚀s识s史s矢s使s屎s驶s始s式s示s士s世s梫q柿s事s拭s誓s逝s嗜s噬s适s棃l仕s侍s释s棇c饰s氏s市f恃s室s视s试s收s手s首s守s授s售s受s椃h瘦s蔬s梳s殊s抒s输s叔s舒s淑s椘c疏s赎s孰s熟s薯s暑s曙s署s蜀s黍s鼠s述s束s戍s竖s墅s庶s漱s薂x薃h楕t楖j楡y荟h薉h薋c芗x薍w薎m薐l薒c薓s薕l薖k榐z薗y薘d薙t薚t薝z薞s槀g薠f薡d薢x薣g薥s槁g薫x薬y薭b薱d槗q薲p薳y薴n薵c薶m薸p荠j薻z薼c薽z薾e薿n藀y藂c藃x藄q藅f藆j藇x藈k藊b藋d藌m荩j槸y藑q藒q藔l藖x藗s樐l藘l藙y藚x藛x艺y藞l藟l藠j藡d藢z藣b藦m藧h藨b薮s藫t藬t藭q藮q藯w藰l樼z樿s藲o藳g藴y藵b苈l藸z橩q恕s刷s耍s摔s衰c甩s栓s拴s霜s双s爽s谁s水s睡s吮s瞬s顺s舜s说s朔s斯s撕s嘶s思s私s司s死s肆s寺s嗣s四s似s饲s巳s松s颂s送s宋s讼s诵s搜s艘s嗽s酥s俗s素s檪l速s粟s僳s塑s溯s宿s诉s蒜s算s檾q櫈d櫐l虽s隋s随s髓s碎s穗s遂s隧s祟s櫢s梭s櫴l唆s索s锁s所s櫿y塌t他t她t欃c塔d蔺l欟g欦q藽q藾l歞e蘁w蘂r歬q殏q蕲q蘈t蘉m蕴y蘌y蘍x蘎j蘏j蘐x殭j毥x蘔j蘕p蘖n蘘r蘙y藓x蘛y蘜j蘝l蔹l蘟y蘠q蘡y茏l蘣t蘤h蘥y蘦l蘨y蘪m蘫l蘬g蘮j蘯d蘰k蘱l蘲l蘳h蘴f蘵z蘶w蘷k汦z汻h沕m蓠l蘻j蘽l蘾h虀j虁k泈z泘h虃j泿y虄s虅t洜l虇q虈x虉y虊l虋m虌b虒s虓x虖h虗x虘c虙f虚x虝h虠j浰l虡j虣b浲f虤y虥z虦z涖l涶t虩x虪s蹋t踏t胎t淃j抬t泰t酞t太t汰t坍t贪t檀t痰t潭t谭t谈t坦t毯t袒t碳t探t炭t渜n塘t搪t堂t棠t膛t唐t糖t倘c躺t淌t趟t掏t滔t萄t桃t逃t淘t陶t讨t套t特t腾t疼t誊t梯t湕j剔t踢t锑t提d题t蹄t啼t体t替t嚏t惕t涕t剃t湲y天t添t填t田t甜t恬t舔t腆t挑t眺t跳t贴t铁f帖t虭d虯q虰d虳j虴z虵s溳y滖s滜z滵m虸z蚃x蚄f漐z蚆b蚇c蚈q蚉w蚎y蚏y蚐j蚑q蚒t漹y潎p蚖y潣m蚗j蚘h蚙q蚚q蚛z蚞m蚟w蚡f蚢h蚥f蚦r蚫b澚a蚮d蚲p蚳c蚷j蚸l蚹f蚻z蚼g蚽p蚾p蛁d蛂b蛃b蛈t蛌t蛍y蛒g蛓c蛕h蛖m蛗f蛚l蛜y蛝x蛠l濵b蛡y蛢p蛣j濸c蛥s蛦y蛧w蛨m蛪q蛫g蛬q瀀y瀇w瀐j蛵x蛶j蛷q蛱j蜕t蛼c蛽b蛿h蜁x蜄s蜅f蚬x蜋l蜌b蜎y蜏y蜐j蜑d蜔d蜖h汀t廷t停t亭t庭t挺t艇t通t桐t酮t瞳t同t铜t彤t童t桶t灜y捅t筒t痛t偷t投t头t灩y透t凸t突t徒t途t屠t土t吐t兔t湍t推t颓t腿t褪t退t吞t屯t臀t拖t托t炏y鸵t陀t驮d炓l炗g驼t妥t拓t唾t挖w哇w蛙w娃w瓦w袜w炲t歪w外w豌w玩w顽w烷w完w碗w挽w晚w皖w惋w宛w烞p婉w腕w汪w王w烮l亡w枉w往w旺w望w忘w妄w威w蜙z蜛j蜝q蜟y蜠j蜤s蜦l蜧l蜨d蜪t蜫k蜬h蜭h蜯b蜰f蜲w蜳d蜵y蜶s蜸q蜹r蜺n蜼w蜽l蝀d蝁e蝂b蝃d蝄w蝅c焭q蝆y焲y蝋l蝍j蝏t焷p蝐m蝑x蝒m蝔j蝘y蝚r蝛w蝜f蝝y蝞m蝟w蝡r蝢x虾h蝧y蝨s蝩c蝪t蝫z蝬z蝭d蝯y蝱m蝲l蝳d蝵q蝷l蜗w蝹y蝺q蝿y螀j螁b蛳s螆c螇x螉w螊l螌b螎r螏j螑x螒h螔y螕b螖h螘y螙d螛h螜h螝g螠y螡w萤y螣t螤z巍w微w危w韦w违w桅w唯w惟w萎w委w尾w未w蔚w味w畏w胃w喂w魏w位w渭w谓w尉w慰w卫w瘟w蚊w文w燰w吻w紊w嗡w翁w爁l我w斡w握w沃w巫w钨w诬w屋w爗y爙r梧w吾w武w爠q五w捂w午w爥z舞w伍w侮w戊w雾w晤w物w勿w悟w误w昔x熙x析x西x硒x矽x晰x嘻x吸x牔b锡x螥c螦s螧q螩d螪s螮d螰l螱w螲d螴c螶q螷p螸y螹c蝼l螼q螾y螿j蟁w蟂x蟃w蛰z蟅z蝈g蟉l蟌c蟍l蟎m蟏x蟐c蟔m蟕z蟖s蟗q蟘t蟙z蟚p蟜j蟝q蟞b蟟l蟡g蟢x虮j蟤z蟦f蟧l蟨j蟩j蟫y狔n狚d蛲n猍l蟰x猏j蟱w蟳x蟴s蟵c蛏c蟷d蟸l蟺s蚁y蟼j蟽d蟿q蠀c蠁x蠂s蠄q蝇y虿c蠇l蠈z蠉x蠋z猽m蠌z蠍x蠎m蠏x蛴q蝾r蠒j蚝h獉z蠗z蠘j蠙b蠚h蠜f蠝l蠞j蠠m蛎l稀x息x希x悉x膝x夕x惜x熄x烯x溪x汐x犀x檄x袭x席x媳x喜x铣x洗x獹l隙x瞎x匣x霞x辖x暇x下x夏x掀x锨x先x仙x鲜x咸x贤x舷x闲x涎x嫌x显x险x腺x馅x陷x限x相x香x箱x襄x湘x乡x翔x祥x详x想x响x享x项x巷h橡x像x象x硝x霄x削x哮x销x消x宵x淆x蠤q蠥n蠦l蠧d蠨x蠩z蠪l蠫l蠬l蠭f蠮y蠯p蠰n蠳y蠴s蠵x瑊j瑘y蠸q瑦w瑸b璊m蠽j蠾z蠿z璠f衃p衆z衉k衋x衎k衏y衐q衑l衒x衕t衘x衦g衧y衪y甇y衱j衳z衴d衵r衶z衸j衺x衻r衼z袀j袃c袆h袇r畄l袉t袊l袌p袎y袏z袐b袑s袓j袔h袕x袗z袘y袙p畞m袚f畧l袝f袟z袠z袡r袣y袥t袦n袧g袨x袩z袪q小x孝x校j肖x疜x笑x效x楔x些x歇x疪b蝎x鞋x邪x斜x谐x械x卸x蟹x懈x痟x谢x屑x薪x痭b芯x锌x欣x辛x新x忻x心x信x衅x星x腥x猩x惺x刑x型x形x邢x行h醒x杏x性x姓x兄x胸x瘹d匈x雄x癁f熊x休x羞x朽x嗅x癊y锈x秀x袖x墟x戌q需x须x徐x许x蓄x酗x癦m旭x序x畜c絮n婿x轩x喧x宣x旋x玄x袬y袮m袯b袲c袳c袵r袶p袸j袹b袺j袻e袽r袿g裀y裃k裄h裇x裈k裋s裌j裍k裐j裑s裓g裖z裗l裚j裛y装z裞s裠q裦b裧c裩k裪t裫y裬l裭c裮c裯c裲l裵p裶f裷y裺y裻d制z裿y褀q褁g褃k褄q褅t褆t褈c褉x褋d褌k褍d褎x褏x褑y褔f褕y褖t褗y褘h褜p褝d褞y褟t褠g褢h褣r褤y褦n褧j褨s褩b褬s褭n褮y褯j褱h裢l褵l褷s选x眩x靴x薛x穴x雪x血x熏x循x旬x询x驯x巡x殉x汛x训x讯x逊x迅x押y鸦y鸭y丫y芽y牙y蚜y崖y衙y涯y雅y盶y讶y焉y阉y淹y盐y研y蜒y延y言y颜y阎y炎y沿y奄y掩y眼y衍y堰y燕y雁y唁y宴y谚y验y殃y央y鸯y秧y佯y羊y洋y氧y仰y养y漾y邀y腰y妖y褛l褹y褺d亵x褼x褽w褾b褿c襀j襃b襅q襆f襇j襈z襉j襊c襋j襌d襍z襎f襏b襑x襒b襓r襔m襕l襗z襘g襙c襚s襛n襜c裣l裆d襡s襢z襣b褴l襥f襧z襨t襩s襫s襭x襮b襰l襱l襳x襴l襵z襶d襷t襸z襹s襺j襼y襽l襾y覀y覂f覄f覅f覇b覉j瞈w覊j瞏q覌g覍b覎y瞔z覐j覑p覒m覔m覕p覗s觇c覙z覚j覛m覜t覝l覞y覟z覠j觋x遥y谣y姚y咬y舀y要y矊m耀y椰y噎y耶y野y冶y也y页y掖y腋y夜y液y一y壹y医y揖y铱y依y伊y衣y颐y夷y遗w移y胰y疑y沂y宜y姨y彝y椅y倚y已y乙y矣y以y抑y易y邑y屹g役y臆y逸y肄y疫y亦y裔y意y毅y益y溢y诣y议y谊y译y翼y翌y茵y因y音y阴y姻y吟y银y淫y寅y饮y尹y引y隐y覢s覣w覤x覥t觎y覧l矲b覨e覩d觊j覭m覮y觏g覰q覱z觐j観g覴d覵j覶l觑q覸j硡h硢y覻q覼l覾s觌d觃y觍t觕c觗z觘c觙j觛d觝d觟h觠q觡g觢s觤g觧j觨h觩q觪x觬n觭j觮j觰z觱b觲x觞s觵g觯z觷x觹x觺y觻l觼j觽x觾y觿x訁y訄q訅q訆j訉f訋d讧h訍c訏x讦j訑y訒r訔y讪s訙x訚y印y英y鹰y迎y赢y盈y影y硬y映y臃y庸y雍y踊y蛹y咏y碐l泳y永y恿y勇y用y幽y悠y尤y由y邮y铀y油y游y酉y碻q有y碽g友y磂l右y釉y诱y又y幼y迂y淤y于y盂y榆y虞y愚y舆y余y俞y逾y鱼y愉y渝y磭c隅y予y磰s雨y禹y宇y语y羽y玉y域y礃z芋y郁y遇y喻y峪y愈y育y誉y訞y訠s訡y讷n訦c訧y訨z訩x訫x訬c訮y訯s訰z訲y訳y訵c诃h訷s訸h訹x诊z注z证z訽g訿z詀z诂g詂f詃j詄d詅l诋d詇y詊p詋z詌g詍y讵j詏y诈z詑t诒y詓q诏z詖b礶g祍r祘s诎q詙b詚d诅z詜t詝z詟z诩x祱s詤h詥h祶d詧c詨x詪h诟g禈h诠q詯h诘j祯z詴w诜s詶c詷t詸m詻l诙h詽y詾x诖g誀e浴y寓y裕y预y豫y驭y鸳y冤y元y垣y袁y原y援y辕y猿y源y远y苑y愿y怨y院y曰y越y跃y钥y月y阅y耘y云y郧y陨y允y运y酝y韵y孕y匝z砸z杂z栽z哉z宰z载z再z在z赞z赃z葬z遭z糟z凿z藻z早z澡z蚤z躁z噪z造z皂z灶z燥z责z贼z怎z增z憎z曾c赠z喳c秢l渣z札z轧g誁b誂t誃y诔l诛z诓k誈w誋j志z誏l誐e诳k诶a誔t誖b誗c誙k诮q誛q誜s誝a誟x誢x诰g誧b誩j誫z説s読d誮h誯c誱j誳q誴c誵x谇s誷w誸x誺c誻t誾y諀p諁z谄c諃c谆z諅j諆j諈z诿w諊j諌d诤z諎z诹z諐q诼z諓j諔c諕x谂s諘b諙h諚b谀y諝x稬n谝p諟s諠x諡s诨h諣h稸x穉z铡z闸z眨z榨z咋z穙p乍z炸z摘z斋z穠n宅z窄z寨z瞻z詹z粘n沾z辗z展z蘸z站z湛z樟z章z彰z漳z掌z杖z丈z账z仗z瘴z障z招z昭z找z沼z赵z照z罩z兆z肇z召s遮z折s哲z辙z者z锗z蔗z这z浙z珍z斟z真z甄z砧z臻z贞z针z枕z疹z震z振z镇z阵z蒸z征z怔z整z拯z正z政z谔e諥z谛d諨f諩p諪t谏j諬q谕y谘z諯z諰x諲y谙a諴x諵n谌c诸z諹y諻h谖x窧z窽k谒y竌c竨d竪s诌z謆s謈b謉k謋h謌g謍y謏x竸j谧m謑x謒q謓c谑x謕t谡s謘c谥s謜y謞h謡y謢l謣y謤b謥c謧l谟m謩m謪s谪z謭j謮z謯j謰l謱l讴o謴g謵x謶z謷a謸a謺z謻y謼h謽j謿c譀h譂c譃x譄z譅s郑z芝z枝z支z吱z蜘z知z肢z脂z汁z之z直z植z殖s值z址z指z止z趾z旨z至z置z峙s智z秩z稚z质z炙z痔z治z窒z中z盅z筳t筴c忠z钟z衷z重c仲z舟z箈t周z州z洲z粥y轴z肘z帚z咒z宙z骤z珠z株z蛛z猪z逐z竹z煮z拄z主z著z柱z助z蛀z贮z铸z譆x譇z譈d譊n譋l譌e谲j譐z譑j譒b譓h譔z譕w谮z譗z谯q譛j譝s譞x譠t譡d譢s譣x譤j譥j譧z譨n譩y谵z譭h譮h譱s譲r譳r篒y譶t譸z譹h譺a譻y譼j譾j譿h讁z讂j讃z讄l讅s讆w讇c讉y讋z篻p讌y讍e雠c讏w讐c讑y讔y谶c讗x讘n讙h讛y谠d讝z谳y讟d讬t讱r讻x诇x诐b诪z谉s谞x住z祝z驻z抓z爪z拽z转z撰z赚z篆z撞z椎c锥z追z赘z捉z拙z卓z桌z琢z茁z酌z啄z着z灼z咨z资z姿z滋z淄z孜z紫z仔z籽z滓z自z字z鬃z棕z踪z宗z邹z走z奏z揍z租z足z卒c族z祖z阻z钻z纂z嘴z醉z最z罪z尊z遵z昨z左z佐z柞z做z作z坐z座z谸q谹h谺x谻j谼h谽h谾h谿x豀x豂l豃h豄d豅l豋d豍b豏x豑z豒z豓y籋n豖c豗h豘t豙y豛y豜j豝b豞h豟e豠c豣j豤k豥g豦j豧f豨x豩b豭j豮f豯x豰h豱w豲h豴d豵z豷y豻a豼p豽n豾p豿g貀n貁y貃m貄s貆h貇k貈h貋a貎n貏b貐y貑j貒t貕x貖y貗j貙c貚t貛h貜j粎m粓g貟y粡t貣d貤y貦w貭z亍c丌q兀w丐g廿n卅s丕p丞c鬲g孬n噩e丨g禺o丿p匕b乇z夭a爻y卮z氐d囟x胤y馗k毓y鼗t丶z亟j鼐n乜m亓q孛b嘏g厝c厥j靥y赝y匚f叵p糂s匾b赜z卦g卣y刂d刈y刎w刳k剌l糛t剞j剡s剜w蒯k剽p劂j劁q劐h劓y冂j罔w亻r仃d仉z仨s糿g仫m仞r仳p伢y佤w仵w伉k紤j佞n佧k攸y佚y佝g貮e贳s貱b赀z貵p貹s贶k絾c綛k綥q緛r繏x繑q繝j纄p纋y纕x纚l缿x翄c翭h翺a耛s聎t肒h肸x胋t胑z胻h脦t脺c脻j腟c臒w臤q臱m舋x舿k艕b芀t芁q芖z苚y茟y茰y莍q菻l萂h萿k葔h蔝m蔨j蔴m蕮x薆a莶x藱h藼x蘀t蘃r蘒q蘓s蘹h虂l虆l虨b虶y虷h蚅e蚔q蚭n蚿x蛯e蝖x螐w螚n蟭j蠷q蠺c衂n衭f袛d袾z襂s襐x覫p覹w觓q訤x詉n詗x詺m誎c誽n諽g諿x謃x謟t謲c譍y譪a譵d貥h乩j仡g斛h颢h銮l乊h乥h夫f兓j兙s兛q兝g兞h兣g兺b囻g坟f妢f婲h孒j尅k屗u岎f帉f幥z幩f弅f徚u怭b怾g慙c昐f晲n曢u朆f朌f朑u朩p枌f梤f乐l橨f檂n欂b毜c毮s洂y涜d颍y澵z炃f炍p炾h烪u焑y焺s燌f燓f燞u燢x獖f瓧s瓰f瓱m瓲t瓼l榛z彳c夔k璞p丟d並b丬p乂y乄s亙g亞y亠t亳b仝t伋j伕f伲n伽g佇z佈b佔z佗t佘s佟t佪h佴e併b佶j佻t佼j佾y侃k來l侉k侏z侑y侔m侖l侶l侷j俅q俎z俑y俚l俜p俟q俠x俳p俸f俾b倆l倉c個g倌g倏s們m倖x倜t倣f倥k倨j倩q倫l倬z倭w倮l偃y偈j偉w偌r偎w偕x側c偵z偺z偽w傖c傘s備b傢j傭y傳c傴y債z傷s傺c傾q僂l僅j僇l僉q僑q僕p僖x僥j僦j僬j僭j僮t僱g價j儀y儂n億y儅d儆j儇x儉j儋d儐b儔c儕c儘j優y儲c儷l儸l儺n儻t儼y兌d兒e兕s兗y內n兩l兮x冊c冑z冖m冢z冥m冪m冫b冱h冼x冽l凇s凈j凍d凫f凱k凵k凼d刖y別b刪s剄j則z剋k剎c剛g剝b剮g剴k創c剷c劃h劇j劉l劊g劌g劍j劑j劬q劭s劻k劾h勁j勐m動d勗x務w勛x勝s勞l勢s勣j勦j勰x勱m勵l勹b勻y匍p匏p匐f匭g匯h匱k區q協x卟b卩j卹x卻q厙s厭y厲l厴y厶s參c叟s叢c叨d叩k叱c叻l吆y吋c吒z吖y吡b吣q吲y吳w吶n呂l呃e呋f呎c呔d呤l呦y呱g呲c呶n呷g咂z咄d咔k咚d咝s咣g咤c咦y咧l咩m咪m咫z咭j咻x咼w咿y哂s哌p哏g哐k哚d哞m員y哧c哳z哽g哿g唄b唅h唏x唑z唔m唣z唧j唪f唰s唳l唷y唸n唼s唿h啁z啉l問w啐c啕t啖d啞y啟q啣x啵b啶d啷l啻c啾j喁y喃n喈j喋z喏n喑y喔o喙h喚h喟k喪s喫c喬q單d喱l喵m嗄a嗆q嗇s嗉s嗌y嗍s嗎m嗑k嗒d嗔c嗖s嗚w嗝g嗟j嗤c嗥h嗦s嗨h嗪q嗬h嗲d嗵t嗶b嗷a嗾s嘀d嘁q嘈c嘌p嘍l嘔o嘖z嘜m嘞l嘟d嘣b嘧m嘩h嘬c嘭p嘮l嘯x嘰j嘵x嘸f嘹l噁e噌c噍j噓x噔d噗p噘j噙q噠d噢o噤j噥n噦y噫a噯a噱j噲k噴p噸d噹d噻s噼p嚀n嚅r嚆h嚇h嚌j嚐c嚓c嚙n嚥y嚦l嚨l嚮x嚯h嚳k嚴y囀z囁n囂x囅c囈y囉l囌s囑z囔n囗w囝j囡n囪c囫h囹l囿y圄y圇l圉y圊q國g圍w園y圓y圖t圜h圩w圪g圮p圯y圳z圻q坂b坌b坨t坩g坫d坭n坰j坳a坶m坻c坼c垅l垌d垓g垠y垡f垤d垴n埏s埒l埕c埝n埡y埤p埭d埯a埴z執z埸y埽s堀k堅j堇j堊e堋b堍t堙y堞d堠h報b場c堿j塄l塊k塋y塍c塒s塗t塢w塤x塥g塬y塵c塹q塾s墀c墁m墉y墊d墑d墚l墜z墮d墻q壅y壇t壑h壓y壙k壚l壞h壟l壢l壩b壯z壺h壽s夂z夙s夠g夢m夤y夥h夼k夾j奐h奕y奘z奚x奧a奪d妁s妃f妍y妗j妝z妞n妣b妤y妯z妲d妳n妾q姊z姍s姒s姘p姝s姣j姦j姪z姹c娉p娌l娑s娓w娛y娣d娼c婀e婊b婕j婢b婦f婧j婭y婷t婺w媛y媧w媯g媲p媸c媼a媽m媾g嫖p嫗y嫘l嫜z嫠l嫣y嫦c嫫m嫵w嫻x嬈r嬉x嬌j嬖b嬗s嬙q嬝n嬡a嬤m嬰y嬲n嬴y嬸s孀s孃n孑j孓j孚f孢b孥n孫s孱c孳z學x孿l宀m宄g宓m宕d宥y宮g宸c寢q寤w實s寧n審s寫x寬k寮l寰h寵c寶b將j專z尋x對d尕g尜g尢w尥l尬g尷g尻k屄b屆j屐j屙e屜t屣x層c屬s屮c屺q岈y岌j岍q岐q岑c岙a岜b岡g岢k岣g岧t岫x岬j岱d岵h岷m峁m峋x峒d峴x島d峽x崆k崍l崗g崙l崛j崞g崠d崢z崤x崦y崧s崮g崴w崽z崾y嵇j嵊s嵋m嵒y嵩s嵫z嵬w嵯c嵴j嶁l嶂z嶄z嶇q嶗l嶙l嶷n嶸r嶺l嶼y嶽y巋k巑c巔d巖y巛c巰q巹j巽x帑t帔p帙z帥s帳z帶d帷w幃w幄w幔m幘z幛z幞f幟z幡f幣b幪m幫b幬c幹g幺y幾j庀p庂z庋g庖p庠x庥x庫k庳b庹t庾y廁c廂x廄j廈s廑q廒a廚c廛c廝s廡w廢f廣g廨x廩l廬l廱y廳t廴y廾g弁b弈y弋y弒s弔d弩n弭m弳j張z強q弼b彀g彆b彈d彊q彌m彎w彐x彖t彗h彘z彙h彡s彥y彫d彷f彿f徂c徇x徉y後h徑j徙x徜c從c徠l徨h復f徫w徬p徭y徵z徹c徼j忉d忐t忑t忒t忖c忝t忡c忤w忪s忭b忮z忸n怊c怍z怏y怙h怛d怡y怦p怩n怫f怵c恁n恂x恆h恙y恚h恝j恣z恥c恧n恪k悃k悅y悌t悒y悖b悚s悛q悝k悱f悴c悵c悶m悻x悽q惆c惘w惙c惝t惡e惱n惲y惴z惻c愀q愆q愍m愎b愕e愛a愜q愣l愨q愫s愴c愾k慄l慇y慊q態t慍y慘c慚c慝t慟t慣g慫s慮l慵y慶q慼q慾y憂y憊b憐l憑p憔q憚d憝d憧c憩q憫m憬j憲x憶y憷c懇k應y懋m懌y懍l懔l懞m懟d懣m懨y懲c懵m懶l懷h懺c懼j懾s懿y戀l戇g戉y戔j戕q戛j戟j戡k戢j戤g戥d戧q戩j戰z戲x戶h戽h戾l扃j扈h扌s扐c扠c扢g扺z抃b抆w抎y抴y抻c拊f拋p拗a拮j拶z挈q挲s挶j挹y挾x捃j捋l捨s捩l捫m捭b捱a捺n掃s掄l掊p掎j掙z掛g採c掬j掭t掮q掰b掾y揀j揄y揆k揎x揚y換h揞a揠y揲d揶y揸z揹b搆g搋c搌z損s搖y搗d搛j搟x搠s搡s搦n搴q搶q搿g摁e摑g摒b摜g摞l摟l摭z摯z摳k摶t摺z摻c撈l撓n撙z撚n撟j撣d撥b撫f撲p撻t撾z撿j擁y擄l擇z擊j擐h擔d擗p擘b據j擠j擢z擣d擤x擬n擯b擰n擱g擲z擴k擷x擺b擻s擼l擾r攄s攆n攉h攏l攔l攖y攙c攛c攜x攝s攢z攣l攤t攥z攬l攮n攴p攷k敉m敕c敗b敘x敫j敵d斂l斃b斐f斕l斫z斬z斷d於w旂q旃z旄m旆p旌j旎n旒l旖y旮g旯l旰g昀y昃z昇s昊h昕x昝z昱y昴m昶c晁c時s晉j晏y晗h晝z晞x晟c晡b晷g暄x暈y暉h暌k暘y暝m暨j暫z暱n暸l暹x暾t曄y曆l曇t曉x曖a曛x曜y曠k曩n曬s曷h書s會h朊r朐q朕z朦m朧l朮s杇w杈c杌w杓b杞q杪m東d杲g杳y杵c杷b杼z枇p枋f枘r枙e枰p枳z枵x枸g柁d柃l柘z柚y柝t柢d柩j柰n柵s栝g栩x栲k栳l桀j桁h桄g桉a桊j桎z桕j桫s桴f桷j桿g梃t梏g梓z梔z條t梟x梩q梵f棄q棖c棗z棟d棣d棧z棰c棲q棹z棼f椋l椏y椐j椴d椹s楂c楊y楓f楗j楝l楠n楣m楦x楨z楫j業y楮c楱c極j楸q楹y榀p榍x榕r榘j榙t榧f榪m榫s榭x榮r榱c榻t榿q槃p槊s槌c槍q槎c槓g槧q槨g槭q槲h槳j槿j樁z樂l樅c樑l樓l樗c樘t標b樞s樨x樵q樸p樹s樺h樽z樾y橄g橈r橋q橐t橘j橛j機j橢t橫h檁l檉c檎q檔d檗b檜g檠q檢j檫c檯t檳b檸n檻j櫓l櫚l櫛z櫝d櫟l櫥c櫧z櫨l櫪l櫬c櫳l櫸j櫺l櫻y欄l權q欏l欒l欖l欞l欷x欹q歃s歆x歎t歐o歙s歟y歡h歲s歷l歿m殂c殄t殍p殘c殞y殤s殪y殫d殮l殯b殲j殳s殺s殼k毀h毂g毆o毌g毪m毬q毳c毹s毽j毿s氅c氆p氈z氌l氍q氕p氘d氙x氚c氡d氣q氤y氪k氫q氬y氳y氵s氽c氾f汆c汊c汍w汎f汔q汜s汨m汩g汴b汶w決j沅y沆h沌d沐m沒m沓d沔m沖c沭s沱t沲t泐l泓h泔g泖m泗s泠l泫x泮p泯m泱y洄h洇y洌l洎j洙z洚j洧w洩x洫x洮t洳r洵x洶x洹h浜b浞z浠x浣h浬h浯w浹j浼m涇j涑s涓j涔c涫g涮s涼l涿z淅x淇q淒q淙c淚l淝f淞s淠p淥l淦g淨j淪l淵y淶l淼m渙h渚z減j渥w渦w渫x測c渲x渾h湄m湊c湎m湓p湔j湞z湟h湧y湫j湮y湯t溆x溏t準z溘k溝g溟m溥p溧l溫w溱q溲s溴x溷h溻t溼s溽r滂p滄c滅m滎x滏f滕t滟y滬h滯z滲s滷l滸h滹h滾g滿m漉l漕c漚o漢h漣l漤l漩x漪y漬z漭m漯l漲z漶h漸j漿j潁y潑p潔j潛q潟x潢h潤r潯x潰k潲s潴z潷b潸s潺c潼t澀s澆j澇l澉g澌s澍s澗j澠m澤d澧l澩x澮k澱d澶c澹d濂l濃n濉s濕s濘n濛m濞b濟j濠h濡r濤t濫l濮p濯z濰w濱b濺j濼l瀅y瀆d瀉x瀋s瀏l瀕b瀘l瀚h瀛y瀝l瀟x瀠y瀣x瀧l瀨l瀰m瀲l瀵f瀹y灃f灄s灑s灕l灘t灝h灞b灣w灤l灬h災z炅g炫x炱t為w炻s烀h烊y烏w焐w焓h無w焯c焱y煅d煉l煊x煒w煙y煜y煢q煦x煨w煩f煬y煲b煳h煸b煺t熒y熗q熘l熠y熨y熱r熳m熵s熹x熾c燁y燄y燉d燐l燒s燔f燙t營y燠y燦c燧s燬h燭z燮x燴h燹x燼j燾d爐l爛l爝j爨c爭z爰y爺y爾e爿p牆q牒d牖y牘d牝p牠t牦m牪y牮j牯g牴d牽q牿g犄j犍j犏p犒k犛l犟j犧x犭q犰q犴a犸m狀z狁y狃n狍p狎x狒f狨r狩s狳y狴b狷j狹x狺y狻s狽b猁l猊n猓g猗y猙z猝c猞s猢h猥w猬w猱n猶y猷y猸m猹c猻s獄y獅s獍j獐z獒a獗j獠l獨d獪k獫x獬x獯x獰n獲h獵l獷g獸s獺t獻x獼m獾h玀l玆z玎d玟m玢b玨j玳d玷d珀p珂k珈j珉m珙g珞l珥e珧y珩h珮p現x琊y琚j琛c琥h琦q琨k琪q琬w琮c琰y琺f琿h瑁m瑕x瑗y瑙n瑛y瑜y瑣s瑤y瑩y瑪m瑭t瑯l瑾j璀c璇x璉l璋z璐l璜h璣j璦a璧b璨c璩q璺w璽x瓊q瓏l瓖x瓚z瓞d瓠h瓴l瓿b甍m甏b甑z甓p甙d產c甦s甬y町d甾z畀b畈f畋t畎q畚b畛z畝m畫h畬s異y畹w畼c畿j疃t疊d疋y疒n疔d疝s疣y疬l疰z疳g疴k疸d疿f痂j痃x痄z痍y痖y痙j痣z痤c痦w痧s痲m痳m痼g痿w瘀y瘃z瘊h瘌l瘍y瘐y瘓h瘕j瘙s瘛c瘞y瘠j瘡c瘢b瘥c瘭b瘰l瘳c瘺l瘼m癀h療l癃l癆l癇x癍b癔y癖p癜d癟b癡c癢y癥z癩l癬x癭y癮y癯q癰y癱t癲d發f皈b皎j皓h皙x皚a皤f皰p皴c皸j皺z皻z盍h盜d盞z盡j監j盤p盥g盧l盪d盱x盹d眄m眇m眈d眍k眚s眢y眣d眥z眭s眵c眸m睇d睏k睚y睜z睞l睢s睥b睨n睪y睽k睿r瞀m瞌k瞍s瞑m瞞m瞟p瞠c瞢m瞭l瞰k瞵l瞼j瞽g瞿j矇m矍j矓l矚z矜j矧s矬c矯j矸g砉h砑y砘d砜f砝f砟z砣t砥d砩f砬l砭b砲p砹a砼t硃z硇n硌g硎x硐d硤x硨c硪w硭m硯y碇d碓d碚b碣j碥b碩s碲d碹x碼m磉s磔z磙g磚z磣c磧q磬q磯j磲q磴d礅d礎c礓j礙a礞m礤c礦k礪l礫l礱l礴b礻s祀s祅y祇q祉z祐y祓f祕m祗q祚z祛q祜h祠c祧t祺q祿l禊x禍h禎z禚z禦y禧x禮l禰m禱d禳r禿t秈x秕b秣m秫s秭z稂l稃f稅s稆l稈g稔r稜l稞k稟b種z稱c稷j稹z穀g穌s積j穢h穩w穫h穰r穸x穹q窀z窆b窈y窕t窠k窨x窩w窪w窬y窮q窯y窳y窶j窺k竄c竅q竊q竦s競j竺d竽y笄j笈j笊z笏h笙s笞c笠l笤t笥s笪d笫z笮z笱g笳j笸p笻q筆b筌q筍s筘k筠j筢p筮s筲s筵y筻g箄b箇g箋j箏z箐q箜k箝q箬r箴z箸z節j篁h範f築z篋q篌h篚f篝g篠x篤d篥l篦b篩s篪c篳b篼d篾m簀z簋g簌s簍l簏l簑s簟d簡j簣k簦d簪z簫x簷y簸b簽q簾l籀z籃l籌c籐t籜t籟l籠l籤q籥y籩b籪d籬l籮l籲y粑b粞x粢z粧z粲c粵y粼l粽z糅r糇h糈x糌z糍c糗q糝s糢m糧l糨j糰t糲l糴d糶t糸m糾j紀j紂z約y紅h紇h紈w紉r紋w納n紐n紓s紕p紗s紙z級j紜y紡f紮z細x紱f紲x紳s紹s紺g紼f紿d絀c終z絃x組z絆b絎h結j絛t絞j絡l絢x給g絨r統t絲s絳j絹j綁b綃x綆g綈t綏s綑k經j綜z綞d綠l綢c綣q綦q綬s維w綮q綰w綱g網w綴z綵c綸l綹l綺q綻z綾l綿m緇z緊j緋f緒x緗x緘j緙k線x緝j緞d締d緡m緣y緦s編b緩h緬m緯w緱g緲m練l緶b緹t緻z縈y縉j縊y縐z縑j縚t縛f縝z縞g縟r縣x縫f縭l縮s縯y縱z縳z縴q縵m縶z縷l縹p縻m總z績j繅s繆m繇y繈q繒z織z繕s繚l繞r繡x繢h繩s繪h繫x繭j繯h繰q繳j繹y繼j繾q纈x纊k續x纍l纏c纓y纔c纖x纘z纛d纜l纟s绔k绛j绱s缰j缶f缽b罄q罅x罈t罌y罘f罟g罡g罨y罰f罱l罵m罹l罾z羅l羆p羈j羋m羝d羧s義y羯j羰t羲x羸l羼c羿y翊y翎l習x翕x翡f翥z翦j翩p翮h翳y翹q耄m耆q耋d耑d耒l耔z耖c耜s耠h耢l耥t耦o耨n耩j耬l耱m耵d耷d聃d聆l聒g聞w聯l聰c聱a聲s聳s聵k聶n職z聹n聽t聾l聿y肅s肓h肜c肟w肫z肭n肱g肴y肷q肼j肽t胂s胍g胗z胛j胝z胥x胨d胩k胬n胭y胱g胲h胴d胼p脅x脈m脎s脒m脘w脛j脞c脣c脧j脩x脫t脬p脲n脹z腈j腌a腎s腓f腙z腚d腠c腡l腦n腧s腩n腫z腭e腱j腴y腸c腼m膂l膃w膈g膚f膠j膦l膪c膺y膻s膽d膾k膿n臁l臉l臊s臌g臍q臏b臚l臟z臠l臧z臨l臬n臾y舁y舂c舄x與y興x舉j舊j舐s舖p舛c舡c舢s舨b舫f舭b舯z舳z舴z舸g舺x舾x艄s艉w艋m艏s艚c艟c艣l艦j艨m艫l艮g艱j艴f艷y艸c艽j艿n芄w芊q芎x芏d芑q芘b芙f芟s芡q芤k芨j芩q芪q芫y芮r芰j芴w芷z芻c芾f苊e苒r苓l苕s苘q苜m苠m苡y苣j苤p苧n苴j苷g苻f茆m茇b茈c茉m茌c茍j茗m茚y茛g茜q茭j茯f茱z茲z茳j茴h茺c茼t荀x荃q荇x荊j荏r荑t荬m荸b荻d荼a荽s莊z莒j莓m莘s莛t莞g莠y莢j莧x莨l莩f莪e莰k莺y莼c菀w菁j菅j菔f菖c菘s菝b菟t菡h菥x華h菰g菸y菹z菽s萁q萃c萆b萊l萋q萏d萑h萘n萜t萬w萱x萵w萸y萼e葆b葉y葑f葙x葚r葜q葦w葩p葭j葯y葳w葶t葷h葸x葺q蒈k蒎p蒔s蒗l蒞l蒡b蒴s蒺j蒼c蒽e蒿h蓁z蓊w蓋g蓍s蓐r蓓b蓥y蓦m蓯c蓰x蓼l蓽b蔌s蔔b蔟c蔣j蔥c蔦n蔭y蔸d蔻k蕁q蕃f蕈x蕎q蕓y蕕y蕖q蕙h蕞z蕢k蕤r蕨j蕩d蕪w蕭x蕷y蕹w蕺j蕻h薅h薇w薈h薊j薌x薏y薑j薔q薜b薟x薤x薦j薧h薨h薩s薰x薷r薹t薺j藁g藍l藎j藜l藝y藥y藪s藶l藷s藹a藺l藿h蘄q蘅h蘆l蘇s蘊y蘋p蘗b蘚x蘢l蘧q蘩f蘭l蘺l蘼m蘿l虍h虔q處c虛x虜l號h虢g虧k虬q虺h虻m蚋r蚍p蚓y蚣g蚧j蚨f蚩c蚪d蚯q蚰y蚱z蚴y蚵k蚶h蚺r蛄g蛅z蛉l蛐q蛑m蛘y蛞k蛟j蛩q蛭z蛸s蛺j蛻t蜃s蜆x蜇z蜈w蜉f蜊l蜍c蜓t蜚f蜞q蜢m蜣q蜥x蜩t蜮y蜱p蜷q蜻q蜾g蜿w蝌k蝓y蝕s蝙b蝠f蝣y蝤q蝥m蝦x蝮f蝰k蝸w蝻n蝽c螂l螃p螅x螋s螓q螗t螞m螢y螨m螫s螬c螭c螯a螳t螵p螻l螽z蟀s蟄z蟆m蟈g蟊m蟋x蟑z蟒m蟓x蟠p蟥h蟪h蟬c蟮s蟯n蟲c蟶c蟻y蟾c蠃l蠅y蠆c蠊l蠐q蠑r蠓m蠔h蠖h蠛m蠟l蠡l蠣l蠱g蠲j蠹d蠼q衄n術s衛w衝c衢q衤y衩c衲n衹z衽r衾q衿j袂m袈j袞g袢p袤m袷q裊n裎c裏l裒p裘q補b裝z裟s裡l裥j裨b裰d裱b裼t製z裾j複f褊b褓b褙b褚c褡d褫c褰q褲k褳l褶z褻x襝l襞b襠d襤l襦r襪w襬b襯c襻p覃q見j規g覓m視s覘c覡x覦y親q覬j覯g覲j覷q覺j覽l覿d觖j觚g觜z觥g觫s觳h觴s觶z觸c訂d訃f訇h訊x訌h討t訐j訓x訕s訖q託t記j訛e訝y訢x訣j訪f設s許x訴s診z註z証z訾z詁g詆d詈l詎j詐z詒y詔z評p詘q詛z詞c詠y詡x詢x詣y詩s詫c詭g詮q話h該g詵s詼h誅z誆k誇k誌z認r誑k誕d誘y誚q語y誠c誡j誣w誤w誥g誨h誰s課k誶s誼y調d諂c諄z談t諉w請q諍z諏z諑z諒l論l諗s諛y諜d諞p諢h諤e諧x諫j諮z諱h諳a諶c諷f諸z諺y諾n謀m謁y謂w謅z謇j謊h謎m謐m謔x謗b謙q謚s講j謝x謠y謦q謨m謫z謬m謳o謹j譁h證z譎j譖z識s譙q譚t譜p譟z譫z譯y議y譴q護h譽y讀d讎c讒c讓r讕l讖c讚z谫j豇j豈q豉c豎s豐f豔y豕s豚t豬z豳b豸z貂d貅x貊m貍l貓m貔p貘m貝b負f財c貢g貧p貨h販f貪t貫g責z貯z貰s貲z貳e貴g貶b貸d貺k貼t貾c貿m賁b賂l賃l賄h賅g賆p資z賈j賉x賊z賋j賌g賎j賏y賐j賑z賒s賓b賔b賕q賖s賗c賘z賙z賛z賜c賝c賞s賟t賠p賡g賢x賣m賤j賥s賧d賨c賩c質z賬z賭d賮j賯x賰c賳z賴l賵f賶c賷j賸s賹y賺z賻f購g賽s賾z賿l贀y贂c贃w贄z贅z贆b贇y贈z贉d贊z贋y贌p贍s贎w贏y贐j贑g贒x贓z贔b贕d贗y贘s贙x贚l贛g贜z贠y贲b贻y贽z赅g赆j赇q赈z赉l赍j赑b赒z赓g赕d赗f赙f赟y赥x赧n赨t赩x赪c赬c赭z赮x赯t赱z赲l赳j赸s赹q赺y赻x赼z赽j赿c趂c趃d趄j趆d趇x趈z趉j趌j趍q趎c趏g趐x趑z趔l趖s趗c趘x趚s趜j趝j趞q趠c趡c趤d趥q趧t趨q趩c趪h趫q趭j趮z趯t趰e趱z趲z趵b趷k趹j趺f趻c趼j趽f趿t跁b跂q跄q跅t跆t跇y跈j跉l跍k跎t跏j跐c跒q跓z跔j跕d跖z跗f跘p跙j跚s跛b跜n跞l跠y跡j跢d跣x跤j跦z跧q跩z跫q跬k跭x跰p跱z跲j跴c跶d跷q跸b跹x跻j跼j跽j跾s跿t踀c踁j踂n踃x踄b踅x踆c踈s踉l踍q踎m踑j踒w踓w踔c踕j踗n踘j踙n踚l踛l踝h踟c踡j踣b踥q踦q踧c踫p踬z踭z踮d踯z踰y踱d踲d踳c踴y踵z踶d踷z踸c踹c踺j踻g踽j踾f踿c蹀d蹁p蹂r蹃n蹇j蹉c蹊q蹍n蹐j蹑n蹒p蹓l蹔z蹕b蹖c蹗l蹘l蹙c蹚t蹛d蹜s蹝x蹞k蹟j蹠z蹡q蹢d蹣p蹤z蹥l蹧z蹨n蹩b蹪t蹫j蹮x蹯f蹰c蹱z蹳b蹴c蹵c蹶g蹷j蹸l蹹t蹺q蹻q蹼p蹽l蹾d躀g躂d躃b躄b躅z躆j躈q躉d躊c躋j躍y躎n躏l躐l躑z躒l躓z躔c躕c躖d躗w躘l躙l躚x躛w躜z躝l躞x躟r躠s躡n躢t躣q躥c躦z躧x躨k躩j躭d躮s躰t躱d躵h躶l躷a躸j躹j躻w躽y躾x躿k軀q軁l軃d軄z軆t軇d軉y車c軋y軌g軎w軏y軐x軑d軒x軓f軔r軕s軖k軗s軘t軙c軚d軜n軝q軟r軠k軡q転z軣h軤h軥q軦k軧d軨l軩d軪a軫z軬f軮y軰b軱g軲g軴z軵r軶e軷b軹z軺y軻k軼y軽q軾s軿p輀e輁g輂j較j輄g輅l輆k輈z載z輋s輌l輍y輎s輏y輐w輓w輔f輕q輖z輗n輘l輙z輚z輛l輝h輞w輟c輡k輢y輣p輤q輥g輦n輨g輩b輫p輬l輭r輮r輰y輱x輲c輴c輵g輶y輷h輸s輹f輺z輻f輽f輾z輿y轀w轁t轂g轃z轄x轅y轆l轇j轈c轉z轊w轍z轎j轏z轐b轑l轔l轖s轗k轘h俁y係x轛d轝y轞j轟h轠l轡p轢l倀c轤l轥l轪d轫r轭e轱g轲k轳l轵z轶y轷h轸z轹l轺y轼s轾z辁q辂l辄z辇n辋w辌l辍c辏c辒w辔p辘l傑j辚l辝c辠z辡b辢l辥x辦b辪x辬b辮b辯b農n辳n辵c辶c辷y辸r辻s込y辿c迃y迆y迉q迊b迋w迌t迍z迏d儈k迕w迖d迗e迚d迤y迥j迨d迩e迬z迮z迯t迱y迲k迳j迴h迵d迺n迻y凜l迾l逄p逅h逇d逈j逋b逍x逎q逑q逓d逕j逖t這z逜w逡q連l逥h逦l逧g逨l逪c逬b逭h逯l週z進j逳y逴c逵k逶w逷t逹d逺y勸q遀s遄c遅c遈s遊y運y遌e過g遐x遑h遒q遖n遘g遙y遛l遜x遝t遞d遟c遠y遡s遢t遤h遦g遨a遪c遫c遯d遲c咴h遴l遶r遷q選x遹y遺y遻e遼l遽j遾s邁m邂x邃s還h邅z邆t邇e邈m邉b邊b邋l邌l邏l邒t邔q邕y邖s邘y邙m邛q邜x邝k邟k邠b邡f邥s邧y邬w邭j邰t邲b邳p邴b邶b邷w邸d邺y邼k邾z邿s喹k郀k郂g郃h郄q郅z郆j郇x郈h郉x郍n嗩s郏j郐k郒l郓y郔y郕c郖d郗x郘l郙f嘆t郚w郛f郜g郟j郠g嘗c郢y郤x郥b郦l郪q郫p郮z郯t郱p郳n郵y郶b郷x郹j郻q郾y郿m鄀r鄁b鄃s鄄j鄆y鄇h鄈k鄉x嚕l鄊x鄌t鄎x鄏r鄐c鄑z鄓y嚶y鄔w鄕x鄗h鄚m鄛c鄜f鄝l鄞y鄟z鄠h鄡q鄢y鄣z鄥q鄦x鄨b鄫z鄬w鄭z鄮m鄯s鄰l鄱p鄲d鄴y鄵c鄶k鄷f鄸m團t鄺k鄻l鄼z鄽c鄾y酀y酁c酂z酃l酄h酆f酇z酈l酊d酎z酏y酐g酑y酓y酔z酕m酖d酘d酙z酛k酜f酟t酠q酡t酢c酤g酦f垸y酧c酩m酫c酭y酯z酰x酲c酴t酹l酺p酻z堝g酾s醀w醁l醂l醃y醄t醅p醊z醌k醍t醎x醏d醐h醑x醕c醖y醗p醘k醙s醜c醝c醞y醟y醠a醡z醢h醣t醤j醥p醧y醨l醩z醪l醫y醬j醭b醮j醯x醰t醱p醲n醳y醴l醵j醶y醷y醸n醹r醺x醻c醼y醽l醾m醿m墼j釁x釃s釄m釅y壎x釆b壘l釐l釓g釖d奩l釘d釚q釛h針z釞z釟b釡f釣d釦k釧c釨z釩f釬h釭g釮q釰r釱d釲s釳x釴y釵c釶s釷t釸x釹n釺q釻q釼r釽p釾y鈀b鈁f鈂c鈅y鈆q嬋c鈉n鈊x鈋e鈌j鈍d嬪p孌l鈐q鈒s鈓r鈔c鈕n鈗y鈘y鈛g鈜h鈞j導d鈡z鈢x鈣g鈤r鈥h鈦t鈧k屝f鈫q鈬d鈭z鈮n鈯t鈰s鈲g鈳k鈴l屨j鈶s鈷g鈸b鈹p鈺y鈻s鈼z鈽b鉁z鉂s鉃s鉄t鉆z鉈t鉉x鉊z鉋b鉌h鉍b鉎s鉏c鉐s鉑b鉓c鉕p鉖t鉘f鉙z鉚m鉛q鉜f鉝l鉟p鉠y鉣j鉤g鉦z崳y鉨x鉩x鉪d鉫j鉭t鉮s嵐l鉯y鉰s鉱k鉶x鉷h鉸j鉹c鉺e鉻g鉼b嶝d鉿h嶧y銀y銂z巒l銄x銆m銇l銈j銉y銊x銋r銌z師s銎q銏s銒x銓q銔p銖z銙k銚d銛x銜x銝x銞j銟c銢p銥y銦y銧g銩d銪y銭q銯k銲h銳r銴s廟m銵k廠c銶q銷x銸z銺z銻t鋀t鋁l鋂m鋄w鋅x鋆y鋇b鋈w鋉s鋋c鋌t鋎h鋑j鋕z鋖s鋗x鋘h鋙w鋚t鋛k忄x鋞x鋟q鋠s鋡h鋢l鋣y鋤c鋥z鋦j鋧x鋨e鋩m鋪p鋬p鋭r鋮c鋯g鋰l鋳z鋴z鋵t惚h鋷z鋸j鋹c鋺y愷k鋼g鋽d鋿s錀l慪o錁k錂l錃p慳q憒k錅l憮w錇p錉m錊z錋p錌a錍p錎x錏y懸x錑l錒a錓k錕k錗n錘c錙z錚z錜n錞c錟t錠d錡q錢q錣z錤j錥y錦j錧g錨m錩c錪t捲j錬l錭d錮g錯c錱z録l錳m錴l錵h錷g錸l錹k錺k錻b揮h錼n錽w錾z錿h鍀d鍁x鍄l鍆m鍇k鍈y鍉c鍊l鍋g鍌x鍍d鍏w鍐z鍑f鍒r鍓j鍔e鍕j鍖c鍗t撐c鍘z鍙h鍚y撖h鍛d撘d撢d撳q擋d鍞k鍟s鍠h鍡w鍢f鍣z鍤c鍥q鍦s鍧h鍨k鍩n鍪m鍫q鍬q鍭h鍯c鍱y鍲m鍳j鍵j鍶s鍷k鍸h鍹x攪j鍺z鍻j鍼z鍽b鍾z鍿z鎀x鎁y鎂m鎃p鎄a鎅j鎆q鎇m鎈c鎉d鎊b攵p鎋x鎌l鎍s數s鎏l鎐y鎑y鎒n鎓w鎔r鎕t鎖s鎘g鎙s鎛b鎜p鎝d鎞b鎟s鎠g鎡z鎤h暢c鎦l鎧k鎨s鎩s鎪s鎫w鎬g鎭z鎮z鎯l鎰y鎱y鎲t鎳n鎴x鎵j鎶g鎷m鎸j鎹k鎺h鎻s鎼x鎽f鎾w鎿n鏀l鏁s鏂o鏃z鏄t鏅x鏆g鏇x鏈l鏉s鏊a鏋m鏌m鏍l鏎b鏏w鏐l鏑d鏒s鏔y鏕l鏖a鏗k鏘q鏙c鏚q鏛s鏝m鏞y鏟c鏠f鏡j鏢b鏣s鏤l鏥x枧j枴g柙x鏧l鏨z鏩j鏪c鏫l鏬x鏭x鏮k鏯s鏰b鏱z鏲q鏳z鏴l鏵h鏶j鏸h鏹q鏺p鏻l鏼s鏽x鏾s鏿c鐀g鐁s鐂l鐃n鐄h鐅p鐆s鐇f鐈q鐉q鐊x鐋t鐌x鐎j鐏z鐐l鐑q鐒l鐓d鐔x鐕z鐖j鐗j鐘z鐙d鐚y鐛y鐜d鐝j鐞n鐟z鐠p鐡t鐣c鐤d鐥s鐦k鐧j鐨f鐩s鐪l鐫j鐬h鐭y鐮l鐯z鐰q鐱j鐲z鐴b鐵t榦g鐷y鐸d鐹g鐻j鐽d鐾b鐿y鑀a構g鑁z鑂x槔g鑄z鑅h鑆z鑇j鑈n鑉h鑊h鑋q鑌b樣y鑎g鑏n鑐x鑑j鑒j鑓y鑔c鑕z鑖m鑗l鑘l檑l鑜s鑝p檣q鑞l鑟d鑠s鑡c鑢l鑣b鑤b鑥l鑦x鑧k鑨l鑩e櫃g鑪l鑫x鑬j櫞y鑮b鑯j鑰y鑱c鑲x鑳j鑴x鑵g鑷n鑸l鑹c鑺q鑻p鑼l鑽z鑾l鑿z钀n钁j欽q钃z钄l钅j钆g钇y钊z钋p钌l钍t钏c钐s钑s钔m钕n钖y钗c钚b钛t钜j钣b钤q钪k钫f钬h钭t钯b钰y钲z钴g钶k钷p钸b钹b钼m钽t铄s铈s铉x铊s铋b铌n铍p铎d铏x铐k铑l铒e铓m铔y铕y铖c铗j铘y铙n铚z铛c铞d铟y铠k铢z汙w铤d铥d铦x铧h铨q铩s铪h铫d铮z铯s铳c铴t铵a铷r铹l铻w铼l铽t铿k锂l锃z锆g锇e锉c锊l锍l锎k锏j況k锒l锓q锔j锕a锖q锘n锛b锜q锝d锞k锟k锠c锢g锧z锩j锪h锫p锬t锱z锲q锴k锵q锶s锷e锸c锺z锼s锽h锾h锿a镂l镃z镄f镅m镆m镈b镉g镋t镌j镎n镏l镒y镓j镔b镕r镖b镗t镘m镙l镚b镛y镝d镞z镟x镠l镡t镢j镤p淺q镥l镦d镧l镨p镩c镫d镬h镯z镱y镲c镳b镴l镵c長c镸c镹j溈w镻d镼j镽l門m閂s閃s閄h滌d閆y閇b閈h閉b閊c開k閌k閍b閎h閏r閐s閑x閒x漁y閔m閕x閖l閗d閘z閙n閚z閛p閜x閝l閞b閠r閡h関g閣g閤g閦c閧h閨g閩m閪s閫k閬l閭l閮t閰j閱y閲y潿w閳c閴q閶c閷s閸k閹y閺w閻y閼e閽h閾y閿w闀h闁b濁z闄y闅w闆b闈w闉y闊k闋q闌l闍d闎q闏p闐t濾l闓k瀾l闕q闖c闗g闘d闙q闚k闛t關g闝p闞k闟x闠h闡c闤h闥t闦w闩s闫y闬h闱w闳h闵m闶k闼t闾l闿k阃k阄j阆l阇d阈y阊c阋x阌w阍h阏e阒q阓h阕q阖h阗t阘t阙j阚k阛h阝f阞l阠x烴t阡q阢w阣y阤t阥y阦y阧d阨a阩s阪b阫p阬k阭y阯z阰p阱j阷c阸e阹q阺d阼z阽d阾l陁t陂b陃b陉x陊d煥h陎s陏d陑e陒g陓y陔g陖j陗q陘x陙c陚w陜x陝s陞s陟z陠p陣z陦d陧n陫f燈d燜m陭q陮d爍s陰y陱j陲c陳c陴p陸l陹s険x陻y陼z陽y陾r陿x隀c隁y隂y隃y隄d隇w隈w隉n隊d隌a牾w隍h階j隑g隒y隓h犋j隕y隖w隗k隚t際j犖l隝d隞a犢d隟x隠y隡s隢r隣l隤t隥d隦p隨s隩a險x隬n隭e隮j隯d隰x隱y隲z隴l隵x隷l隸l隹z隺h隻z隼s隽j隿y雂q雃j雈h雉z雊g雋j雎j雐h雑z雒l雓y雔c雖s雗h雘h雙s雚g雛c雜z雝y雞j雟g雡l離l難n雤y雥z雦c雧j雩y雫n雬f獎j雭s雮m雯w雰f雱p雲y雳l雴c雵y雸a獮x電d雼d雽h雿d霁j霂m霃c霅z霆t霈p霊l霋q霌z霎s霏f霐h霑z霒y霔s霕t霗l霘d霙y霚w霛l霝l霟h霠y霡m霢m霤l霥m霦b霧w霨w霩k霪y霫x霬y霭a霮d霯t霰s霱y霳l霴d霵j霶p霷y霺w霼x瑋w霽j霾m霿m靀m靁l靂l靃h靄a靅f靆d靇l靈l靉a靊f靋l靌b靍h靎h靏h靐b璁c靑q靓j靔t靕z靗c靘q靚j靜j靝t靟f靣m靤p靦m靧h靨y靪d靫c靬j靭r靮d靯d靰w靱r靲q靵n靷y環h靸s靹n靺m靻z靼d靽b靾x靿y鞀t鞁b瓔y鞂j鞃h鞄p鞅y鞆b鞇y鞈g鞉t鞊j鞌a鞎h鞏g鞐k鞑d鞒q鞓t甌o鞔m鞕b鞖s鞗t鞙x鞚k甕w鞛b鞜t鞝s鞞b鞟k鞡l鞢x鞣r鞤b鞥e鞦q鞧q鞨h鞩q鞪m鞫j鞬j鞮d鞯j鞰w鞱t鞲g鞳t鞴b鞵x畢b鞶p鞷g鞸b鞹k鞺t鞻l鞼g當d鞽q鞾x鞿j韀j疇c韂c韃d韅x韆q韇d韈w韉j韊l痠s韋w韌r韍f韎m韏q韐g韑w韒q韓h韔c韕k痺b韖r韗y韘s韙w韚g韛b韜t韝g瘋f韞y韟g韠b韡w韢s韣d韤w韥d韨f韪w韫y韬t韮j韯x韰x韱x韲j韴z韷l韸p韹h韺y韻y韼p韽a韾y響x頀h頁y頂d頃q項x癉d頇h須x頉y癘l頊x頋e頌s頍k頎q頏h癤j預y頑w頒b頓d頔d頕d頖p頗p領l頙c頚j頛l頜h頝q頞e頟e頠w頡j頢k頣s頤y頥y頦k頧d頨y頩p頪l頫f頬j頭t頮h頯k頰j頱l頲t頳c頴y頵j頶h頷h頸j頹t頺t頻b頼l頽t頾z頿z顀c顁d顂l顃t顄h顅q顆k顇c顈j顉q顊y顋s題t額e顎e顏y眙y顐w顒y顓z顔y顕x顖x顗y願y顙s顚d顛d顜j眾z顝k類l顟l顠p顡w顢m顣c顤y顥h顦q顧g顨x顩y顪h顫c顬r顭m顮b顯x顰p瞇m顱l顲l顳n顴q顸h顼x颀q颉j颋t颌g颎j颏k颒h颔h颕y颙y颚e颛z颞n颟m颡s颣l颥r颦p風f颩d颪g颫f颬x颭z颮b颯s颰b颱t颲l颳g颴x颵x颶j颷b颸s颹w颺y颻y颼s颽k颾s颿f飀l飁x飂l飃p飄p飅l飆b飇b飈b飉l飊b飋s飌f飍x飏y飐z飑b飒s飓j飔s飕s飖y砦z飗l飙b飚b飛f飜f飝f飡c飢j飣d飤s飥t飦z飧s飨x飩t飪r飫y飬y飭c飮y飯f飰f飱s碭d飲y飳z飴y飵z飶b飷j確q飸t飹b飺c飻t飼s飽b飾s飿d餀h餁r餂t餃j餄h餅b餆y餇t餈c餉x養y餋j餌e磽q餍y餎l餏x餑b餒n餓e餔b餕j餖d餗s餘y餙s餚y餛h餜g餝s餞j餟c餠b餡x餢b餣y餤d餥f餦z餧w館g餩e餪n餫y餬h餭h餮t餯h餰j餱h餲a餳x礬f餵w餶g餷c餸s餹t餺b餻g餼x餽k餾l餿s饀t饂w饃m饄t饅m饆b饇y饈x饉j饊s饋k饌z饍s饎x饏d饐y饑j饒r饔y饕t饖w饗x饘z饚h饛m饜y饝m饞c饟x饠l饡z饢n饣s饤d饦t饧x饨t禪s饩x饪r饫y饬c饳d饴y饷x饸h饹g饻x饽b饾d馀y馂j馃g馄h馇c馉g馊s馌y馎b馐x馑j馓s馔z馕n馘g馛b馜n馝b馞b馟t馠h馡f馢j馣a馤a馥f馦x馧y馨x穎y穡s馪p馫x馬m馭y馮f馯h馰d馱t馲t馳c馴x馵z馶z馷p馸x馹r馺s馻y馼w馽z馾d馿l駀y竇d駂b駃j筅x駅y駆q駇w駈q駉j駊p駋z駌y筧j駍p駎z駏j駐z駑n駒j駓p駔z駕j駖l駗z駘t駙f駚y駛s駜b駝t駞t駟s箢y駠l駡m駢p駣t駤z駥r駦t駧d駨x駩q駪s駫j駬e駭h駮b簞d駰y駱l駲z駳d駴h駵l駶j駷s駸q駹m駺l駻h駼t駽x駾t駿j騀e騁c騂x騃a騄l騅z騆z騇s騈p騉k騊t騋l騌z騍k騎q騏q騐y騑f騒s験y騔g騕y騖w騗p騙p騚q騛f紆y騜h騝q騞h騟y騠t騡q騢x騣z純c騥r騦s騧g騨t絕j騩g騪s騬c騭z騮l騯p騰t騱x騲c騳d騴y綽c緄g騶z騷s騸s騹q騺z騻s騼l騽x騾l騿z縋z驁a驂c驃p驄c驅q縲l驆b驇z驈y驉x驊h驋b驌s驍x驎l驏z驐d繃b驑l驒t驓c驔d驕j驖t驗y驘l驙z驚j驛y驜y繽b驝t驞p驟z驠y驡l驢l驣t驤x驥j驦s驧j驨x驩h驪l驫b驲r驵z驷s驸f驺z驽n驿y骀d骁x骃y骅h骈p骉b骊l骍x骎q骐q骒k骓z骔z骕s骖c骘z骙k罷b骛w骜a骝l骞q骟s骠b骢c骣c骥j骦s骧x骩w骪w骫w骬y骭g骮y骯a骰t骱j骲b骳b骴c骵t羨x骶d骷k骹q骺h骻k骼g骽t骾g骿p羻q髀b髁k髂q髃y髄s髅l髆b髇x髈b髉b髋k髌b髎l髏l聖s髐x髑d髒z體t髕b髖k髗l髙g髚q髛k髜q髝l髞s髟b髠k髡k髢d肀y髣f髤x髥r髦m髧d髩b髪f髫t髬p髭z髮f髯r髰t胙z髱b髲b髳m髴f髷q髸g髹x髺k髻j髽z髾s髿s鬀t鬁l膣z鬄t鬅p鬆s鬇z鬈q鬉z鬊s鬋j鬌d鬍h鬎l鬏j鬐q鬑l鬒z鬓b鬔p鬕m鬖s鬗m鬘m鬙s鬚x鬛l鬜q鬝q鬞n鬟h鬠k臘l鬡n鬢b鬣l鬤r鬥d臥w鬧n鬨h鬩x鬪d鬬d鬭d鬮j鬯c鬰y艙c鬳y艤y鬴f鬵z鬶g鬷z鬸l鬹g鬺s鬻y鬽m鬾j鬿q魀g魃b魅m魆x魇y芐h魉l魊y魋t魍w魎l魐g魑c魒p魕j魖x魗c魘y魙z魚y荮z莖j魜r魝j魞a魟h魠t魡d魢j魣x魤e魥j魦s魧h菪d菴a魩m萇c魪j魫s魬b魭y魮p魯l魰w葒h魲l魳z魴f魶n魷y魸n魹m魺h魻x魼q魽h魾p魿l鮀t蒹j蓀s鮂q鮃p鮄f鮅b鮆c鮇w鮈j鮉d蓮l鮊b鮋y鮌g鮍p鮎n鮏x鮐t鮑b蔆l鮒f鮓z鮔j鮕g鮖s蔞l蕆c蕘r鮘c鮙t鮚j鮛s鮜h鮝x鮞e鮟a鮠w鮡z鮢z鮣y鮤l鮥l鮦t鮧y鮨y鮩b鮪w鮫j鮬k鮭g鮮x鮯g鮰h鮱l鮲m鮳k鮴x鮵t鮶j鮷t鮸m鮹s鮺z鮻s鮼q鮽y鮾n鯀g鯁g鯂s鯃w鯄q鯅s鯆p鯇h鯈t蘞l鯊s鯋s鯌k鯍m鯎c鯏l虼g鯐s鯑k鯒y鯓s鯔z鯕q鯖q鯗x鯘n鯚j鯛d鯜q鯝g鯞z鯟d鯠l鯡f鯢n鯣y鯤k蜴y鯦j鯧c鯨j鯩l鯪l螄s螈y鯬l鯭m鯮z鯯z鯰n鯱x鯲d鯳s鯴s鯵s鯶h鯷t鯹x鯺z鯻l鯼z鯽j鯾b鯿b鰀h蟛p鰁q鰂z鰃w蟣j鰄w鰅y鰆c鰇r鰈d鰉h鰊l鰋y鰌q鰍q鰎j鰏b蠶c鰑y蠻m衊m鰓s鰔j鰕x鰖t鰗h鰘s鰙r鰚h鰛w鰜j鰝h鰞w鰟p鰠s鰡l鰢m鰣s鰤s鰥g鰦z鰧t鰨t鰩y鰪e鰫y鰬q鰭q鰮w鰯r鰰h鰱l鰲a袼g裉k鰴h鰵m鰶j鰷t鰸q鰹j鰺s鰻m鰼x鰽q鰿j鱀j鱁z鱂j鱃x鱄z鱅y鱆z鱇k鱈x襖a襲x鱊y鱋q鱌x鱍b鱎j鱏x鱐s鱑h鱒z覈h觀g觔j鱔s鱕f鱖g鱗l鱘x鱙y鱚x鱛a鱜k鱞g鱟h鱠k鱡z鱢s鱣z鱤g鱥g計j鱦y鱧l鱨c鱩h鱪s鱫a訟s訥n訶h鱭j鱮x鱯h鱰s鱱l鱲l鱳l鱴m鱵z鱶x鱷e鱸l鱹g鱺l鱻x鱽d鱾j試s鱿y鲀t鲂f詬g鲃b鲄h鲅b詰j鲆p鲇n詳x鲈l鲉y鲊z鲋f詿g鲌b鲎h誄l鲏p鲐t鲑g鲒j鲓k鲔w鲕e鲖t鲗z鲘h鲙k鲚j鲛j鲝z鲞x鲟x誦s鲠g鲡l說s鲢l鲣j鲥s鲦t誹f鲧g鲨s鲩h鲪j鲫j鲬y鲭q鲮l鲯q鲰z鲱f鲲k鲳c鲴g鲵n鲶n鲷d鲹s鲺s諦d鲻z鲼f諭y鲽d鲾b鲿c鳀t諼x謄t鳁w鳂w鳄e謖s鳅q鳆f謾m譏j鳇h鳈q鳉j鳊b變b鳌a鳍q鳎t鳏g鳐y鳑p讞y鳓l鳔b鳕x鳗m鳘m鳙y鳚w鳜g鳝s鳟z鳠h鳡g鳢l鳣z鳤g鳥n鳦y鳧f豊l鳨l鳪b鳫y鳬f鳭d鳮j鳯f鳰n鳱g鳲s鳳f鳴m鳵b鳶y貞z買m費f貽y鳸h賀h鳹q鳺f鳻b鳼w鳽j鳾s鳿y鴀f鴁y鴂j鴃j鴄p賍z鴅h鴆z鴇b鴈y鴉y鴊z鴋f鴌f賚l賦f賫l鴎o賱y鴏d賲b鴐j鴑r鴒l鴓m鴔f鴕t鴖m鴗l鴘b鴙z鴚g鴛y鴜c鴝q鴞x鴟c鴠d鴡j鴣g鴤z鴥y鴦y鴧y鴨y鴩d鴪y贖s鴬y鴭d赾q鴰g鴱a鴲z鴳y鴴h鴵x鴶j鴷l鴸z鴹y鴺y鴻h鴼l鴽r趒t鴾m鴿g趕g鵁j鵂x鵃z鵄c鵅l鵆q鵇t鵈e趛y鵊j鵋j趢l鵌t鵍h鵎t趦z趬q趶k鵐w鵒y鵓b鵔j鵕j跊m鵖b鵗x鵘j鵙j鵚t鵛j鵜t鵝e鵞e鵟k鵠h鵢s鵣l鵤z跮d鵦l鵧p鵨s鵩f鵪a鵫z鵬p踇m鵭q鵮q鵯b踋j鵰d鵱l鵲q踐j鵳j鵴j鵵t鵶y鵷y踖j鵸q鵹l鵺y鵻z鵼k鵽d踜l鵾k鵿s鶀q踠w鶁j鶂y踤z踨z踼t鶄j鶅z鶆l鶇d蹅c蹆t蹌q蹎d蹏t鶉c鶊g鶋j鶌q鶍y鶎k鶏j鶐s鶑y鶒c鶓m躌w躤j鶖q躪l鶗t鶘h鶙t鶚e躳g躴l躼l軂l軅y軈y軍j鶜m鶝f鶞c鶟t鶠y鶡h鶢y鶣p鶤k鶥m鶦h軛e鶧y軞m軭k軯p軳p鶩w鶪j軸z輇q鶬c鶭f鶮h鶯y鶰y鶱x鶲w輑y鶴h鶵c輜z鶶t鶷x鶸r輠g鶹l鶺j鶻g鶼j輧p輪l輯j輳c輼w鶾h鶿c鷀c鷁y鷂y轋h轌x轓f鷄j鷅l鷆t鷇k鷈t鷉t鷊y鷋t鷌m鷍x鷎g鷏t鷐c鷑j鷒t鷓z轙y鷔a轚j鷕y鷖y轜e鷗o鷘c鷙z鷚l鷛y轣l鷝b鷞s鷟z鷠y鷡w鷢j鷣y鷤t鷥s鷦j鷨h鷩b鷪y鷫s鷬h辀z鷮j辎z鷯l辤c鷱g辧b鷲j鷳x鷴x鷵t鷶m鷷z鷸y鷹y鷺l鷻t鷼x鷽x辭c鷿p鸀z鸁l鸂x鸃y鸄j鸅z鸆y鸇z辴z鸈y鸊p鸋n鸌h辺d鸍m鸎y鸏m鸐d鸑y迀g鸒y鸓l鸔b鸕l鸖h鸗l鸘s鸙y鸚y鸛g鸜q鸝l鸞l鸠j鸢y鸤s鸧c鸨b鸩z鸪g鸫d鸬l鸮x鸰l鸱c鸲q鸴x鸶s鸷z鸸e鸹g鸺x鸻h鸼z鸾l鹀w鹁b鹂l鹄g鹆y鹇x迒h鹈t迓y鹉w鹋m鹌a鹍k迠c鹎b迡c鹐q鹑c迣z迦j迧c鹓y鹔s迶y鹖h鹗e迼j鹘g迿x鹙q鹚c鹛m逌y逘y鹜w鹝y鹞y鹟w鹠l鹡j鹢y鹣j鹥y鹦y鹨l鹩l鹪j逤s鹫j逩b逫z逰y鹬y鹭l鹮h鹯z鹱h鹲m鹳g鹵l鹷l鹸j鹹x鹻j鹼j鹽y鹾c逽n逿d遃y遆t遉z麁c麂j麃b麄c麅p麆z麇j麈z麉j麊m麋b麌y麍l麎c麏j達d麐l違w麑n麒q麔j遚c麕j麖j麗l麘x麙x麚j麛m麜l麝s麞z麟l麠j麢l麣y麤c麥m麧h麨c麩f麪m麫m麬f麭p麮q麯q麰m麱f麲x麳l麴q麵m麶c麷f麸f麹q麺m適s麼m麽m遬s麾h麿m遰d黀z遱l黁n遳c黃h黅j黆g黇t黈t黉h黊h黋k黌h黏n黐c黒h黓y黕d黖x黗t黙m黚q黛d黜c黝y點d黟y黠x黡y黢q黣m黤y黥q黦y黧l黨d黩d黪c黫y邍y黬y邎y黭y黮d邐l黯a黰z黱d黲c黳y黴m黵d黶y黷d黸l黹z黻f黼f黽m邗h黾m黿y鼀c鼁q鼂c鼃w鼄z鼅z鼆m鼇a邞f鼊b鼋y邨c鼌c邩h鼍t邫b邽g鼑d鼒z鼔g鼕d鼘y鼙p鼚c鼛g鼜c鼝y鼞t鼟t鼡n鼢f鼣f鼤w鼥b鼦d鼧t郋x鼨z郌g鼩q鼪s鼫s鼬y鼭s鼮t鼯w鼰j鼱j鼲h鼳j鼴y鼵t鼶s鼷x鼸x郞l鼹y鼺l鼼y鼽q鼾h鼿w齀w齁h齂x齃e齄z齅x郣b郩x齆w齇z齈n齉n齊q郰z郲l齌j齍z齎j齏j齑j齒c齓c齔c齕h齖y齗y齘x郼y齚z齛x齜z齝c齞y齟j齠t齡l齢l齣c齤q齥x鄅y鄋s齧n齨j鄍m齪c齫y齬y齭c鄒z齯n鄖y鄘y鄤m齱z齲q齳y齴y鄧d鄩x鄪b齶e齷w齸y齹c齺z齻d齼c齾y龀c龁h龂y鄳m鄹z龃j龅b龆t龇z龈y龉y龊c龌w龍l龏g鄿q酅x龑y龒l龓l龔g龕k龗l龘d龛k龜g龝q酨z龞b龢h龣j龤x龥y鳩j鳷z鴍w鴢y鴫t鴮w鴯e鵀r鵉l鵏b鵑j鵡w鵥k鶃y鶛j鶨c鶫d鶳s鶽s鷃y鷜l鷧y鷭f鷰y鷾y鸉y鹒g鹕h鹶j鹺c麀y麡q鼈b鼉t鼏m齋z齙b齦y齮y齰z齵y齽j龎p龖d龡c癷b唉a苯b瞓f硸n秎f斗d稥x坊f竕f告g龟g哼h解j擂l罖r芈m羒f羘z羛y羜z羣q羦h羪y羫q羭y羮g羳f羵f羶s羷l翂f裂l聁u膹f艈u漂p骑q砌q雀q蒊h蒶f蕒m蕡f是s伺c毝c苔t虲u蚠f蝊u蟇m衁h衇m衈e衖x衚h衜d衞w衟d衠z衯f衮g袰b袴k呀y訜f子z豶f亂l傯z僨f償c兇x喲Y嗯E堯Y塏K墳F墾K鶕A鶔r鶈q鱬r鱝f魵f髍m馩f馚f饙f餴f颃h霻f霣y雺w隫f闧u闇a閥f閟b間j镪q钿d鐼f鐢f鏦c鏜t鍂p奮f婁l媵y屢l嶠j幀z幗g憤f錖d錆q銽x橥z歸g殛j炷z甯n瘧n瘵z碡z糞f紛f羥q腳j膩n臺t莜y蓿x褸l誒e讜d讠y贁b趀c趓d趙z趸d跀y跥d輊z輒z轒f轕g遧z邚r邤x郬q郺y酳y酼h酽y醆z醈t醓t醔q醦c釀n釂j釈s釋s釒j釔y釕l釗z釙p釠l釢n釤s釥q鉀j釪h釫h釯m釿j鈃x鈄d鈇f鈈b鈎g鈏y鈑b鈖f鈙q鈚p鈝y鈟d鈠y鈨y鈩h鈱m鈵b鈾y鈿d鉅j鉇s鉒z鉔z鉗q鉞y鉡b鉢b鉥s鉧m鉬m鉲k鉳b鉵t鉽s鉾m銁j銃c銅t銍z銐c銑x銕t銗h銘m銠l銡j銣r銤m銨a銫s銬k銰a銱d銹x銼c銾h銿z鋃l鋊y鋍b鋏j鋐h鋒f鋓c鋔w鋜z鋝l鋫l鋱t鋲b鋶l鋻j鋾t錄l錈j錐z錔t錛b錝c錫x錰s錶b鍃h鍅f鍎t鍜x鍝y鍮t鍰h鍴d鎎k鎗q鎚c鎢w鎣y鎥t鏓c鏷p鐍j鐳l鐶h鐺d鑃d鑍y鑙j鑚z鑛k鑭l鑶c钂t钘x铇b锳y镮h镺a镾m閁m閅m閯s閵l闂h闃g闑n闒t闔h闢p闣d陥x陬z陯l韁j韄h頄q順s顑k飠s饁y饓c駁b駄t駯z騘c騤k騫q騵y鰐e鰒f鰳l鰾p鱉b鱓s鳋s鳒j鳛x鹧z鹴s黂f黺f鼖f齩y驀m髊c髨k髵e髶e髼p鬂b鬦d鬫k鬱y魈x魌q魓b魛d魨t魱h鮁b鮗d鮿z鯙c鯉l鯥l鯫z鯸h龐p".IndexOf(text, StringComparison.Ordinal); + if (num < 0) + { + return string.Empty; + } + + return "丂k丄s丅x丆m丏m丒c丗s丢d丠q両l丣y并b丩j丮j丯j丱g丳c丵z丷b丼j乀f乁y讈l乆j乑y乕h乗c乚h乛w乢g乣j乤h乧d乨s乪n乫g乬g乭d乮m乯o乲c乴x乵y乶p乷s乸n乹q乺s乻e乼z乽z乿z亀g亁q乱l亃l亄y亅j亇m亊s亐y亖s亗s亘g亜y亝q亚y亣d亪y亯x亰j亱y亴y亶d亷l亸d亹m亼j亽j亾w仈b仌b仏f仐j仒e仚x仛t仜h仢b仦c仧c仩c仭r仮f仯c仱q仴w仸y仹f仺c仼w仾d伀z伂p伃y伄d伅d伆w伇y伈x汲j伌a伒j伓p伔d伖t伜c伝y伡c伣q伨x伩x伬c伭x伮n伱n伳x伵x伷z伹q伻b伾p伿z佀s佁a佄h佅m伫z布b佉q佊b佋z佌c佒y占z佖b佡x佢q佦s佨b徊h佫h佭x佮g佱f佲m佷h佸h佺q佽c侁s侂t侅g来l侇y侊g侌y侎m侐x侒a侓l侕e仑l侘c侙c侚x侜z侞r侟c価s侢d侤t侫n侭j侰j侱c侲z侳z侴h侣l局j侸s侹t侺s侻t侾x俀t俣y系j俆x俇g俈k俉w俋y俌f俍l俒h俓j俔q俕s俖p俙x俛f侠x俢x俤d俥c俧z俫l俬s俰h俲x俴j俵b俶c俷f俹y俻b俼y俽x俿h伥c倁z倂b倃j倅c俩l倇w倈l仓c倊z个g倎t倐s们m倓t倕c幸x倗p倛q倝g倞j倠s倢j仿f値z倧z伦l倯s倰l倱h倲d倳z倴b倵w倶j倷n倸c倹j倻y倽s倿n偀y偁c偂q偄r偅z偆c伟w偊y偋b偍t偐y偑f偒t偓w偔e偖c偗s偘k偙d偛c偝b偞x偠y偡z偢c偣a偦x偧z偨c偩f偪b偫z偭m偮j偯y偰x偱x偲c偳d侧c侦z偸t偹b咱z偼j伪w傁s傂z傃s傄x傆y傇r傉n傊y傋j傌m傎d傏t傐h杰j傒x傓s傔q傕j伧c傗c伞s备b傚x傛r傜y傝t傞s傟y傠f傡b家j傤z傦g傪c傫l佣y傮z偬z傰p傱s传c伛y债z伤s傹j傼h傽z倾q傿y僀d僁x偻l僃b僄b仅j僆l戮l僈m佥q僊x僋t僌y働d僎z僐s侨q僒j僓t僔z仆p僗l僘c僙g僛q僜d僝c僞w僟j僠b僡h僢c僣t僤d侥j偾f僩x僪y僫e僯l僰b雇g僲x僴x僶m僷y僸j价j僺q僼f僽z僾a僿s仪y儁j侬n儃c亿y当d侩k俭j儊c儌j儍s儎z儏c傧b儑a儓t俦c侪c儖l儗y尽j儙q儚m儛w儜n儝q儞n偿c儠l儢l儣k儤b儥y儦b儧z儨z儩s优y儫h儬q儭c儮l儯t儰w儱l储c儳c儴x儵s儶h俪l罗l儹z傩n傥t俨y儽l儾n兂z凶x兊d兑d兎t兏c児e儿e兖y兘s兟s兡b兤h兦w内n两l兪y兯h兲t兾j兿y冃m冄r円y冇m册c冋j冎g冏j冐m胄z冓g冔x冘y冚k冝y冞s冟s冡m冣z冦k冧l冨f冩x幂m冭t冮g冴y冸p冹f冺m冾q冿j凁s凂m凃t凅g净j凊q冻d凎g凐y凒a凓l凔c凕m凖z凗c凘s凙d凚j凛l凞x凟d凢f凣f凥j処c凧y凨f凩k凪n凬f凮f凯k凲g凴p凷k凾h刄r刅c刉j刋q刌c刏j刐d刓w刔j刕l刜f刞q刟d刡m刢l刣z别b刦j刧j删s刬c刯g刱c刲k刴d刵e刼j刾c刭j剅d剆l则z剈y剉c克k刹c剒c剓l剕f剗c剘q剙c剚z刚g剥b剟d剠q剢d剣j剤j剦y剨h剫d剬z剭w剐g剰s剱j剳d剀k创c剶c铲c剸t剹l剺l剻p剼s剾k劀g划h劄z劅z劆l剧j刘l刽g劋j刿g剑j劎j劏t剂j劒j劔j劕z劖c劗z劘m劙l劚z劜y劤j劥k劦x劧z劮y劯z劰m労l劵j劶k劷y劸w効x劺m匡k劼j劽l勀k劲j勂g勄m勅c勆l勈y勊k勌j勍q勎l勏b勑c勓k勔m动d勖x务w勚y勋x勜w胜s劳l勠l勡p势s积j勥j剿c勧q勨x勪q勫f勬j勭t勮j勯d劢m勲x勳x勴l励l勶c勷x劝q匀y勼j勽b匁m匂x匃g匄g匇y匉p匊j匋t匌g匎e匑g匒d匓j匔g匘n匛j匜y匞j匟k匢h匤q匥f匧q匨z匩k匫h匬y匦g汇h匰d匮k匲l匳l匴s匵d匶j匷j匸x匼k匽y区o卂x卄n卆z卋s卌x卍w卐w协x単d卙j卛s卝g卥x卨x卪j卬a卭q卲s卶c恤x却q卼w卽j卾e厀x厁s厃w厇z厈h厊y厎d厏z厐p厑y厒q厓y厔z厖m厗t厍s厛t厜z厞f厡y厤l厧d厪j厫a厬g厌y厯l厰c厱q厉l厳y厣y厵y厷g厸l厹r厺q厼k厽l厾d叀z参c叄c叅c叆a叇d収s叏g叐b叒r叓l叕z叚j叜s叝j叞w叡r丛c叧g叴q叺c叾d叿h吀m吂m吅x吇z寸c吔y吘o吙h吚y吜c吢q吤j吥b吪e吰h吴w呐n吷x吺d吽h吿g呁j吕l呄g呅w呇q呉w呌j呍h尺c呏s呑t呚h呝e呞s呟j呠p呡w呣m呥r呧d呪z呫t呬x呭y呮q呯p呰z呴g呹y呺x呾d呿q咁x咃t咅p咇b咈f咉y咊h咍h咑d咓w咗z咘b咜t咞x咟h咠q咡e咢e咥d咮z咰s咲x咵k咶g咷t咹e咺x呙g咾l哃t哅x哊y哋d哖n哘x哛p哠h员y哢l哣p哤m哫z哬h哯x哰l哱b哴l哵b哶m哸s哹f哻h哾c唀y唂g唃g呗b含h唈y唊j唋t唌d唍w唎l唒q唓c唕z唖y唗d唘q唙d唚q唜m唝g唞d唟g唡l唥l唦s唨z唩w唫j唭q唲e唴q唵a唶j念n唹y唺t唻l唽x啀a啂g啇d啈h啋c啌q啍z啎w问w啑s啒g啓q啔q啗d啘w啚b啝h哑y启q啠z啢l衔x啨q啩g啫z啯g啰l啱y啲d啳q啴c啹j啺t啽a啿d喅y喆z喌z喍c喎w喐h喒z喓y喕m喖h喗y唤h喛h喞j喠z喡w喢s喣x喤h喥d喦y喨l喩y丧s吃c乔q喭y单c喯p喰c哟y喴w営y喸p喺x喼j喿z嗀h嗁t嗂y嗃h呛q啬s嗈y嗊g嗋x吗m嗏c嗐h嗕r嗗w嗙p呜w嗛q嗞z嗠l嗢w嗧j唢s嗭z嗮s嗰g嗱n嗴q哔b嗸a嗹l嗺z嗻z嗼m嗿t嘂j嘃c嘄j嘅k叹t嘇s嘊a嘋x喽l嘐x嘑h嘒h呕o嘕x啧z尝c嘙p嘚d唛m嘝h嘠g嘡t嘢y嘥s嘦j嘨x哗h嘪m嘫r唠l啸x叽j嘳k哓x嘷h呒m嘺q嘼c嘽t嘾d噀x恶e噂z噃f噄c噅h噆z噇c噈c噉d噊j噋t噏x噐q噑h噒l嘘s噕h噖y噚x噛n噝s噞y噟y哒d噡z噣z哝n哕y噧x噭j噮y嗳a噰y哙k噳y喷p噷x吨d噺h噽p噾y噿z咛n嚁d嚂l嚃t嚄h吓h嚈y嚉d嚊x嚋z哜j嚑x嚔t噜l嚖h嚗b嚘y啮n嚚y嚛h嚜m嚝h嚞z嚟l嚠l嚡x嚢n嚤m咽y呖l嚧l咙l嚩p嚪d嚫c嚬p嚭p向x嚰m嚱x嚲d喾k严y嚵c嘤y嚸d嚹l嚺t嚻x嚽c嚾h嚿h啭z嗫n嚣a囃z冁c囆c囇l呓y囋z苏s囍x囎z囏j囐y嘱z囒l囓n囕r囖l囘h囙y囜n団t囥k囦y囧j囨p囩y囱c囬h囮e囯g囲w図t囶g囷q囸r囼t圀g圁y圂h圅h囵l国g圌c围w圎y圏q圐k圑p园y圆y圔y圕t图t圗t团t圙l圚h圛y圝l圞l圠y圡t圢t圤p圥l圦k圧y圫y圱q圲q圴z圵d圶q圷x圸s圼n圽m圿j坁z坃x坄y坅q坆m坈r坉t坋b坒b坓j坔d坕j坖j坘d坙j坢b坣t坥q坧z坬g坮t垧s坱y坲f坴l坵q坸g坹x坽l坾z坿f垁z垇a垈d垉p垊m垍j垎h垏l垐c垑c垔y垕h垖d垗z垘f垙g垚y垜d垝g垞c垟y垥x垨s垪b垬h垯d垰k垱d垳h垵a垶x垷x垹b垺p垻b垼y垽y垾h垿x埀c埁c埄b埅d埆q埇y埈j埉x埊d埌l埍j埐q埑z埓l埖h埗b埛j埜y埞d垭y埢q埣s埥q埦w埧j埨l埩z埪k埫c埬d埮t埰c埲b埳x埵d执z埻z埼q埾j埿n堁k堃k堄n坚j堈g堉y垩e堌g堎l堏f堐y堒k堓a堔s堖n堗t堘c堚h堛b堜l埚g堟z堢b堣y堥m堦j堧r堨a堩g堫z堬y堭h堮e尧y报b堲j堳m场c堶t堷y堸f堹z堺j堻j堼f堽g堾c碱j塀p塁l塂j塃h塅d塆w塇x塉j块k茔y塎y垲k塐s埘s塓m塕w塖c涂t塙q塚z塛l塜p塝b塟z塠d塡t坞w塣z埙x塦z塧a塨g塩y塪x塭w塮x塯l塰h塱l塲c塳p塴b尘c塶l塷l塸o堑q塺m塻m塼z塽s塿l墂b墄q墆z墇z墈k垫d墋c墌z墍x墎g墏q墐j墒s墔c墕y墖t増z墘q墛w坠z墝q墠s墡s墢f墣p墤k墥t墦f墧q墪d墫c墬d墭s堕d墯d墰t墱d墲w墴h墵t墶d墷y墸z墹j墺a墙q垦k墿y壀p壂d壃j壄y壆x坛t壈l壉j壊h壋d壌r壍q壏x壐x壒a压y壖r壗j垒l圹k垆l壛y壜t壝w坏h垄l壠l壡r坜l壣l壥c壦x壧y壨l坝b壪w壭s壮z壱y売m壴z壵z壷h壸k壶h壻x壼k寿s壾m壿d夀s夁y夃g夅j夆f夈z変b夊s夋q夌l夎c夐x夑x夒n夓x夗y夘w夛d夝q夞y够g夡q梦m夣m夦c夨c夬g夰g夲b夳t夵y夶b夻h夽y夹g夿b奀e奃d奅p奆j奊x奌d奍q奂h奒k奓z奙b奛h奜f奝d奞x奟b奡a奣w奤h奦w奥a奨j奁l夺d奫y奬j奭s奋f奯h奰b奱l奲d奵d奷q奺j奻n奼c奾x奿f妀j妅h妉d妋f妎h妏w妐z妑p妔k妕z妘y妚f妜y妆z妟y妠n妡x妦f妧w妬d妰z妱z你n妴y妵t妶x妷z妸e妺m妼b妽s妿e姀h姁x姂f姄m姅b姇f姈l姉z姌r姗s姎y姏g姕z姖j姙r姛d姞j姟g姠x姡h姢j姤g奸j姧j姩n侄z姫z姭x姮h姯g姰j姱h姲y姳m姴l姵p姶y姷y姸y姺x姼s姽g姾q娀s娂h娋s娍c娎x娏m娐f娒m娔k娕c娖c娗t娙x娚n娱y娝b娞n娡z娢h娤z娦p娧t娨m娪w娫y娬w娭a娮y娯y娰s娳l娵j娷s娸q娹x娺z娻d娽l娾a娿e娄l婃c婄p婅j婇c婈l婋x婌s婍q婎h婏f婐w婑w婒t婓f婔f婖t婗n婘j婙j婛j婜q婝d婞x婟h婠w婡l婣y婤z婥c妇f婨l婩a婫h婬y娅y婮j婯l婰d婱x婳h婸d婹y婻n婼c婽j婾t媀y媁w媂d媃r媄m媅d媆r媇q媈h媉w媊q媋c媌m媍f媎j媏d媐y媓h媔m媕a媖y媗x媘j媙w媜z媞t媟x媠d媢m媣r媤s媥p媦w娲w媨c媩h媫j媬b媭x媮t妫g媰c媱y媴y媶r媷r媹l媺m媻p媪a妈m媿k嫀q嫃z嫄y嫅j嫆r嫇m嫈y嫊s嫋n嫍t嫎p嫏l嫐n嫑b嫓p嫕y妪y嫙x嫚m嫛y嫝k嫞y嫟n嫢g嫤j嫥z嫧z嫨h嫪l嫬z嫭h嫮h嫯a嫰n嫲m嫳p嫴g妩w嫶q嫷t嫸z嫹m嫺x娴x嫼m嫽l嫾l嬀g嬁d嬂z嬄y嬅h嬆x嬇k娆r嬊y婵c娇j嬍m嬎f嬏f嬐x嬑y嬒h嬔f嬕s嬘s嫱q嬚l嬛h袅n嬞d嬠c嫒a嬢n嬣n嬷m嬥t嬦c嬧j嬨c嬩y嫔p嬫r嬬r嬭n嬮y嬯t婴y嬱q嬳y嬵m嬶k婶s嬹x嬺n嬻d嬼l嬽y嬾l嬿y孁l孂j娘n孄l孅x孆y孇s孈x孉h孊m孋l娈l孍y孎z孏l孖m孞x孠s孡t孧y孙s孭m孮c孯q孲y孴n孷l学x孹b孻n孼n孾y孪l宂r宆q宊t宍r宎y宐y宑j宒z宔z宖h実s宧y宨t宩s宬c宭q宫g宯x宱z宲b宷c宺h宻m宼k寀c寁z寃y寈q寉h寊z寋j寍n寎b寏h寑q寔s寕n寖j寗n寘z寙y寚b寛k寜n寠j寝q寣h实s宁n审s寪w写x宽k寭h寯j寱y寲y寳b寴q宠c宝b寷f寽l対d尀p専z尃f将j专z寻x尌s对d导d尐j尒e尓e尗s尙s尛m尞l尟x尠x尡h尣w尦l尨m尩w尪w尫w尭y尮d尯k尰z尲g尳g尵t尶g尴g屃x届j屇t屌d屍s屒z屓x屔n屖x屘m屚l屛p屉t扉f屟x屡l层c屧x屦j屩j屪l屫j属s屭x屰n屲w屳x屴l屵a屶h屷h屸h屻r屼w屽h屾s岀c岃y岄y岆y岇a岉w岊j岋e岏w岒q岓q岕j岝z岞z岠j冈g岤x岥p岦l迢t岨j岮t岯p岰a岲k岴q岶p岹t岺l岻d岼p峀x峂t峃x峅b峆h峇b峈l峉e峌d峍l峎e峏e峐g峑q峓y峔m峕s峖a峗w峘h峚m峛l峜f峝t峞w峟y峠q峢l峧j峩e峫x峬b峯f峱n峲l峳y岘x峵r岛d峷s峸c峹t峺g峼g峡x峿w崀l崁k崄x崅q崈c崉t崊l崋h崌j崃l崏m崐k崑k崒z崓g崕y岗g崘l崚l崜d崝z崟y岽d崡h峥z崣w崥p崨j崪z崫j崬d崯y崰z崱z崲h嵛y崵y崶f崷q崸y崹t崺y崻z崼s崿e嵀z嵁k嵂l嵃y嵄m嵅h嵆j嵈h嵉t嵍w嵎y嵏z岚l嵑k岩y嵓y嵔w嵕z嵖c嵗s嵙k嵚q嵜q嵞t嵟c嵠x嵡w嵢c嵣d嵤r嵥j嵦k嵧l嵨w嵪k嵭b嵮d嵰q嵱y嵲n嵳c嵵s嵶r嵷s嵸z嵹j嵺l嵻k嵼y嵾c嵿d嶀t嵝l嶃z崭z嶅a嶆c岖q嶉w嶊z嶋d嶌d嶍x嶎y嶏p嶐l嶑x嶒c嶓b嶔q嶕j嶖y崂l嶘z嶚l嶛l嶜q嶞t嶟z峤j嶡j嶢y嶣j嶤y嶥j嶦z峄y嶨x嶩n嶫y嶬y嶭n嶮x嶯j嶰x嶱k嶲g嶳d嶴a嶵z嶶w嵘r嶹d岭l嶻j屿y岳y嶾y嶿r巀j巁l巂x巃l巄l巇x巈j巉c巊y岿k巌y巎n巐c漓l峦l巓d巅d巕n巗y巘y巙k巚y巜k巟h巠j巣c巤l巪g巬p巭b巯q巵z巶z巸y卺j巺x巻j巼p巿f帀z帄d帇n帊p帋z帍h帎d帒d帓m帗f帞m帟y帠y帡p帢q帣j帤r帅s帨s帩q帪z师s帬q帯d帰g帲p帐z帴j帵w带d帹s帺q帾z帿h帧z幁z帏w幆y幇b幈p幉d幊g幋p幍t幎m幏j幐t幑h幒z幓s幖b帼g帻z幙m幚b幜j幝c帜z幠h币b幤b幦m幧q幨c蒙m帮b帱c幭m幮c幰x幱l幵j幷b干g几j庁t仄z広g庈q庉d庌y庍b庎j庒z庘y庛c庝t庡y庢z庣t庤z庨x庩t庪g库k庬m庮y庯b庰b庱c庲l庴j庻s庼q庽y庿m廀s厕c厢x廃f厩j廅e廆h廇l厦s廋s廌z廍b廎q廏j廔l廕y廗d廘l廙y厨c廜t厮s廞x庙m厂a庑w废f广a廤k廥k廦b廧q廪l廫l庐l廭j廮y廯x廰t痈y廲l厅t廵x廸d廹p廻h廼n廽h弆j弇y弉z弌y弍e弎s弑s吊d弖h弙w弚t弜j弝b弡j弢t弣f弤d弨c弫z弬y弮j弰s弲x弪j弴d张z弶j强j弸p弻b弽s弾d弿j彁g彂f彃b彄k彅j彇x弹d彉g彋h弥m彍g弯w彏j彑j彔l彚h彛y彜y彞y彟h彠h彣w彦y彧y彨c雕d彮y彯p彲c彴z彵t彶j彸z彺w彽d彾l佛f徃w徆x徍w徎c徏z径j従c徔c徖c徝z从c徟z徕l徢x徣j徤j徥s徧b复f旁p徯x徰z徱p徲t徳d徶b彻c徺j徻h徾m徿l忀x忁b忂q忈r忊d忋g忎r忓h忔y忕s忚x忛f応y忞m忟m忢w忣j忥x忦j忨w忩c忬y忯q忰c忲t忳d忴q忶h忷x忹w忺x忼k怇j怈y怉b怋m怌p怐j怑b怗t怘h怚c怞y怟d怢t怣y怤f怬x怮y怰x怲b怳h怴x怶b怷s怸x怹t怺y怽m恀s恄x恅l恒h恇k恈m恉z恊x恌y恏h恑g恓x恔x恖s恗h恘q恛h恞y恟x恠g恡l耻c恦s恮z恱y恲p恴d恵h恷q恾m悀y悁j悂p悦y悆y悇t悈j悊z悋l悎h悏q悐t悑b悓q悕x悗m悘y悙h悜c悞w悡l悢l悤c悥y悧l悩n悪e悮w悰c悳d怅c闷m悷l悹g悺g凄q悾k悿t惀l惁x惂k惃g惄n惇d惈g惉z惌y惍j惎j惏l惐y惒h惓q惔t惖t惗n啜c惛h惞x惢s惣z惤j惥y惪d恼n恽y惵d惷c惸q恻c惼b惽m惾z惿t愃x愄w愅g愇w愊b愋x愌h愐m愑y愒q愓d愔y愖c愗m愘k愙k爱a惬q愝y愞n愡c愢s愥y悫q愩g愬s愭q愮y愯s愰h愱j愳j怆c愵n愶x恺k愸z愹y愺c愻x愼s愽b忾k慀x慁h慂y栗l慅s慆t殷y慉x态t愠y慏m慐g慒c慓p慔m慖g慗c惨c惭c慛c慜m慞z恸t慠a慡s惯g慤q慥z慦j慩l怄o怂s慬q慭y虑l慯s慱t慲m悭q慴s庆q慸d慹z慺l慻j戚q慽q欲y慿p憀l憁c忧y憃c憄z憅t憆c憇q憈q惫b憌q憍j憏c怜l凭p愦k憓h憕c憖y憗y憘x憙x惮d憛t憞d憟s憠j憢x憣f愤f憥l憦l憪x悯m憭l怃w憯c憰j憱c宪x憳t憴s憵p忆y憸x憹n憺d憻t憼j憽s懀w懁x懃q懄q懅j懆s恳k应y怿y檩l懎s懐h懓a懕y懖g懗x懘c懙y懚y懛d懜m懝a怼d懠q懢l懑m懤c懥z懧n恹y懩y懪b懫z懬k懭k懮y懯f懰l懱m惩c懳h懴c懒l怀h悬x懹r忏c懻j惧j懽h慑s恋l戁n戂m戃t戄j戅g戆g钺y戓g戋j戙d戜d戝z戞j戠z戣k戦z戗q戨g戬j戫y戭y戯x战z戱x戏h户h戸h戹e戺s戻t戼m扂d扄s扅y扆y扊y扏q仂l払f扖h扗z扙z扚d扜y扝y扞h扟s叉c扡t扦q扤w扥d扨s扱c扲q扴j扵y扷b扸x抵d扻z扽d抁y抂k拚p抅j擦c抇h抈y抋q抌d抍z殒y抏w抐n抔p抙p抜b抝a択z抣y抦b抧z抩n抪p抭y抮z抰y抲h抳n曳y抶c抷p抸j抺m抾q拀z拁j拃z抛p拏n拑q拕t拝b拞d拠j拡k拤q拪q拫h拰n拵c拸y拹x拺c拻h挀b挃z挄k挅d挆d挊n挋z挍j挏d挐n挒l挓z挔l挕d挗j挘l挙j挜y挦x挧y挩t挬b挭g挮t挰c挱s挳k挴m挵n挷b挸j挻s挼r挟x挿c捀p捁j捄j捇h捈t捊p捑z捒s捓y捔j捖w捗b捘z捙y捚z捛l捜s捝t捠b捤w捥w捦q舍s捪m扪m捬f捯d捰w卷j捳y捴z捵c捸t捹b捼r捽z捾w捿q掁c扫s抡l掅q掆g掋d掍h掑q掓s掔q掕l掗y挣z掚l挂g掜y掝h掞y掟z采c掦t掫z掯k掱p掲j掵m掶j掹m掻s掽p掿n拣j揁z揂j揃j揅y揇n揈h揊p揋w揌z揑n揓s揔z揕z揗x揘h揙b扬y换h揜y揝z揟x揢k揤j揥d揦l揧l揨c揫j揬t挥h揯g揰c揱x揳x揵q揷c背b揺y揻w揼b揾w搃z搄g构g搇q搈r搉q搊c损s搎s搑r搒b搕k摇y捣d搘z搙n搚l搝q擀g搢j搣m搤e搥c搧s搨t搩j搫p搯t搰h搱z搲w搳h搵w抢q搷t搸z搹e搻n搼q搾z摂s摃g摉s摋s摌c摍s摎n摏c摐c掴g摓f摕d摗s摙l摚c摛c掼g摝l搂l摠z摡g摢h摣z摤q摥t摦h摨z摪j摫g摬y摮a挚z摰n摱m摲c抠k摴c摵s抟t摷j掺c摼k摽b摿y撀g撁q撃j撆p捞l撉d撊x撋r撌g撍z撎y撏x撑c挠n撔h撗h搭d捻n撛l撜z撝h挢j撠j撡c掸d拨b撦c撨x撪b抚f撯z撱w扑p揿q撴d撶h撹j挞t撽j挝w捡j拥y擃n掳l擆z择z擈p擉c击j挡d擌s擏q擑j擓k担d擕x擖y擙a据j擛y擜e擝m挤j擡t擥l擧j擨y擩r擪y擫y拟n擭h擮j摈b拧n搁g掷z擳z扩k擵m擶j撷x擸l擹t摆b擞s撸l擽l扰r攁y攃c摅s攅z撵n攇x攈j攊l攋l攌h攍y攎l隆l攐q攑q攓q拦l攕x撄y攗m搀c撺c携x摄s攞l攟j攠m攡c攒c挛l摊t攦l攧d攨w攩d搅j揽l攭l攰g攱g攲q攳x考k攼g攽b敀p敁d敂k敃m敄w敆h敇c敊c敋g敍x敎j敐c敒s敓d敔y败b叙x敚d敜n敟d敠d敡y敤k敥y敧q敨t敩x敪d敭y敮x敯m敱a敳a敌d敶c数s敹l敺q敻x敼y敽j敾s敿j斀z斁d敛l毙b斄l斅x斆x斈x斉q斊q斍j斎z斏l斒b斔y斓l斖w斘s斚j斝j斞y斠j斢t斣d斦y斨q斪q斩z斱z斲z斴l斵z斶c断d斸z斺c斻h斾p斿l旀m旗q旇p旈l旉f旊f旍j旐z旑y旓s旔j旕e旘z旙f旚p旛f旜z旝k旞s旟y旡j旣j旪x旫t旲t旳d旴x旵c旸y旹s旻m旼m旽t旾c旿w昁b昄b昅j升s昈h昉f昋g昍x昑q昒h昖y昗z昘f昚s昛j昜y昞b昡x昢p昣z昤l昦h昩m昪b昫x昬h昮z昰s昲f昳d昷w昸d昹a昺b昻a昽l昿k晀t时s晄h晅x晆k晈j晋j晊z晍t晎h晐g晑x晘h晙j晛x晜k昼z曦x晠s晢z晣z晥w晧h晩w晪t晫z晭z晱s晳x晵q晸z晹y晻a晼w晽l晿c暀w暁x暃f暅g暆y晕y晖h暊x暋m暍y暏s暐w暒q暓m暕j阳y暙c暚y暛s暜p暞j暟k暠g暡w畅c暣q暤h暥y暦l暩j暪m暂z暬x暯m暰c昵n暲z暳h暵h暶x暷c了l暺t暻j暼p暽l暿x曀y曁j曂h曃d晔y曅y历l昙t曈t晓x曊f曋s曍h曎y曏x曐x曑s曒j曓b曔j曕y暧a曘r曚m曞l曟c旷k曡d曣y曤h曥l曧r曨l曪l曫l晒s曭t曮y曯z曱y曵y曶h书s曺c曽z朁c朂x会g朄y朅q朇b朎l朏k朒g朓t朖l朘j朙m朚h朜t朞j朠y朡z朢w朣t朤l朥l胧l术s朰t朲r朳b朶d朷d朸l朹q朻j朼b朾c朿c杁r杄q杅y圬w杊x杋f杍z杒r杔t杕d杗m杘c杙y杚g杛g杝t杢j杣m杤w杦j杧m杫s杬y杮f东d杴x杶c杸s杹h杺x杻c杽c枀s枂w枃j枅j枆m枊a枍y枎f枏n枑h枒y枓d枔x枖y栀z枛z枟y枠h枡s枤d枦l枩s枬z枮x枱s枲x拐g枹b枺m枻y枼y枽y枾s枿n柀b柂d柅n柆l柇h柈b柉f柊z柋d柌c柍y柎f柕m柖s柗s柟n柡y柣z柤z柦d柧g柪a柫f柭b柮w柲b栅s柶s柷z柹s柺g査c柼y柾j栁l栂m栃l栄r栆z栍s栐y栒x栔q栕c栘y栙x栚z栛l栜s栞k栟b栠r栢b栣r栤b栥z栦c栧y栨c栫j栬z栮e栯y栰f栱g栴z栵l栶y栺z栻s栿f桇r桋y桍k桏q桒s桖x桘c桙y桚z桛k桝j桞l桟z桪x桬s桭c桮b桯t桰g桱j桲b桳b桵r桸x桹l桺l桻f桼q桽w桾j杆g梀s梂q梄y梇l梈p梉z梊d梋x梌t梎a梐b梑d梒h梕r梖b梘j梙h梚w梛n梜j条t梞j枭x梠l梡k梣c梥s里l梪d梬y梮j梱k梲z梴c梶w梷j梸l梹b梺x梻x梼d梽z梾l梿l棁z弃q棅b棆l棈q棊q棌c棎c棏d棐f棑p棓b棔h枨c枣z棙l棛y棜y棝g棞j栋d棡g棢w棤q棥f棦c栈z棨q棩y棪y棫y棬j棭y棯s栖q棳z棴f棶l棷z棸z棻f棽c棾q棿n椀w椂l椄j椆c椇j椈j椉c椊z椌k桠y椑b椓z椔z椕b椖p椗d椙c椚m椛h検j椝g椞x椡d椢g椣d椥z椦q椧m椨f椩g椪p椫s椬y椮s椯d椱f椲h椳w椵j椶z椷j椸y椺x椻y椼y椾j楀y楁h楃w楄p楅b楆y楇g楈x楉r杨y楋l楌y楍b楎h楏k楐j楑k楒s枫f楘m楙m楛h楜h楟t楢y楤c楥x楧y桢z楩p楪d楬j业y楯d楰y楲w楳m楴d极j楶j楺r楻h楽l楾h楿k榁m榃t榅w榊s榋c榌b榎j榏y榑b榒n榓m榖g榗j榚y榝s榞y榟z榠m榡s榢j榣y榤j榥h榩q杩m榬y荣r榯s榰z榲w榳t榵r榶t榸z榹s榺s榼k榽x榾g桤q槂s盘p槄t槅g槆c槇d槈n槉j枪q槏q槑m槒x杠g槕z槖t様y槙d槚j槜z槝d槞l槡s槢x槣j槤l槥h槦r椠q椁g槩g槪g槫t槬h槮s槯c槰p槱y桨j槴h槵h槶g槷n槹g槺k槻g槼g槾m樀d桩z樃l樄c枞c樆l樇x樈q樉s樋t樌g樍z樎s樏l梁l樒m楼l樔c樕s樖k标b樚l樛l樜z樝z枢s樠m樢n样y樤t樥p樦z樧s権q樫j樬c樭j樮y樰x樲e樳x樴z樶z樷c朴p树s桦h樻g橀x橁c橂d橃f橅m橆w桡r橉l橊l桥q橌x橍r橎f橏j橑l橒y橓s橔t橕c橖t橗m橚s橜j橝t橞h机j橠n椭t橣n橤r橦t橧z橪y横h橬q橭g橮l橯l橰g橲x橳s橴z橵z橶j橷d橸j橺x橻c橽t橾s橿j檃y檅h檆s檇z檈x柽c檊g檋j檌z檍y檏p檒f檓h档d檕j檖s檘p檙c檚c檛z桧g檝j檞j檟j檡z检j樯q檤d檥y檦b檧s檨s檭y檮c台t檰m檱q檲t槟b檴h檵j檶q檷n柠n檹y檺g槛j檼y檽n檿y櫀q櫁m櫂z柜g櫄c櫅j櫆k櫇p櫉c櫊g櫋m櫌y櫍z櫎h櫏q櫑l櫒s橹l櫔l櫕c櫖l櫗m櫘h櫙o榈l栉z櫜g椟d橼y栎l櫠f櫡z櫣l櫤j橱c櫦q槠z栌l櫩y枥l櫫z榇c櫭j櫮e櫯s櫰h櫱n櫲y栊l櫵q櫶x櫷g榉j櫹x棂l樱y櫼j櫽y櫾y欀x欁n栏l欅j欆s欇s欈w欉c权q欋q欌z欍j欎y椤l欐l欑c栾l欓d欔q欕e榄l欗l欘z欙l欚l欛b欜n欝y欥y欨x欩c欪c欫q欬k欭y欮j欯x欰x欱h欳k欴l欵k欶s欸a欻c欼c钦q欿k歀k歁k歂c歄g歅y歈y歊x歋y歍w歏j欧o歑h歒t歓h歔x歕p歖x歗x歘x歚s歛l歜c歝y欤y歠c欢h歨b歩b歫j歭z歮s歯c歰s歱z岁s歳s歴l歵z歶y归g歺d歽z歾m殁m殀y殅s殈x殌j殎q殐s殑j殔y殕f殗y残c殙h殜d殝z殟w殠c殢t殣j殇s殥y殦c殧j殨k殩c殚d殬d殓l殡b殰d殱j歼j殶z殸q殹y杀s殻k壳k殽x殾x毁h毃q毄j殴o毇h毈d毉y毊x毋w毎m毐a毑j毘p毚c毞b毟m毠j毢s毣m毤t毦e毧r毨x毩j球q毭d毰p毱j毲d毴b毶s毷m毸s毺s毻t毼h毾t毵s氀l氁m氂m氃t氄r毡z氉s氊z氋m氇l氎d氒j気q氜y氝n氞n氠s气q氥x氢q氩y氭d氱y氲y氶z氷b氹d氺s氻l氼n泛f氿g汃p汄z汅m汈d汋z汌c丸w汏d汑t汒m汓q汖p汘q污w汚w汢t汣j汥z汧q汫j汬j汭r汮j汯h汱t汳b汵g汷z汸f决j汼n汿x沀x沄y沇y沊d沋y沍h沎h沑n没m冲c沗h沘b沚z沜p沝z沞z沠p沢z沨f沬m沯z沰t沴l沵m沶y沷f沺t泀s况k泂j泃j泆y泇j泋h泍b泎z泏c泑y泒g泙p泚c泜z泝s泟c泤s泦j泧y泩s泬j泭f泲j泴g泹d洀p洃h洅z洆c洈w洉h洊j洍s洏e洐x洑f洓s洔z洕y洖w洘k洝a洟y洠s洡l洢y洣m洤q洦p洨x泄x洬s洭k洯q洰j洴p汹x洷z洸g洺m洿w浀q浂y浄j浉s浌p浐c浕j浖l浗q浘w浛h浝m浟y浡b浢d浤h浥y浧y浨l浫h浭g浱c浳y浵t浶l浃j浺c浻j浽s浾c浿p涀x涁s涃k涄p涆h泾j涊n涋t涍x涏t涐e涒t涗s涘s涙l涚s涢y涥h涬x涭s涰c涱z涳n涴w涷d涹w涺j涻s凉l涽h涾t淁q淂d淈g淉g淊y淍z淎p淏h淐c淓f淔z淕l淗j泪l淛z淜p淟t淢y淣n渌l淧m淩l沦l淭q淯y淰n淲b淴h渊y涞l淸q浅j淽z淾y淿b渀b渁y渂w渃r渄f渆y渇k済j渉s渋s渏y渒p渓x渕y渘r涣h减j渞q渟t渢f涡g渧t渨w渪r测c渮h渰y渱h渳m渵m渶y渷y渹q渻s渼m渽z浑h渿n湀g湁c湂e湅l湆q湇q湈m湉t凑c湋w湌c湏h湐p湑x湒j湗f湙y湚y湜s湝j浈z湠t湡y湢b湣m湤s湥t湦s涌c湨j湩d湪t湬q湭q汤s湰l湱h湳n湴b湵y湶q湷z湸l湹c湺x湻c湼n湽z満m溁y溂l溄f溇l沩w溊b溋y溌h溍j溎y溑s溒y溓l溔y溕m准z溗c溙t溚t溛w沟g溞s溠z溡s溣l溤m溦w溨z溩w温w溬q溭z溮s溰a溵y溸s溹s湿s溾a溿p滀c滃w沧c灭m滆g滈h滉h滊q涤d滍z荥x滐j滒g滘j滙h滛y滝l滣c滧y滪y滫x沪h滭b滮b滞z滰j滱k渗s滳s滶a卤l浒h滺y滻c滼f滽y滚g满m漀q渔y漃j漄y漅c漇x漈j漊l漋l漌j漍g漎c漑g漒q漖j漗c漘c漙t沤o漛t漜y漝x漞m漟t漡s汉h涟l漥w漦c漧g漨f渍z漮k漰p涨z漴c漵x漷h渐j漺s漻l漼c漽t浆j潀c潂h潃x潄s潅g潈z潉k潊x潌z潏y潐j泼p潒d潓h洁j潕w潖p潗j潙w潚s潜q潝x泻x潠s潡d润r潥s潧z潨c潩y潪z潫w潬t浔x溃k潱y潳t潵s潶h滗b潹c潻s潽p潾l涠w涩s澁s澂c澃j澅h浇a涝l澊c澋j澏h澐y澑l澒h澓f澔h澕h澖x涧j澘s澙x澛l澝n澞y澟l渑m澢d澣h泽d澥x澦y澨s泶x澪l澫w澬z澭y浍k澯c澰l淀d澲y澴h澷m澸g澺y澻s澼p澽j澾t澿q浊z浓n濄g濅j濆p濇s濈j濊h濋c濌t濍s濎d濏s濐z濓l濔m濖s濗m泞n濙y濚y濜j濝q济j濢c濣w涛t濥y濦y濧d濨c濩h濪q滥l濬j濭a潍w滨b濲g濳q濴y濶k濷f濹b溅j濻w泺p濽z滤l濿l瀁y瀂l瀃s瀄z滢y渎d瀈h瀊p渖s瀌b瀍c瀎m浏l瀒s瀓c瀔g濒b瀖h瀗x泸l瀙q瀜r沥l瀞j潇x潆y瀡s瀢w瀤h瀥x瀦z泷l濑l瀩d瀪f瀫h瀬l瀭s瀮l瀯y瀱j潋l瀳j瀴y瀶l瀷y瀸j瀺c瀻d瀼r瀽j澜l瀿f灀s灁y灂z沣f滠s灅l灆l灇c灈q灉y灊q灋f灍j灎y灐y洒s灒z灓l灔y灖m灗s滩t灙d灚j灛c灏h灟z灠l灡l灢n湾w滦l灥x灦x灧y灨g灪y灮g灱x灲x灳h灴h灷z灹z灺x灻c灾z炁q炂z炄n炆w炇p炈y炋p炌k炐p炑m炘x炚g炛g炞b炟d炠x炡z炢z炣k炤z炥f炦b炧x炨x炩l炪z炰p炴y炵t炶s为w炿z烄j烅x烆h烇q烉h烋x烌x烍x烎y乌w烐z烑y烒s烓w烔t烕m烖z烗k烚x烜x烝z烠h烡g烢c烣h烥c烰f烱j烲x烳p烃t烵z烶t烸h烺l烻y烼x烾c烿r焀h焁x焂s焃h焄x焅k焆j焇x焈x焋z焌j焍d焎x焏j焒l焔y焗j焛l焜k焝h焞t焟x焠c无m焢h焣j焤f焥w焧z焨f焩p焪q焫r焬x焮x焳j焴y焵g焸x焹g焻c焼s焽x焾n焿g煀q煁c煂h煃k煄z煆x煇h煈f炼l煋x煍j煏b煐y煑z炜w煓t煔s煕x煖n煗n煘c烟y煚j煛j煝m煟w煠y煡j茕q煣r焕h烦f煪q煫s炀y煭l煯j煰z煱g煴y煵n煶s煷h煹g煻t煼c煾e煿b熀h熁x熂x熃w熅y熆h熇h熈x熉y熋x熌s熍q熎y熐m熑l荧y熓w熕g熖y炝q熚b熛b熜c熝l熞j熡l熢p熣s熤y熥t熦j熧z熩h熪y熫z熭w熮l熯h熰o热r熲j熴k熶c熷z熸j熺x熻x熼y熽x炽c熿h燀c烨y燂t焰y燅x燆q燇j灯d炖d燊s燋q燍s燏y磷l燑t烧s燖x燗l燘m烫t燚y燛j焖m燝z营y燡y燣l燤t灿c燨x燩q燪z燫l烛z燯l燱y燲x燳z烩h燵t燶n燷l燸x燺h燻x烬j燽c焘d燿y爀h爂b爃r爄l爅m爇r爈l爉l爊a爋x爌k烁s爎l爏l炉l爑j爒l爓y爔x爕x爖l爘c爚y烂l爜c爞c爟g爡c爢m爣t爤l爦l爧l爩y爫z争z爮p爯c爲w爳h爴j爷y爼z尔e牀c牁k牂z牃d牄q牅y牉p牊c牋j牎c牏y牐z牑b牓b牕c牗y牍d牚c牜n牞j它t牣r牤m牥f牨g瘪b牫g牬b牭s牰y牱k牳m牶q牷q牸z牻m牼k牵q犂l犃p犅g犆z犇b犈q犉c犌j犎f犐k犑j犓c犔x犕b荦l犗j犘m犙s犚w犁l犜d犝t犞q犠x犡l犊d犣l犤b犥p犦b牺x犨c犩w犪k犫c犮q犱j犲c犳z犵g犺k犻p犼h犽y犾y犿h状z狅k狆z狇m狉p狊j狋y狌s狏t狑l狓p狕y狖y狘x狛b狜k狝x狟h狢h狣z狤j狥x狦s狧t狪t狫l狵m狶x狭x狈b狾z狿y猀s猂h猄j猅p猆f猇x猈b猉q猋b猌y猐q猑k猒y猔z猘z狰z猚y猟l猠c猣z猤g猦f猧w猨y猭c猯t猰y猲h猳j猵p犹y猺y狲s猼b獀s獁m獂h獃d狱y狮s獆h獇q獈y獊c獋h獌m奖j獏m獑c獓a獔h獕s獘b獙b獚h獛p獜l獝x獞t獟y獡s獢x獣s獤d獥j獦g獧j独d獩h狯k猃x猕m狞n獱b获h獳r獴m猎l獶n犷g兽s獭t献x獽r獿n猡l玁x玂q玃j玅m兹c玈l玊s玌q玍g玏l玐b玒h玓d玔c玕g玗y玘q玙y玚c玜h玝w玞f玠j玡y玣b玤b玥y玦j玧m珏j玪j玬d玭p玱q玴y玵a玶p玸f玹x玼c玽g玾j玿s珁c珃r珄s珅s珆y珇z珋l珌b珎z珒j珓j珔j珕l珖g珗x珘z珚y珛x珜y珝x珟s珡q珢y珣x珤b珦x珨x珪g珫c珬x佩p珯l珰d珱y珳w珴e珵c珶d珷w珸w珹c珺j珻m珼b珽t现x珿c琀h琁x琂y琄x琇x琈f琋x琌l琍l琎j琑s琒f琓w琔d琕p琖z琗c琘m琙y琜l琝m琞s琟w琠t琡s琣b琤c琧e琩c琫b琭l琯g琱d琲b琷q琸z琹q珐f琻j琽d琾j珲h瑀y瑂m瑃c瑄x瑅t瑆x瑇d瑈r瑉m玮w瑌r瑍h瑎x瑏c瑐j瑑z瑒y瑓l瑔q瑖d瑝h瑠l瑡s瑢r琐s瑶y瑥w瑧z瑨j莹y玛m瑫t瑬l瑮l琅l瑱t瑲q瑳c瑴j瑵z瑹t瑺c瑻k瑼z瑽c瑿y璂q璄j璅s璆q璈a琏l璌y璍y璏z璑w璒d璓x璔z璕x璖q璗d璘l璙l璚j璛s璝g璟j璡j璢l玑j璤h璥j瑷a璪z璫d璬j璭g璮t璯h环h璱s璲s璳t璴c璵y璶j璷l璸b璹s璻z璼l玺x璾j璿x瓀r瓁w瓂g瓃l瓄d瓅l瓆z瓇r瓈l瓉z琼q瓋t瓌g瓍s瓎l珑l瓐l瓑l瓓l璎y瓕m镶x瓗q瓘g瓙d瓒z瓛h瓝b瓟b瓡z瓥l瓨x瓩q瓪b瓫p瓬f瓭d瓳h瓵y瓸b瓹j瓺c瓻c瓽d瓾w甀z甁p甂b甃z甅l甆c甈q甉x甊l甋d瓯o甎z甐l甒w甔d瓮w甖y甗y甛t甝h甞c甠q甡s产c産c甤r甧s甪l甮f甴y甶f甹p甼t甽z甿m畁b畂m畃x畆m畇y畉f畊g畍j畐f畑t畒m畓d畕j畖w畗d畘n亩m畟j畠t畡g毕b畣d畤z畨f畩y画h畲s畭s畮m畯j异y畱l畳d畵h畷z畺j畻c畽t畾l疀c疁l疂d疄l疅j畴c疈p疉d叠d疌j疍d疎s疐z疓n疕b疘g疛z疞x疢c疦j疧q疨y疩c疭z疶x疷z疺f疻z痱f痀g痁d痆n痋t痌t痎j痏w痐h痑t痓z痗m痉j痚x痜t痝m酸s痡f痥d痩s痬y痮z痯g麻m痵j痶t痷a痸c痹b痻m痽d痾k瘂y瘄c瘆s瘇z瘈z瘉y疯f疡y瘎c瘏t瘑g瘒w痪h瘔k瘖y瘚j瘜x瘝g瘗y疮c瘣h疟n瘨d瘬z瘮s瘯c瘱y瘲z瘶s瘷s瘘l瘻l瘽q疗l癄q癅l痨l痫x癈f瘅d癋h癎x癏g癐g癑n癒y癓w癕y癗l疠l癙s癚d癛l癝l癠j痴c痒y疖j症z癧l癨h癞l癪j癣x瘿y瘾y瘫t癫d癳l癴l癵l癶b癹b発f发f癿q皀b皁z皃m皅p皉c皊l皌m皍j皏p皐g皒e皔h皕b皗c皘q皑a皛x皜h皝h皞h皟z皠c皡h皢x皣y皥h皦j皧a皨x皩h皪l皫p皬h皭j皯g疱p皳q皵q皶z皷g皲j皹j皱z隳h皼g皽z皾d盀q盁y盃b啊a阿a埃a挨a哎a哀a癌a蔼a矮a艾a碍a隘a鞍a氨a安a俺a按a暗a岸a胺a案a肮a昂a盎a凹a敖a熬a翱a袄a傲a懊a澳a芭b捌b扒b叭b吧b笆b八b疤b巴b拔b跋b靶b把b耙b霸b罢b爸b白b柏b百b佰b拜b稗b斑b班b搬b扳b般b颁b板b版b扮b拌b伴b瓣b半b办b绊b邦b梆b榜b膀b绑b棒b磅b蚌b镑b傍b谤b苞b胞b包b褒b盄d盇h盉h盋b盌w盓y盕f盙f盚q盗d盝l盏z盠l盢x监j盦a卢l盨x盩z荡d盫a盬g盭l盰g盳m盵q盷x盺x盻x盽f盿m眀m眂s眃y眅p眆f眊m県x眎s眏y眐z眑y眒s眓h眔d眕z眖k眗j眘s眛m眜m眝z眞z眡s眤n眦z眧c眪b眫p眬l眮t眰d眱d眲n眳m眴s眹z眻y眽m众z眿m睂m睄s睅h睆h睈c睉c睊j睋e睌m睍x睎x困k睒s睓t睔g睕w睖l睗s睘q睙l睁z薄b雹b保b堡b饱b抱b暴b豹b鲍b爆b杯b碑b悲b卑b北b辈b贝b钡b倍b焙b被b奔b本b笨b崩b绷b甭b泵b蹦b迸b逼b鼻b比b鄙b笔b彼b碧b蓖b蔽b毖b庇b闭b敝b弊b必b辟b壁b臂b避b陛b鞭b边b编b贬b扁b便b变b卞b辨b辩b辫b遍b彪b膘b表b鳖b憋b彬b斌b宾b兵b冰b柄b丙b秉b饼b炳b睝l睐l睟s睠j睤b睧h睩l睾g睭z睮y睯h睰m睱x睲x睳h睴h睵z睶c睷j睸m睺h睻x睼t瞁x瞂f瞃w瞆g眯m瞉k瞊d瞋c瞐m瞕z瞖y瞗d瞘k瞙m瞚s瞛c瞜l瞝c瞒m瞡g瞣w瞤s瞦x瞨p瞫s瞮c瞯x瞱y瞲x瞴w瞶g瞷j瞸y瞹a瞺h睑j瞾z矀w矁c矂s矃n矄x矅y矆h矈m矉p矋l矌k矎x矏m矐h矑l矒m矔g矕m矖x矘t矙k瞩z矝j矞y矟s矠z矡j矤s病b玻b菠b播b钵b波b博b勃b搏b铂b箔b伯b帛b舶b脖b膊b渤b泊b驳b捕b卜b哺b补b埠b不b步b簿b部b怖b猜c裁c材c才c财c睬c踩c彩c菜c蔡c餐c蚕c苍c舱c藏c操c糙c槽c曹c草c策c蹭c插c茬c茶c查c碴c搽c察c岔c差c诧c拆c柴c豺c蝉c馋c谗c缠c阐c颤c昌c猖c矦h矨y矪z矫j矰z矱y矴d矵q矷z矹w矺z矻k矼g砃d砄j砅l砆f砇m砈e砊k砋z砎j砏p砐e砓z砕s砙w砛j砞m砠j砡y砢l砤t砨e砪m砫z砮n砯p砱l炮b砳l砵b砶p砽y砿k硁k硂q朱z硄k硆e硈q硉l硊w硋a硍k硏y硑p硓l硔h硘q硙w硚q硛c硜k硞q硟c硠l硣x硖x硥m硦l硧y砗c硩c砚y硰s硱k硲y硳z硴h硵l硶c硹s硺z硻k硽y硾z硿k碀c碁q碂z碃q常c长c肠c敞c唱c倡c超c抄c钞c朝c嘲c潮c巢c吵c炒c车c扯c撤c掣c澈c郴c臣c辰c晨c忱c沉c陈c趁c衬c称c城c橙c成c呈c乘c程c澄c诚c承c逞c骋c秤c持c匙c池c迟c弛c驰c齿c侈c赤c翅c斥c充c虫c崇c抽c酬c踌c稠c愁c筹c仇c绸c瞅c丑c臭c初c出c躇c锄c雏c滁c除c楚c碄l碅j碆b碈m碊j碋h碏x碒y碔w碕q碖l碙n碝r碞y碠d碢t碤y碦k碨w硕s碪z碫d碬x砀d碮t碯n碵t碶q碷d碸f确q码m碿s磀e磃s磄t磆h磇p磈k磌t磍x磎x磏l磑w磒y磓d磖l磗z磘y砖z磛c磜q磝a磞p磟l磠l磡k磢c碜c磤y磥l磦b碛q磩z磪c磫z磮l矶j磱l磳z磵j磶x磸d磹d磻b磼j硗q磾d磿l礀j礂x礄q礆j礇y礈z礉h礊k礋z礌l础c矗c搐c触c处c揣c川c穿c椽c船c喘c串c窗c幢c床c闯c吹c炊c捶c锤c垂c春c椿c醇c唇c淳c纯c蠢c戳c绰c疵c茨c磁c雌c辞c慈c瓷c词c此c刺c赐c次c聪c葱c匆c粗c醋c簇c促c蹿c篡c窜c摧c崔c催c脆c瘁c粹c淬c翠c村c存c磋c撮c搓c措c挫c错c达d答d瘩d打d大d呆a歹d傣d戴d殆d代d贷d袋d待d逮d礍j礏y礐q礑d礒y礔p礕p礖y礗p礘e礚k礛j礜y礝r礟p礠c礡b礢y礣m礥x矿k礧l礨l礩z砺l砾l矾f礭q礮p礯y礰l砻l礲l礳m礵s礷j礸c礹y礽r礿y祂t祃m祄x祆x只z祊b祋d祌z祎y祏s佑y祑z祒t祔f秘b祙m祡c祣l祤y祦w祩z祪g祫x祬z祮g祰g祲j祳s祴g祵k祹t祻g祼g祽z祾l禄l禂d禃z禆b禇c禉y禋y禌z祸h禐y禑x禒x怠d耽d丹d郸d胆d旦d氮d但d淡d诞d蛋d党d刀d蹈d倒d祷d到d稻d悼d道d德d得d的d蹬d登d等d瞪d凳d邓d堤d低d滴d迪d笛d狄d翟d嫡d底d地d蒂d第d帝d弟d递d缔d颠d掂d滇d碘d点d典d靛d电d佃d甸d店d惦d奠d殿d碉d叼d凋d刁d掉d钓d调d跌d爹d碟d蝶d迭d谍d禓s禔z禕y禖m禗s禘d禙b禛z禜y禝j禞g禟t禠s禡m禢t禣f禤x禥q御y禨j禩s禅c禫d禬g禭s礼l禯n祢m禲l禴y禵t禶z禷l禸r禼x秃t秂r秄z秅c秇y籼x秊n秌q秏h秐y秓z秔j秖z秗y秙k秚b秛p秜n秝l秞y秠p秡b秥n秨z秪d秬j秮h秱t秲s秳h秴h秵y秶z秷z秹r秺d秼z秾n秿f稁g稄x税s稇k秆g稉j稊t稌s稏y稐l稑l稒g稓z稕z稖b稘j稙z稛k棱l丁d盯d叮d钉d顶d鼎d锭d定d订d冬d董d懂d侗d恫d洞d兜d抖d陡d豆d逗d痘d都d督d毒d读d堵d睹d赌d杜d镀d肚d度d渡d妒d端d短d锻d段d缎d堆d队d墩d蹲c敦d顿d囤d钝d盾d遁d掇d哆d多d垛d躲d朵d跺d舵d剁d惰d蛾e峨e鹅e俄e额e讹e娥e厄e扼e遏e鄂e饿e恩e而e耳e饵e洱e二e稝p禀b稡z稢y稤l稦y稧x稨b稩j稪f稫p稭j种c稯z稰x稲d稴x稵z稶y稺z稾g谷g穁r穂s穃r穄j穅k穇c穈m穊j穋l稣s颖y穏w穐q穒k穓y穔h穕q穖j穘x穚j穛z穜t穝z穞l穟s穑s秽h穣r穤n穥y穦p穧j穨t稳w穪c穬k穭l穮b穯s穱z穲l穳c穵w穻y穼s穽j穾y窂l窅y窇b窉b窊w窋z窌j窎d窏w窐w窓c窔y窙x窚c窛k窞d窡z窢h贰e罚f筏f伐f乏f阀f法f藩f帆f番f翻f樊f钒f繁f凡f反f返f范f贩f犯f饭f芳f方f肪f房f防f妨f访f纺f放f菲f非f啡f飞f肥f匪f诽f吠f肺f沸f费f芬f酚f吩f氛f分f纷f焚f汾f粉f份f忿f粪f丰f封f蜂f峰f锋f风f烽f逢f冯f缝f讽f奉f凤f否f敷f肤f孵f扶f拂b辐f幅f氟f符f伏f俘f服f窣s窤g窝w洼w窫y穷q窑y窰y窱t窲c窴t窵d窭j窷l窸x窹w窥k窻c窼c窾k竀c竁c竂l竃z窍q竆q窦d竈z竉l窃q竍s竎f竏q竐c竑h竒q竓h竔s竗m竘q竚z竛l竜l竝b竡b竢s竤h竧j竩y竫j竬q竮p竰l竱z竲c竳d竴c竵w竞j竷k竻l竼p竾c笀m笁z笂w笅j笇s笉q笌y笍z笎y笐h笒c笓b笖y笗d笘s笚d笜z笝n笟g笡q笢m笣b笧c笩f笭l浮f涪f福f袱f弗f甫f辅f俯f釜f斧f脯f腑f府f腐f赴f副f覆f赋f傅f付f阜f父f腹f负f富f讣f附f缚f咐f噶g嘎g该g改g概g钙g盖g溉g甘g柑g竿g肝g赶g感g敢g赣g钢g缸g肛g纲g港g篙g皋g高g膏g羔g糕g搞g镐g稿g哥g歌g戈g鸽g胳g疙g割g革g葛g格g蛤g阁g隔g铬g各g给g根g跟g耕g更g庚g羹g笯n笰f笲f笴g笵f笶s笷m笹t筇q笽m笿l筀g筁q筂c筃y筄y筈k筊j笋s筎r筓j筕h筗z筙l筜d筞c筟f筡t筣l筤l筥j筦g笕j筨h筩t筪x筫z筬c筭s筯z筰z筶g筸g筺k筼y筽o筿x箁p箂l箃z箅b箆b箉g箊y笺j箌z箎c筝z箑s箒z箓l箖l箘q箙f箚z箛g箞q箟j箠c箣c箤z箥p箮x箯b箰s箲x箳p箵x箶h箷s箹y箺c箻l箼w箽d箾s箿j节j篂x篃m埂g耿g梗g工g攻g功g恭g龚g供g躬g公g弓g巩g汞g拱g贡g共g钩g勾g苟g狗g垢g购g辜g菇g咕g箍g估g沽g孤g姑g鼓g古g蛊g骨g股g故g顾g固g刮g瓜g寡g褂g乖g怪g棺g关g官g冠g观g管g馆g罐g灌g贯g光g逛g瑰g规g圭g硅g闺g轨g鬼g诡g癸g桂g跪g贵g辊g棍g锅g郭g果g裹g过g哈h篅c篈f筑z篊h箧q篍q篎m篏q篐g篔y篕h篖t篗y篘c篛r篜z篞n篟q筱x篢l篣p笃d篧z篨c筛s篫z篬q篭l篯j篰b篲h筚b篴z篵c篶y篸c篹s篺p篽y篿t箦z簁s簂g簃y簄h簅c簆k簈p簉z簊j篓l簎c簐n蓑s簒c簓s簔s簕l簗z簘x簙b簚m簛s簜d簝l箪d簠f简j簢m篑k簤d簥j簨z簩l箫x簬l簭s簮z簯q簰p簱q簲p簳g簴j簵l簶l檐y簹d簺s簻z簼g签q帘l籂s骸h孩h海h氦h亥h害h骇h酣h憨h邯h韩h涵h寒h函h喊h罕h翰h撼h捍h旱h憾h悍h焊h汗h夯b杭h航h壕h嚎h豪h毫b郝h好h耗h号h浩h呵h喝h荷h菏h核h禾h和h何h合g盒h貉h阂h河h涸h赫h褐h鹤h贺h嘿h黑h痕h很h狠h恨h亨h衡h轰h哄h烘h虹h鸿h洪h宏h弘h红g喉h侯h猴h吼h厚h候h后h呼h乎h忽h瑚h葫h胡h蝴h狐h糊h湖h篮l籄k籅y籆y籇h籈z籉t籊t籎y籏q藤t籑z籒z籓f籔s籕z籖q籗z籘t籙l籚l籛j箨t籝y籞y籁l笼l籡s籢l籣l龠y仠g籦z籧j籨l笾b簖d籫z篱l籭s箩l籯y籰y籱z吁x籵f籶s籷z籸s籹n籺h籾n籿c粀z粁q粂z粃b粄b粅w粆s粇k粈r粊b粋c粌y粍z佂z粏t粐h佹g侀x粔j粖y粙z粚c粛s粠h侼b侽n粣c粦l粨b粩l粫e粬q粭h粯x粰f粴l粤y粶l粷j粸q粺b粻z弧h虎h唬h护h互h花h华h猾h滑h化h话h槐h淮h桓h还h缓h患h豢h宦h幻h荒h慌h黄h磺h蝗h簧h皇h凰h惶h煌h晃h幌h恍h谎h灰h辉h徽h恢h蛔h回h悔h慧h卉h惠h晦h贿h讳h诲h绘h荤h昏h婚h魂h混h豁h活h伙h火h或h惑h霍h货h圾j基j畸j稽j箕j粿g糀h倄y糃t糄b糆m糉z糋j糎l糏x糐f糑n糒b糓g糔x糘j糚z糁s糡j馍m糣s糤s糥n糦x粮l糩k糪b糫h糬s糭z糮x糱n粝l糳z籴d糵n粜t糷l糹s糺j糼g糽z纠j纪j紁c纣z紃x约y纡y纥g纨w纫r纹w紌q纳n紎z紏t纽n紑f紒j纾s纰p紖z纱s紘h纸z级j纭y紝r紞d紟j紣c紥z紦h紨f紩z紪q紬c紭h扎z细x绂f绁x绅s紴b紵z紶q偟h肌j饥j迹j激j讥j鸡j姬j绩j缉j吉j棘j辑j籍j集j及j急j疾j即j嫉j脊j己j蓟j技j偤y冀j季j伎j祭j悸j寄j寂j计j记j既j忌j际j妓j继j嘉j枷j佳j加j荚j颊j贾g甲j钾j假j稼j架j驾j嫁j尖j间j煎j兼j肩j艰j缄j茧j柬j硷j剪j荐j鉴j践j贱j见j键j箭j件j紷l紸z绍s绀g紻y绋f紽t紾z绐d绌c絁s终z弦x组z絅j絇q絈m絉s絊z絋k経j絍r绗h絏x傶q结j絑z絒c傸c絓g絔b绝j絖k絗h絘c絙h絚g绦t絜j絝k绞j絟q絠g络l绚x絣p絤x絥f絧t绒r絩t絪y絫l絬x絭j絯g絰d统t丝s絴x絵h絶j絸j绢j絺c絻w絼z絽l絿q綀s綂t绡x綄h綅q绠g綇x绨t綉x綊x綋h綌x綍f綎t绥s綐d捆k綒f经j綔h綕z綖y綗j綘f健j舰j饯j建j僵j姜j江j疆j蒋j讲j匠j酱j降j蕉j椒j礁j焦j胶j交j郊j骄j嚼j铰j脚j狡j角j饺j缴j教j酵j轿j较j叫j窖j揭j接j皆j秸j街j阶j截j劫j桔j捷j睫j竭j姐j戒j藉j芥g界j借j介j疥j诫j巾j筋j斤j金j兠d今j津j襟j紧j锦j谨j进j靳j禁j近j浸j継j続x综z綝c缍d綟l绿l綡j绻q綤s綧z綨j綩w綪q綫x绶s维w綯t绾w网w綳b缀z綶g綷c纶g绺l绮q绽z綼b绫l绵m緀q緁j緂t緃z绲g緅z緆x缁z緈x緉l绯f緌r緍m緎y総z緐f緑l绪x緓y緔s緕z緖x缃x缂k线x緜m緟c缗m緢m缘y緤x緥b缌s緧q緪g緫z缅m緭w緮f纬w緰x缑g缈m緳x练l緵z缏b緷g緸y缇t緺g荆j兢j茎j睛j晶j鲸j京j惊j精j粳j井j警j景j颈g静j境j敬j镜j靖j竟j炯j窘j揪j究j玖j韭j久j灸j九j酒j救j旧j臼j舅j咎j就j疚j鞠j拘j狙j疽j居j驹j菊j咀j矩j举j沮j聚j拒j巨j具j距j剏c踞j锯j俱j句g炬j捐j鹃j娟j倦j眷j撅j攫j抉j掘j倔j爵j觉j诀j均j菌j钧j军j君j峻j致z緼w緽c緾c緿d縀x縁y縂z縃x縄s縅o縆g縇s萦y缙j缢y缒z縌n縍b縎g縏p绉z缣j縒c縓q縔s縕y縖x縗c縘x縙r縜y缜z缟g缛r縠h縡z縢t县x縤s縥z縦z縧t縨h縩c縪b縬c缡l缩s演y縰x纵z缧l纤q缦m絷z缕l縸m缥p縺l縼x总z縿s繀s繂l繄y缫s缪m襁q繉s繊x繋j繌z繍x繎r繐s缯z繓z织z缮s繖s繗l繘j繙f缭l繛c繜z勩y俊j竣j浚j郡j骏j喀k咖g卡k咯g开k揩k楷j慨k刊k堪k勘k坎k砍k看k康k慷k糠k扛g抗k亢g炕k拷k烤k靠k坷k苛k柯k棵k磕k颗k科k咳h可k渴k刻k客k课k肯k啃k坑k吭h空k恐k孔k控k口k扣k寇k枯k哭k窟k苦k酷k裤k夸k垮k挎k跨k胯k筷k快k款k筐k狂k框k眶k亏k盔k葵k奎k魁k傀g绕r繟c繠r绣x缋h繣h繤z繥x繦q繧w繨d绳s繬s繮j缳h缲q繱c繲x繴b繵d繶y繷n繸s绎y繺s繻x缤b缱q繿l纀p纁x纃z纅y纆m纇l缬x纉z纩k续x累l纎x纐k纑l纒c缨y厠c纗z缵z纙l缆l纝l纞l纮h纴r纻z纼z绖d绤x绬y绹t缊w缐x缞c缷x缹f缻f缼q缾p罀z罁g罃y罆g罇z罉c罊q罋w罂y罍l罎t罏l罒w罓w馈k愧k坤k昆k括g廓k阔k垃l拉l喇l蜡l腊l辣l啦l莱l赖l蓝l婪l阑l兰l谰l览l榔l狼l廊l郎l朗l浪l牢l老l佬l姥l酪l烙l勒l雷l镭l蕾l磊l儡l肋l类l楞l冷l厘l梨l黎l狸l离l理l李l鲤l莉l荔l吏l丽l利l傈l例l俐l罙s罛g罜z罝j罞m罠m罣g罤t罥j罦f罧s罫g罬z罭y罯a罳s骂m罶l罸f罺c呩s罻w罼b罽j罿c羀l羂j羃m羄z罴p羇j羁j羉l羍d羏y羐l羑y羓b羕y羖g羗q羙m羠y羢r羟q羡x义y羬x羱y羴s羺n羾h翀c翃h翆c翇f翈x翉b翋l翍p翏l翐z翑q习x翓x翖x翗k翙h翚h翛x翜s翝h翞j翢d翣s哷l痢l立l粒l隶l力l璃l哩l联l莲l连l镰l廉l脸l链i啅z粱l良l辆l量l晾l亮l谅l撩l聊l僚l燎l寥l辽l潦l撂l镣l廖l料l列l烈l劣l琳l林l霖l临l邻l鳞l淋l赁l啙z啛c吝l拎l玲l菱l零l龄l铃l伶l羚l凌l灵l陵l领l另l令l溜l琉l榴l硫l馏l留l瘤l流l柳l六l龙l聋l窿l翤c翧x翨c翪z翫w翬h翯h翲p翴l翵h翶a翷l翸p翘q翽h翾x翿d耂l耇g耈g耉g耊d耎n耏n耓t耚p嗘j耝q耞j耟j耡c耣l耤j耫z耧l耭j耮l耯h耰y耲h耴y耹q耺y耼d耾h聀z聄z聅c聇z聈y聉w聏e聐y聑t聓x聕h圣s聗l聙j聛b聜d聝g闻w聟x聠p聡c聢x聣n聤t聥j聦c聧k聨l聫l聬w聭k聮l声s耸s聴t聩k聂n职z聸d聍n聺q聻n嘓g聼t听t拢l陇l漏l陋l芦l颅l虏l鲁l麓l碌l露l路l赂l鹿l潞l录l陆l驴l铝l旅l履l氯l律l率l卵l掠l略l轮l噵d论l萝l螺l逻l锣l骡l裸g落l洛l嚍j骆l嚒m蚂m马m嘛m埋m买m麦m卖m迈m脉m馒m蛮m蔓m曼m慢m漫m肁z肂s肃s肈z肊y肍q肎k肏c肐g肑d囄l肔c肕r肗r肙y肞c肣q肦b肧p肨p肬y肰r肳w肵q肶p肹x肻k胅d胇b胈b胉b胊q坺f垀h胏z胐f胒n胓p胔z胕f胘x胟m胠q胢q胣c胦y胮p胵c胷x胹e埱c埶y胾z胿g脀z脁t脃c脄m胁x脇x脋x脌n脕w脗w脙x胫j脜r脝h脟l脠s脡t脢m脤s脥j塈x睃s脨c修x脪x脱t脭c脮n脰d脳n脴p脵g脷l胀z脼l脽s脿b谩m芒m墽q茫m盲m氓m壔d忙m莽m猫m茅m锚m毛m矛m铆m卯m茂m冒m帽m貌m贸m么m玫m枚m梅m酶m霉m煤m眉m媒m镁m每m美m昧m寐m妹m媚m门m萌m檬m盟m锰m猛m孟m醚m靡m糜m迷m谜m米m觅m泌b蜜m密m棉m眠m冕m免m勉m娩m面m苗m妌j描m瞄m藐m秒m妛c妭b渺m妙m蔑m民m抿m皿m敏m姃z闽m明m螟m鸣m铭m名m命m谬m摸m腀l腁p腂g腃j腄c腅d腇n腉n腍r肾s腏z腒j腖d腗p腘g腛w腜m腝r腞z娊x脶l腢o腣d腤a脑n腨s腪y肿z腬r腯t腲w腵j婂m腶d腷b膁q腽w膄s膅t膆s膇z膉y膋l膌j膍p膎x膐l膒o膓c膔l膕g膖p膗c膙j膞z膟l膡y膢l膤x膥c膧t腻n膫l膬c膭k膮x媑z膯t膰f膱z膲j膴h媝q媡l膵c膶r膷x膸s膼z脍k脓n臄j臅c臇j臈l臋t脐q臎c膑b臐x臑n嫿h嬃x嬓j臓z摹m蘑m模m嬜x膜m磨m摩m嬟y魔m抹m末m莫m墨m默m沫m漠m寞m陌m谋m牟m某m拇m牡m姆m母m墓m暮m幕m募m慕m木m目m孨z睦m牧m穆m拿n哪n孶z钠n那n娜n氖n乃n奶n耐n奈n南n男n难n囊n闹n淖n呢n馁n嫩n能n妮n霓n倪n泥n尼n匿n逆n溺n蔫n拈n年n碾n酿n鸟d尿n捏n孽n镊n镍n涅n您n凝n臔x臕b臖x臗k臙y胪l臛h臜z臝l臞q脏z脔l臡n臢z卧w臦g臩g臫j臮j臯g臰c岅b臲n臵g臶j臷d臸z臹x岟y臽x臿c舃x与y兴x岪f岾z峊f舎s舏j舑t峣y舓s舕t铺p舗p峮q舘g舙h舚t舝x舠d舤f舥p舦t舧f舩c舮l舲l舼q峾y舽p艀f艁z艂f艃l艅y艆l艊b艌n艍j艎h艐k艑b艒m艓d艔d嵽d嶈q艖c艗y艛l艜d艝s艞y艠d艡d艢q舣y艥j艧h艩q牛m扭n钮n嶪y农n弄l奴n努n怒n女n暖n虐n挪n懦n糯n诺n哦e巆y鸥o藕o偶o巏q啪p趴p爬p帕p怕p琶p拍p排p牌p徘p湃p派p攀p潘f磐p盼p畔p判p叛p乓p庞p耪p胖p咆p刨b袍p跑p泡p呸p胚p培p裴p赔p陪p配p沛b盆p砰p抨p烹p澎p彭p蓬p棚p硼p篷p膨p朋p鹏p捧p碰p坯p砒p霹p批p披p劈p琵p毗p艪l舻l艬c艭s艵p艶y艳y艹a艻l艼d幯j庅m庺s芃p芅y芆c芇m廐j芉g芌y苄b芓z芔h芕s弐e芚t芛w芞q芠w芢r芣f芧x芲l弞s芵j芶g芺a刍c芼m芿r苀h苂c苃y苅y苆s苉p苐d苖d苙l苝b苢y苎z苨n苩p苪b苬x苭y苮x苰h徛j苲z徦j苳d苵d苶n苸h苺m苼s苽g苾b苿w徴z茀f徸z茊z茋z茐c茒y茓x茖g茘l忇l茙r茝c茞c怓n茠h茡z茢l茣w茤j茥g茦c茩h茪g茮j怱c茷f茻m茽z啤p脾p疲p皮p匹p恎d痞p僻p屁p譬p篇p偏p片p骗p恜c飘p瓢p票p撇p瞥p拼p频p贫p品p聘p乒p坪p苹p萍p平p瓶p评p屏b坡p颇p婆p破p魄b迫p粕p剖p莆p葡p菩p蒲p埔b圃b普p浦p谱p曝b瀑b期j欺q妻q七q漆q柒q沏q其j棋q奇j歧q畦q崎q愂b齐j祈q祁q起q岂q乞q企q契q器q迄q汽q泣q愪y讫q掐q茾q茿z荁h荂f荄g荅d愲g荈c荋e荌a荍q荎c荓p荕j荖l荗s荘z荙d荝c荢z慃y荰d荱w荲l荳d荴f荵r荶y荹b荺y荾s荿c莀c莁w莂b莃x莄g莇z莈m庄z莋z莌t莏s莐c莑p莔m莕x憉p莗c莙j莚y莝c莟h莡c莣w莤s莥n莦s憜d苋x莬w莭j莮n憡c莯m莵t莻n莾m莿c菂d菃q菄d菆c菈l菉l菋w菍n菎k菐p菑z菒g菓g菕l菗c憿j菙c菚z菛m菞l菢b菣q菤j菦q菧d菨j菫j懏j菬q菭t恰q洽q钎q铅q千q懡m迁q仟q谦q乾q黔q钱q钳q前q遣q谴q嵌k欠q歉q腔q羌q蔷q橇q锹q敲q悄q瞧q巧q鞘q撬q峭q俏q切q茄j且j怯q戵q侵q亲q秦q琴q勤q芹q擒q禽q沁q青q轻q卿q清q擎q晴q氰q情q顷q请q秋q丘q邱q求q囚q抯z酋q泅q趋q蛆q曲q躯q屈q驱q渠q菮g菳q庵a菵w拲g菶b菷z菺j挌g菼t菾t菿d萀h萅c苌c萈h萉f萐s萒y萓y萔t萕q萖w萗c萙k萚t萛j萞b萟y萠p萡b萢p萣d萩q萪k萫x万m萭y萮y萯f萰l萲x萳n萴c掤b莴w萶c萷s萹b萺m萻a萾y葀k葁j葂m葃z葄z葅z葇r葈x叶x葊a葋q葌j葍f葎l葏j葐p荭h葓h搮l摀w葕x葖t葘z葝q葞m葟h葠s葢g葤z摖q葥q苇w葧b葨w葪j葮d药y葰j葲q葴z摾j葹s葻l葼z取q娶q龋q趣q去q圈j颧q醛q泉q全q痊q拳q犬q券q撧j缺q炔g瘸q鹊q榷q裙q群q然r燃r冉r染r瓤r壤r攘r嚷r让r饶r惹r壬r擟m仁r人r忍r韧r任r认r刃r妊r扔r仍r日r戎r茸r擿t攂l蓉r融r熔r溶r攚w容r冗r揉r柔r肉r茹r蠕r儒r孺r如r辱r乳r汝r攺y入r褥r软r阮r蕊r瑞r锐r闰r若r弱r撒s萨s腮s鳃s塞s赛s三s叁s葽y葾y葿m蒀y蒁s蒃z蒄g蒅s蒆x蒍w蒏y蒐s蒑y蒒s蒓c莳s蒕y蒖z蒘r蒚l蒛q蒝y莅l蒟j蒠x蒢c蒣x蒤t蒥l蒦h蒧d蒨q蒩z蒪p蒫c蒬y蒭c蒮y蒰p蒱p蒳n斮z蒵x斳q蒷y蒻r蒾m荪s蓂m蓃s蓅l蓆x蓇g蓈l蓌c蓎t蓏l蓒x蓔y蓕g蓗z蓘g蓙g蓚t蓛c蓜p蓞d蓡s旤h蓢l蓤l蓧d蓨t蓩m蓪t蓫z蓭a苁c蓱p蓲q蓳j蓴c蓵j蓶w蓷t蓸c蓹y蓺y蓻z荜b蓾l蔀b蔁z蔂l散s桑s嗓s搔s骚s嫂s瑟s色s森s僧s莎s砂s沙s傻s啥s晇x煞s珊s苫s杉s山s煽s衫s闪s陕s擅s赡s膳s善s汕s晬z扇s商s赏s晌s上s尚s裳c梢s捎s稍s芍s勺s韶s少s哨s邵s奢s赊s蛇s舌s赦s射s涉s社s设s砷s申s呻s伸s身s深s娠s神s沈s暎y暔n甚s慎s生s甥s牲s蔃q暭h蔄m蔅y蔇j蔈b蔉g蔊h蔋d蔍l蔎s蔏s蔐d蔒h蔕d蔖c蔘s蔙x蔛h蔜a曌z曗y曻s蒌l蔠z蔢p蔤m茑n蔧h蔩y蔪j荫y蔮g蔯c蔰h蔱s蔲k蔳q枈p蔵z蔶z蔾l蔿w蕀j荨q蕂s蕄m蕅o蒇c蕇d蕋r蕌l蕍y荞q蕏z蕐h蕑j芸y蕔b莸y蕗l柛s荛r蕚e蕛t蕜f蕝j蕟f蕠r柨b蒉k蕣s蕥y蕦x蕧f柸b芜w蕫d蕬s萧x栭e蕯s蕰y蕱s蕳j蕵s蕶l蓣y蕸x桗d蕼s蕽n蕿x薀y薁y桜y省s盛c剩s失s施s诗s尸s虱s十s石d拾s什s梍z食s蚀s识s史s矢s使s屎s驶s始s式s示s士s世s梫q柿s事s拭s誓s逝s嗜s噬s适s棃l仕s侍s释s棇c饰s氏s市f恃s室s视s试s收s手s首s守s授s售s受s椃h瘦s蔬s梳s殊s抒s输s叔s舒s淑s椘c疏s赎s孰s熟s薯s暑s曙s署s蜀s黍s鼠s述s束s戍s竖s墅s庶s漱s薂x薃h楕t楖j楡y荟h薉h薋c芗x薍w薎m薐l薒c薓s薕l薖k榐z薗y薘d薙t薚t薝z薞s槀g薠f薡d薢x薣g薥s槁g薫x薬y薭b薱d槗q薲p薳y薴n薵c薶m薸p荠j薻z薼c薽z薾e薿n藀y藂c藃x藄q藅f藆j藇x藈k藊b藋d藌m荩j槸y藑q藒q藔l藖x藗s樐l藘l藙y藚x藛x艺y藞l藟l藠j藡d藢z藣b藦m藧h藨b薮s藫t藬t藭q藮q藯w藰l樼z樿s藲o藳g藴y藵b苈l藸z橩q恕s刷s耍s摔s衰c甩s栓s拴s霜s双s爽s谁s水s睡s吮s瞬s顺s舜s说s朔s斯s撕s嘶s思s私s司s死s肆s寺s嗣s四s似s饲s巳s松s颂s送s宋s讼s诵s搜s艘s嗽s酥s俗s素s檪l速s粟s僳s塑s溯s宿s诉s蒜s算s檾q櫈d櫐l虽s隋s随s髓s碎s穗s遂s隧s祟s櫢s梭s櫴l唆s索s锁s所s櫿y塌t他t她t欃c塔d蔺l欟g欦q藽q藾l歞e蘁w蘂r歬q殏q蕲q蘈t蘉m蕴y蘌y蘍x蘎j蘏j蘐x殭j毥x蘔j蘕p蘖n蘘r蘙y藓x蘛y蘜j蘝l蔹l蘟y蘠q蘡y茏l蘣t蘤h蘥y蘦l蘨y蘪m蘫l蘬g蘮j蘯d蘰k蘱l蘲l蘳h蘴f蘵z蘶w蘷k汦z汻h沕m蓠l蘻j蘽l蘾h虀j虁k泈z泘h虃j泿y虄s虅t洜l虇q虈x虉y虊l虋m虌b虒s虓x虖h虗x虘c虙f虚x虝h虠j浰l虡j虣b浲f虤y虥z虦z涖l涶t虩x虪s蹋t踏t胎t淃j抬t泰t酞t太t汰t坍t贪t檀t痰t潭t谭t谈t坦t毯t袒t碳t探t炭t渜n塘t搪t堂t棠t膛t唐t糖t倘c躺t淌t趟t掏t滔t萄t桃t逃t淘t陶t讨t套t特t腾t疼t誊t梯t湕j剔t踢t锑t提d题t蹄t啼t体t替t嚏t惕t涕t剃t湲y天t添t填t田t甜t恬t舔t腆t挑t眺t跳t贴t铁f帖t虭d虯q虰d虳j虴z虵s溳y滖s滜z滵m虸z蚃x蚄f漐z蚆b蚇c蚈q蚉w蚎y蚏y蚐j蚑q蚒t漹y潎p蚖y潣m蚗j蚘h蚙q蚚q蚛z蚞m蚟w蚡f蚢h蚥f蚦r蚫b澚a蚮d蚲p蚳c蚷j蚸l蚹f蚻z蚼g蚽p蚾p蛁d蛂b蛃b蛈t蛌t蛍y蛒g蛓c蛕h蛖m蛗f蛚l蛜y蛝x蛠l濵b蛡y蛢p蛣j濸c蛥s蛦y蛧w蛨m蛪q蛫g蛬q瀀y瀇w瀐j蛵x蛶j蛷q蛱j蜕t蛼c蛽b蛿h蜁x蜄s蜅f蚬x蜋l蜌b蜎y蜏y蜐j蜑d蜔d蜖h汀t廷t停t亭t庭t挺t艇t通t桐t酮t瞳t同t铜t彤t童t桶t灜y捅t筒t痛t偷t投t头t灩y透t凸t突t徒t途t屠t土t吐t兔t湍t推t颓t腿t褪t退t吞t屯t臀t拖t托t炏y鸵t陀t驮d炓l炗g驼t妥t拓t唾t挖w哇w蛙w娃w瓦w袜w炲t歪w外w豌w玩w顽w烷w完w碗w挽w晚w皖w惋w宛w烞p婉w腕w汪w王w烮l亡w枉w往w旺w望w忘w妄w威w蜙z蜛j蜝q蜟y蜠j蜤s蜦l蜧l蜨d蜪t蜫k蜬h蜭h蜯b蜰f蜲w蜳d蜵y蜶s蜸q蜹r蜺n蜼w蜽l蝀d蝁e蝂b蝃d蝄w蝅c焭q蝆y焲y蝋l蝍j蝏t焷p蝐m蝑x蝒m蝔j蝘y蝚r蝛w蝜f蝝y蝞m蝟w蝡r蝢x虾h蝧y蝨s蝩c蝪t蝫z蝬z蝭d蝯y蝱m蝲l蝳d蝵q蝷l蜗w蝹y蝺q蝿y螀j螁b蛳s螆c螇x螉w螊l螌b螎r螏j螑x螒h螔y螕b螖h螘y螙d螛h螜h螝g螠y螡w萤y螣t螤z巍w微w危w韦w违w桅w唯w惟w萎w委w尾w未w蔚w味w畏w胃w喂w魏w位w渭w谓w尉w慰w卫w瘟w蚊w文w燰w吻w紊w嗡w翁w爁l我w斡w握w沃w巫w钨w诬w屋w爗y爙r梧w吾w武w爠q五w捂w午w爥z舞w伍w侮w戊w雾w晤w物w勿w悟w误w昔x熙x析x西x硒x矽x晰x嘻x吸x牔b锡x螥c螦s螧q螩d螪s螮d螰l螱w螲d螴c螶q螷p螸y螹c蝼l螼q螾y螿j蟁w蟂x蟃w蛰z蟅z蝈g蟉l蟌c蟍l蟎m蟏x蟐c蟔m蟕z蟖s蟗q蟘t蟙z蟚p蟜j蟝q蟞b蟟l蟡g蟢x虮j蟤z蟦f蟧l蟨j蟩j蟫y狔n狚d蛲n猍l蟰x猏j蟱w蟳x蟴s蟵c蛏c蟷d蟸l蟺s蚁y蟼j蟽d蟿q蠀c蠁x蠂s蠄q蝇y虿c蠇l蠈z蠉x蠋z猽m蠌z蠍x蠎m蠏x蛴q蝾r蠒j蚝h獉z蠗z蠘j蠙b蠚h蠜f蠝l蠞j蠠m蛎l稀x息x希x悉x膝x夕x惜x熄x烯x溪x汐x犀x檄x袭x席x媳x喜x铣x洗x獹l隙x瞎x匣x霞x辖x暇x下x夏x掀x锨x先x仙x鲜x咸x贤x舷x闲x涎x嫌x显x险x腺x馅x陷x限x相x香x箱x襄x湘x乡x翔x祥x详x想x响x享x项x巷h橡x像x象x硝x霄x削x哮x销x消x宵x淆x蠤q蠥n蠦l蠧d蠨x蠩z蠪l蠫l蠬l蠭f蠮y蠯p蠰n蠳y蠴s蠵x瑊j瑘y蠸q瑦w瑸b璊m蠽j蠾z蠿z璠f衃p衆z衉k衋x衎k衏y衐q衑l衒x衕t衘x衦g衧y衪y甇y衱j衳z衴d衵r衶z衸j衺x衻r衼z袀j袃c袆h袇r畄l袉t袊l袌p袎y袏z袐b袑s袓j袔h袕x袗z袘y袙p畞m袚f畧l袝f袟z袠z袡r袣y袥t袦n袧g袨x袩z袪q小x孝x校j肖x疜x笑x效x楔x些x歇x疪b蝎x鞋x邪x斜x谐x械x卸x蟹x懈x痟x谢x屑x薪x痭b芯x锌x欣x辛x新x忻x心x信x衅x星x腥x猩x惺x刑x型x形x邢x行h醒x杏x性x姓x兄x胸x瘹d匈x雄x癁f熊x休x羞x朽x嗅x癊y锈x秀x袖x墟x戌q需x须x徐x许x蓄x酗x癦m旭x序x畜c絮n婿x轩x喧x宣x旋x玄x袬y袮m袯b袲c袳c袵r袶p袸j袹b袺j袻e袽r袿g裀y裃k裄h裇x裈k裋s裌j裍k裐j裑s裓g裖z裗l裚j裛y装z裞s裠q裦b裧c裩k裪t裫y裬l裭c裮c裯c裲l裵p裶f裷y裺y裻d制z裿y褀q褁g褃k褄q褅t褆t褈c褉x褋d褌k褍d褎x褏x褑y褔f褕y褖t褗y褘h褜p褝d褞y褟t褠g褢h褣r褤y褦n褧j褨s褩b褬s褭n褮y褯j褱h裢l褵l褷s选x眩x靴x薛x穴x雪x血x熏x循x旬x询x驯x巡x殉x汛x训x讯x逊x迅x押y鸦y鸭y丫y芽y牙y蚜y崖y衙y涯y雅y盶y讶y焉y阉y淹y盐y研y蜒y延y言y颜y阎y炎y沿y奄y掩y眼y衍y堰y燕y雁y唁y宴y谚y验y殃y央y鸯y秧y佯y羊y洋y氧y仰y养y漾y邀y腰y妖y褛l褹y褺d亵x褼x褽w褾b褿c襀j襃b襅q襆f襇j襈z襉j襊c襋j襌d襍z襎f襏b襑x襒b襓r襔m襕l襗z襘g襙c襚s襛n襜c裣l裆d襡s襢z襣b褴l襥f襧z襨t襩s襫s襭x襮b襰l襱l襳x襴l襵z襶d襷t襸z襹s襺j襼y襽l襾y覀y覂f覄f覅f覇b覉j瞈w覊j瞏q覌g覍b覎y瞔z覐j覑p覒m覔m覕p覗s觇c覙z覚j覛m覜t覝l覞y覟z覠j觋x遥y谣y姚y咬y舀y要y矊m耀y椰y噎y耶y野y冶y也y页y掖y腋y夜y液y一y壹y医y揖y铱y依y伊y衣y颐y夷y遗w移y胰y疑y沂y宜y姨y彝y椅y倚y已y乙y矣y以y抑y易y邑y屹g役y臆y逸y肄y疫y亦y裔y意y毅y益y溢y诣y议y谊y译y翼y翌y茵y因y音y阴y姻y吟y银y淫y寅y饮y尹y引y隐y覢s覣w覤x覥t觎y覧l矲b覨e覩d觊j覭m覮y觏g覰q覱z觐j観g覴d覵j覶l觑q覸j硡h硢y覻q覼l覾s觌d觃y觍t觕c觗z觘c觙j觛d觝d觟h觠q觡g觢s觤g觧j觨h觩q觪x觬n觭j觮j觰z觱b觲x觞s觵g觯z觷x觹x觺y觻l觼j觽x觾y觿x訁y訄q訅q訆j訉f訋d讧h訍c訏x讦j訑y訒r訔y讪s訙x訚y印y英y鹰y迎y赢y盈y影y硬y映y臃y庸y雍y踊y蛹y咏y碐l泳y永y恿y勇y用y幽y悠y尤y由y邮y铀y油y游y酉y碻q有y碽g友y磂l右y釉y诱y又y幼y迂y淤y于y盂y榆y虞y愚y舆y余y俞y逾y鱼y愉y渝y磭c隅y予y磰s雨y禹y宇y语y羽y玉y域y礃z芋y郁y遇y喻y峪y愈y育y誉y訞y訠s訡y讷n訦c訧y訨z訩x訫x訬c訮y訯s訰z訲y訳y訵c诃h訷s訸h訹x诊z注z证z訽g訿z詀z诂g詂f詃j詄d詅l诋d詇y詊p詋z詌g詍y讵j詏y诈z詑t诒y詓q诏z詖b礶g祍r祘s诎q詙b詚d诅z詜t詝z詟z诩x祱s詤h詥h祶d詧c詨x詪h诟g禈h诠q詯h诘j祯z詴w诜s詶c詷t詸m詻l诙h詽y詾x诖g誀e浴y寓y裕y预y豫y驭y鸳y冤y元y垣y袁y原y援y辕y猿y源y远y苑y愿y怨y院y曰y越y跃y钥y月y阅y耘y云y郧y陨y允y运y酝y韵y孕y匝z砸z杂z栽z哉z宰z载z再z在z赞z赃z葬z遭z糟z凿z藻z早z澡z蚤z躁z噪z造z皂z灶z燥z责z贼z怎z增z憎z曾c赠z喳c秢l渣z札z轧g誁b誂t誃y诔l诛z诓k誈w誋j志z誏l誐e诳k诶a誔t誖b誗c誙k诮q誛q誜s誝a誟x誢x诰g誧b誩j誫z説s読d誮h誯c誱j誳q誴c誵x谇s誷w誸x誺c誻t誾y諀p諁z谄c諃c谆z諅j諆j諈z诿w諊j諌d诤z諎z诹z諐q诼z諓j諔c諕x谂s諘b諙h諚b谀y諝x稬n谝p諟s諠x諡s诨h諣h稸x穉z铡z闸z眨z榨z咋z穙p乍z炸z摘z斋z穠n宅z窄z寨z瞻z詹z粘n沾z辗z展z蘸z站z湛z樟z章z彰z漳z掌z杖z丈z账z仗z瘴z障z招z昭z找z沼z赵z照z罩z兆z肇z召s遮z折s哲z辙z者z锗z蔗z这z浙z珍z斟z真z甄z砧z臻z贞z针z枕z疹z震z振z镇z阵z蒸z征z怔z整z拯z正z政z谔e諥z谛d諨f諩p諪t谏j諬q谕y谘z諯z諰x諲y谙a諴x諵n谌c诸z諹y諻h谖x窧z窽k谒y竌c竨d竪s诌z謆s謈b謉k謋h謌g謍y謏x竸j谧m謑x謒q謓c谑x謕t谡s謘c谥s謜y謞h謡y謢l謣y謤b謥c謧l谟m謩m謪s谪z謭j謮z謯j謰l謱l讴o謴g謵x謶z謷a謸a謺z謻y謼h謽j謿c譀h譂c譃x譄z譅s郑z芝z枝z支z吱z蜘z知z肢z脂z汁z之z直z植z殖s值z址z指z止z趾z旨z至z置z峙s智z秩z稚z质z炙z痔z治z窒z中z盅z筳t筴c忠z钟z衷z重c仲z舟z箈t周z州z洲z粥y轴z肘z帚z咒z宙z骤z珠z株z蛛z猪z逐z竹z煮z拄z主z著z柱z助z蛀z贮z铸z譆x譇z譈d譊n譋l譌e谲j譐z譑j譒b譓h譔z譕w谮z譗z谯q譛j譝s譞x譠t譡d譢s譣x譤j譥j譧z譨n譩y谵z譭h譮h譱s譲r譳r篒y譶t譸z譹h譺a譻y譼j譾j譿h讁z讂j讃z讄l讅s讆w讇c讉y讋z篻p讌y讍e雠c讏w讐c讑y讔y谶c讗x讘n讙h讛y谠d讝z谳y讟d讬t讱r讻x诇x诐b诪z谉s谞x住z祝z驻z抓z爪z拽z转z撰z赚z篆z撞z椎c锥z追z赘z捉z拙z卓z桌z琢z茁z酌z啄z着z灼z咨z资z姿z滋z淄z孜z紫z仔z籽z滓z自z字z鬃z棕z踪z宗z邹z走z奏z揍z租z足z卒c族z祖z阻z钻z纂z嘴z醉z最z罪z尊z遵z昨z左z佐z柞z做z作z坐z座z谸q谹h谺x谻j谼h谽h谾h谿x豀x豂l豃h豄d豅l豋d豍b豏x豑z豒z豓y籋n豖c豗h豘t豙y豛y豜j豝b豞h豟e豠c豣j豤k豥g豦j豧f豨x豩b豭j豮f豯x豰h豱w豲h豴d豵z豷y豻a豼p豽n豾p豿g貀n貁y貃m貄s貆h貇k貈h貋a貎n貏b貐y貑j貒t貕x貖y貗j貙c貚t貛h貜j粎m粓g貟y粡t貣d貤y貦w貭z亍c丌q兀w丐g廿n卅s丕p丞c鬲g孬n噩e丨g禺o丿p匕b乇z夭a爻y卮z氐d囟x胤y馗k毓y鼗t丶z亟j鼐n乜m亓q孛b嘏g厝c厥j靥y赝y匚f叵p糂s匾b赜z卦g卣y刂d刈y刎w刳k剌l糛t剞j剡s剜w蒯k剽p劂j劁q劐h劓y冂j罔w亻r仃d仉z仨s糿g仫m仞r仳p伢y佤w仵w伉k紤j佞n佧k攸y佚y佝g貮e贳s貱b赀z貵p貹s贶k絾c綛k綥q緛r繏x繑q繝j纄p纋y纕x纚l缿x翄c翭h翺a耛s聎t肒h肸x胋t胑z胻h脦t脺c脻j腟c臒w臤q臱m舋x舿k艕b芀t芁q芖z苚y茟y茰y莍q菻l萂h萿k葔h蔝m蔨j蔴m蕮x薆a莶x藱h藼x蘀t蘃r蘒q蘓s蘹h虂l虆l虨b虶y虷h蚅e蚔q蚭n蚿x蛯e蝖x螐w螚n蟭j蠷q蠺c衂n衭f袛d袾z襂s襐x覫p覹w觓q訤x詉n詗x詺m誎c誽n諽g諿x謃x謟t謲c譍y譪a譵d貥h乩j仡g斛h颢h銮l乊h乥h夫f兓j兙s兛q兝g兞h兣g兺b囻g坟f妢f婲h孒j尅k屗u岎f帉f幥z幩f弅f徚u怭b怾g慙c昐f晲n曢u朆f朌f朑u朩p枌f梤f乐l橨f檂n欂b毜c毮s洂y涜d颍y澵z炃f炍p炾h烪u焑y焺s燌f燓f燞u燢x獖f瓧s瓰f瓱m瓲t瓼l榛z彳c夔k璞p丟d並b丬p乂y乄s亙g亞y亠t亳b仝t伋j伕f伲n伽g佇z佈b佔z佗t佘s佟t佪h佴e併b佶j佻t佼j佾y侃k來l侉k侏z侑y侔m侖l侶l侷j俅q俎z俑y俚l俜p俟q俠x俳p俸f俾b倆l倉c個g倌g倏s們m倖x倜t倣f倥k倨j倩q倫l倬z倭w倮l偃y偈j偉w偌r偎w偕x側c偵z偺z偽w傖c傘s備b傢j傭y傳c傴y債z傷s傺c傾q僂l僅j僇l僉q僑q僕p僖x僥j僦j僬j僭j僮t僱g價j儀y儂n億y儅d儆j儇x儉j儋d儐b儔c儕c儘j優y儲c儷l儸l儺n儻t儼y兌d兒e兕s兗y內n兩l兮x冊c冑z冖m冢z冥m冪m冫b冱h冼x冽l凇s凈j凍d凫f凱k凵k凼d刖y別b刪s剄j則z剋k剎c剛g剝b剮g剴k創c剷c劃h劇j劉l劊g劌g劍j劑j劬q劭s劻k劾h勁j勐m動d勗x務w勛x勝s勞l勢s勣j勦j勰x勱m勵l勹b勻y匍p匏p匐f匭g匯h匱k區q協x卟b卩j卹x卻q厙s厭y厲l厴y厶s參c叟s叢c叨d叩k叱c叻l吆y吋c吒z吖y吡b吣q吲y吳w吶n呂l呃e呋f呎c呔d呤l呦y呱g呲c呶n呷g咂z咄d咔k咚d咝s咣g咤c咦y咧l咩m咪m咫z咭j咻x咼w咿y哂s哌p哏g哐k哚d哞m員y哧c哳z哽g哿g唄b唅h唏x唑z唔m唣z唧j唪f唰s唳l唷y唸n唼s唿h啁z啉l問w啐c啕t啖d啞y啟q啣x啵b啶d啷l啻c啾j喁y喃n喈j喋z喏n喑y喔o喙h喚h喟k喪s喫c喬q單d喱l喵m嗄a嗆q嗇s嗉s嗌y嗍s嗎m嗑k嗒d嗔c嗖s嗚w嗝g嗟j嗤c嗥h嗦s嗨h嗪q嗬h嗲d嗵t嗶b嗷a嗾s嘀d嘁q嘈c嘌p嘍l嘔o嘖z嘜m嘞l嘟d嘣b嘧m嘩h嘬c嘭p嘮l嘯x嘰j嘵x嘸f嘹l噁e噌c噍j噓x噔d噗p噘j噙q噠d噢o噤j噥n噦y噫a噯a噱j噲k噴p噸d噹d噻s噼p嚀n嚅r嚆h嚇h嚌j嚐c嚓c嚙n嚥y嚦l嚨l嚮x嚯h嚳k嚴y囀z囁n囂x囅c囈y囉l囌s囑z囔n囗w囝j囡n囪c囫h囹l囿y圄y圇l圉y圊q國g圍w園y圓y圖t圜h圩w圪g圮p圯y圳z圻q坂b坌b坨t坩g坫d坭n坰j坳a坶m坻c坼c垅l垌d垓g垠y垡f垤d垴n埏s埒l埕c埝n埡y埤p埭d埯a埴z執z埸y埽s堀k堅j堇j堊e堋b堍t堙y堞d堠h報b場c堿j塄l塊k塋y塍c塒s塗t塢w塤x塥g塬y塵c塹q塾s墀c墁m墉y墊d墑d墚l墜z墮d墻q壅y壇t壑h壓y壙k壚l壞h壟l壢l壩b壯z壺h壽s夂z夙s夠g夢m夤y夥h夼k夾j奐h奕y奘z奚x奧a奪d妁s妃f妍y妗j妝z妞n妣b妤y妯z妲d妳n妾q姊z姍s姒s姘p姝s姣j姦j姪z姹c娉p娌l娑s娓w娛y娣d娼c婀e婊b婕j婢b婦f婧j婭y婷t婺w媛y媧w媯g媲p媸c媼a媽m媾g嫖p嫗y嫘l嫜z嫠l嫣y嫦c嫫m嫵w嫻x嬈r嬉x嬌j嬖b嬗s嬙q嬝n嬡a嬤m嬰y嬲n嬴y嬸s孀s孃n孑j孓j孚f孢b孥n孫s孱c孳z學x孿l宀m宄g宓m宕d宥y宮g宸c寢q寤w實s寧n審s寫x寬k寮l寰h寵c寶b將j專z尋x對d尕g尜g尢w尥l尬g尷g尻k屄b屆j屐j屙e屜t屣x層c屬s屮c屺q岈y岌j岍q岐q岑c岙a岜b岡g岢k岣g岧t岫x岬j岱d岵h岷m峁m峋x峒d峴x島d峽x崆k崍l崗g崙l崛j崞g崠d崢z崤x崦y崧s崮g崴w崽z崾y嵇j嵊s嵋m嵒y嵩s嵫z嵬w嵯c嵴j嶁l嶂z嶄z嶇q嶗l嶙l嶷n嶸r嶺l嶼y嶽y巋k巑c巔d巖y巛c巰q巹j巽x帑t帔p帙z帥s帳z帶d帷w幃w幄w幔m幘z幛z幞f幟z幡f幣b幪m幫b幬c幹g幺y幾j庀p庂z庋g庖p庠x庥x庫k庳b庹t庾y廁c廂x廄j廈s廑q廒a廚c廛c廝s廡w廢f廣g廨x廩l廬l廱y廳t廴y廾g弁b弈y弋y弒s弔d弩n弭m弳j張z強q弼b彀g彆b彈d彊q彌m彎w彐x彖t彗h彘z彙h彡s彥y彫d彷f彿f徂c徇x徉y後h徑j徙x徜c從c徠l徨h復f徫w徬p徭y徵z徹c徼j忉d忐t忑t忒t忖c忝t忡c忤w忪s忭b忮z忸n怊c怍z怏y怙h怛d怡y怦p怩n怫f怵c恁n恂x恆h恙y恚h恝j恣z恥c恧n恪k悃k悅y悌t悒y悖b悚s悛q悝k悱f悴c悵c悶m悻x悽q惆c惘w惙c惝t惡e惱n惲y惴z惻c愀q愆q愍m愎b愕e愛a愜q愣l愨q愫s愴c愾k慄l慇y慊q態t慍y慘c慚c慝t慟t慣g慫s慮l慵y慶q慼q慾y憂y憊b憐l憑p憔q憚d憝d憧c憩q憫m憬j憲x憶y憷c懇k應y懋m懌y懍l懔l懞m懟d懣m懨y懲c懵m懶l懷h懺c懼j懾s懿y戀l戇g戉y戔j戕q戛j戟j戡k戢j戤g戥d戧q戩j戰z戲x戶h戽h戾l扃j扈h扌s扐c扠c扢g扺z抃b抆w抎y抴y抻c拊f拋p拗a拮j拶z挈q挲s挶j挹y挾x捃j捋l捨s捩l捫m捭b捱a捺n掃s掄l掊p掎j掙z掛g採c掬j掭t掮q掰b掾y揀j揄y揆k揎x揚y換h揞a揠y揲d揶y揸z揹b搆g搋c搌z損s搖y搗d搛j搟x搠s搡s搦n搴q搶q搿g摁e摑g摒b摜g摞l摟l摭z摯z摳k摶t摺z摻c撈l撓n撙z撚n撟j撣d撥b撫f撲p撻t撾z撿j擁y擄l擇z擊j擐h擔d擗p擘b據j擠j擢z擣d擤x擬n擯b擰n擱g擲z擴k擷x擺b擻s擼l擾r攄s攆n攉h攏l攔l攖y攙c攛c攜x攝s攢z攣l攤t攥z攬l攮n攴p攷k敉m敕c敗b敘x敫j敵d斂l斃b斐f斕l斫z斬z斷d於w旂q旃z旄m旆p旌j旎n旒l旖y旮g旯l旰g昀y昃z昇s昊h昕x昝z昱y昴m昶c晁c時s晉j晏y晗h晝z晞x晟c晡b晷g暄x暈y暉h暌k暘y暝m暨j暫z暱n暸l暹x暾t曄y曆l曇t曉x曖a曛x曜y曠k曩n曬s曷h書s會h朊r朐q朕z朦m朧l朮s杇w杈c杌w杓b杞q杪m東d杲g杳y杵c杷b杼z枇p枋f枘r枙e枰p枳z枵x枸g柁d柃l柘z柚y柝t柢d柩j柰n柵s栝g栩x栲k栳l桀j桁h桄g桉a桊j桎z桕j桫s桴f桷j桿g梃t梏g梓z梔z條t梟x梩q梵f棄q棖c棗z棟d棣d棧z棰c棲q棹z棼f椋l椏y椐j椴d椹s楂c楊y楓f楗j楝l楠n楣m楦x楨z楫j業y楮c楱c極j楸q楹y榀p榍x榕r榘j榙t榧f榪m榫s榭x榮r榱c榻t榿q槃p槊s槌c槍q槎c槓g槧q槨g槭q槲h槳j槿j樁z樂l樅c樑l樓l樗c樘t標b樞s樨x樵q樸p樹s樺h樽z樾y橄g橈r橋q橐t橘j橛j機j橢t橫h檁l檉c檎q檔d檗b檜g檠q檢j檫c檯t檳b檸n檻j櫓l櫚l櫛z櫝d櫟l櫥c櫧z櫨l櫪l櫬c櫳l櫸j櫺l櫻y欄l權q欏l欒l欖l欞l欷x欹q歃s歆x歎t歐o歙s歟y歡h歲s歷l歿m殂c殄t殍p殘c殞y殤s殪y殫d殮l殯b殲j殳s殺s殼k毀h毂g毆o毌g毪m毬q毳c毹s毽j毿s氅c氆p氈z氌l氍q氕p氘d氙x氚c氡d氣q氤y氪k氫q氬y氳y氵s氽c氾f汆c汊c汍w汎f汔q汜s汨m汩g汴b汶w決j沅y沆h沌d沐m沒m沓d沔m沖c沭s沱t沲t泐l泓h泔g泖m泗s泠l泫x泮p泯m泱y洄h洇y洌l洎j洙z洚j洧w洩x洫x洮t洳r洵x洶x洹h浜b浞z浠x浣h浬h浯w浹j浼m涇j涑s涓j涔c涫g涮s涼l涿z淅x淇q淒q淙c淚l淝f淞s淠p淥l淦g淨j淪l淵y淶l淼m渙h渚z減j渥w渦w渫x測c渲x渾h湄m湊c湎m湓p湔j湞z湟h湧y湫j湮y湯t溆x溏t準z溘k溝g溟m溥p溧l溫w溱q溲s溴x溷h溻t溼s溽r滂p滄c滅m滎x滏f滕t滟y滬h滯z滲s滷l滸h滹h滾g滿m漉l漕c漚o漢h漣l漤l漩x漪y漬z漭m漯l漲z漶h漸j漿j潁y潑p潔j潛q潟x潢h潤r潯x潰k潲s潴z潷b潸s潺c潼t澀s澆j澇l澉g澌s澍s澗j澠m澤d澧l澩x澮k澱d澶c澹d濂l濃n濉s濕s濘n濛m濞b濟j濠h濡r濤t濫l濮p濯z濰w濱b濺j濼l瀅y瀆d瀉x瀋s瀏l瀕b瀘l瀚h瀛y瀝l瀟x瀠y瀣x瀧l瀨l瀰m瀲l瀵f瀹y灃f灄s灑s灕l灘t灝h灞b灣w灤l灬h災z炅g炫x炱t為w炻s烀h烊y烏w焐w焓h無w焯c焱y煅d煉l煊x煒w煙y煜y煢q煦x煨w煩f煬y煲b煳h煸b煺t熒y熗q熘l熠y熨y熱r熳m熵s熹x熾c燁y燄y燉d燐l燒s燔f燙t營y燠y燦c燧s燬h燭z燮x燴h燹x燼j燾d爐l爛l爝j爨c爭z爰y爺y爾e爿p牆q牒d牖y牘d牝p牠t牦m牪y牮j牯g牴d牽q牿g犄j犍j犏p犒k犛l犟j犧x犭q犰q犴a犸m狀z狁y狃n狍p狎x狒f狨r狩s狳y狴b狷j狹x狺y狻s狽b猁l猊n猓g猗y猙z猝c猞s猢h猥w猬w猱n猶y猷y猸m猹c猻s獄y獅s獍j獐z獒a獗j獠l獨d獪k獫x獬x獯x獰n獲h獵l獷g獸s獺t獻x獼m獾h玀l玆z玎d玟m玢b玨j玳d玷d珀p珂k珈j珉m珙g珞l珥e珧y珩h珮p現x琊y琚j琛c琥h琦q琨k琪q琬w琮c琰y琺f琿h瑁m瑕x瑗y瑙n瑛y瑜y瑣s瑤y瑩y瑪m瑭t瑯l瑾j璀c璇x璉l璋z璐l璜h璣j璦a璧b璨c璩q璺w璽x瓊q瓏l瓖x瓚z瓞d瓠h瓴l瓿b甍m甏b甑z甓p甙d產c甦s甬y町d甾z畀b畈f畋t畎q畚b畛z畝m畫h畬s異y畹w畼c畿j疃t疊d疋y疒n疔d疝s疣y疬l疰z疳g疴k疸d疿f痂j痃x痄z痍y痖y痙j痣z痤c痦w痧s痲m痳m痼g痿w瘀y瘃z瘊h瘌l瘍y瘐y瘓h瘕j瘙s瘛c瘞y瘠j瘡c瘢b瘥c瘭b瘰l瘳c瘺l瘼m癀h療l癃l癆l癇x癍b癔y癖p癜d癟b癡c癢y癥z癩l癬x癭y癮y癯q癰y癱t癲d發f皈b皎j皓h皙x皚a皤f皰p皴c皸j皺z皻z盍h盜d盞z盡j監j盤p盥g盧l盪d盱x盹d眄m眇m眈d眍k眚s眢y眣d眥z眭s眵c眸m睇d睏k睚y睜z睞l睢s睥b睨n睪y睽k睿r瞀m瞌k瞍s瞑m瞞m瞟p瞠c瞢m瞭l瞰k瞵l瞼j瞽g瞿j矇m矍j矓l矚z矜j矧s矬c矯j矸g砉h砑y砘d砜f砝f砟z砣t砥d砩f砬l砭b砲p砹a砼t硃z硇n硌g硎x硐d硤x硨c硪w硭m硯y碇d碓d碚b碣j碥b碩s碲d碹x碼m磉s磔z磙g磚z磣c磧q磬q磯j磲q磴d礅d礎c礓j礙a礞m礤c礦k礪l礫l礱l礴b礻s祀s祅y祇q祉z祐y祓f祕m祗q祚z祛q祜h祠c祧t祺q祿l禊x禍h禎z禚z禦y禧x禮l禰m禱d禳r禿t秈x秕b秣m秫s秭z稂l稃f稅s稆l稈g稔r稜l稞k稟b種z稱c稷j稹z穀g穌s積j穢h穩w穫h穰r穸x穹q窀z窆b窈y窕t窠k窨x窩w窪w窬y窮q窯y窳y窶j窺k竄c竅q竊q竦s競j竺d竽y笄j笈j笊z笏h笙s笞c笠l笤t笥s笪d笫z笮z笱g笳j笸p笻q筆b筌q筍s筘k筠j筢p筮s筲s筵y筻g箄b箇g箋j箏z箐q箜k箝q箬r箴z箸z節j篁h範f築z篋q篌h篚f篝g篠x篤d篥l篦b篩s篪c篳b篼d篾m簀z簋g簌s簍l簏l簑s簟d簡j簣k簦d簪z簫x簷y簸b簽q簾l籀z籃l籌c籐t籜t籟l籠l籤q籥y籩b籪d籬l籮l籲y粑b粞x粢z粧z粲c粵y粼l粽z糅r糇h糈x糌z糍c糗q糝s糢m糧l糨j糰t糲l糴d糶t糸m糾j紀j紂z約y紅h紇h紈w紉r紋w納n紐n紓s紕p紗s紙z級j紜y紡f紮z細x紱f紲x紳s紹s紺g紼f紿d絀c終z絃x組z絆b絎h結j絛t絞j絡l絢x給g絨r統t絲s絳j絹j綁b綃x綆g綈t綏s綑k經j綜z綞d綠l綢c綣q綦q綬s維w綮q綰w綱g網w綴z綵c綸l綹l綺q綻z綾l綿m緇z緊j緋f緒x緗x緘j緙k線x緝j緞d締d緡m緣y緦s編b緩h緬m緯w緱g緲m練l緶b緹t緻z縈y縉j縊y縐z縑j縚t縛f縝z縞g縟r縣x縫f縭l縮s縯y縱z縳z縴q縵m縶z縷l縹p縻m總z績j繅s繆m繇y繈q繒z織z繕s繚l繞r繡x繢h繩s繪h繫x繭j繯h繰q繳j繹y繼j繾q纈x纊k續x纍l纏c纓y纔c纖x纘z纛d纜l纟s绔k绛j绱s缰j缶f缽b罄q罅x罈t罌y罘f罟g罡g罨y罰f罱l罵m罹l罾z羅l羆p羈j羋m羝d羧s義y羯j羰t羲x羸l羼c羿y翊y翎l習x翕x翡f翥z翦j翩p翮h翳y翹q耄m耆q耋d耑d耒l耔z耖c耜s耠h耢l耥t耦o耨n耩j耬l耱m耵d耷d聃d聆l聒g聞w聯l聰c聱a聲s聳s聵k聶n職z聹n聽t聾l聿y肅s肓h肜c肟w肫z肭n肱g肴y肷q肼j肽t胂s胍g胗z胛j胝z胥x胨d胩k胬n胭y胱g胲h胴d胼p脅x脈m脎s脒m脘w脛j脞c脣c脧j脩x脫t脬p脲n脹z腈j腌a腎s腓f腙z腚d腠c腡l腦n腧s腩n腫z腭e腱j腴y腸c腼m膂l膃w膈g膚f膠j膦l膪c膺y膻s膽d膾k膿n臁l臉l臊s臌g臍q臏b臚l臟z臠l臧z臨l臬n臾y舁y舂c舄x與y興x舉j舊j舐s舖p舛c舡c舢s舨b舫f舭b舯z舳z舴z舸g舺x舾x艄s艉w艋m艏s艚c艟c艣l艦j艨m艫l艮g艱j艴f艷y艸c艽j艿n芄w芊q芎x芏d芑q芘b芙f芟s芡q芤k芨j芩q芪q芫y芮r芰j芴w芷z芻c芾f苊e苒r苓l苕s苘q苜m苠m苡y苣j苤p苧n苴j苷g苻f茆m茇b茈c茉m茌c茍j茗m茚y茛g茜q茭j茯f茱z茲z茳j茴h茺c茼t荀x荃q荇x荊j荏r荑t荬m荸b荻d荼a荽s莊z莒j莓m莘s莛t莞g莠y莢j莧x莨l莩f莪e莰k莺y莼c菀w菁j菅j菔f菖c菘s菝b菟t菡h菥x華h菰g菸y菹z菽s萁q萃c萆b萊l萋q萏d萑h萘n萜t萬w萱x萵w萸y萼e葆b葉y葑f葙x葚r葜q葦w葩p葭j葯y葳w葶t葷h葸x葺q蒈k蒎p蒔s蒗l蒞l蒡b蒴s蒺j蒼c蒽e蒿h蓁z蓊w蓋g蓍s蓐r蓓b蓥y蓦m蓯c蓰x蓼l蓽b蔌s蔔b蔟c蔣j蔥c蔦n蔭y蔸d蔻k蕁q蕃f蕈x蕎q蕓y蕕y蕖q蕙h蕞z蕢k蕤r蕨j蕩d蕪w蕭x蕷y蕹w蕺j蕻h薅h薇w薈h薊j薌x薏y薑j薔q薜b薟x薤x薦j薧h薨h薩s薰x薷r薹t薺j藁g藍l藎j藜l藝y藥y藪s藶l藷s藹a藺l藿h蘄q蘅h蘆l蘇s蘊y蘋p蘗b蘚x蘢l蘧q蘩f蘭l蘺l蘼m蘿l虍h虔q處c虛x虜l號h虢g虧k虬q虺h虻m蚋r蚍p蚓y蚣g蚧j蚨f蚩c蚪d蚯q蚰y蚱z蚴y蚵k蚶h蚺r蛄g蛅z蛉l蛐q蛑m蛘y蛞k蛟j蛩q蛭z蛸s蛺j蛻t蜃s蜆x蜇z蜈w蜉f蜊l蜍c蜓t蜚f蜞q蜢m蜣q蜥x蜩t蜮y蜱p蜷q蜻q蜾g蜿w蝌k蝓y蝕s蝙b蝠f蝣y蝤q蝥m蝦x蝮f蝰k蝸w蝻n蝽c螂l螃p螅x螋s螓q螗t螞m螢y螨m螫s螬c螭c螯a螳t螵p螻l螽z蟀s蟄z蟆m蟈g蟊m蟋x蟑z蟒m蟓x蟠p蟥h蟪h蟬c蟮s蟯n蟲c蟶c蟻y蟾c蠃l蠅y蠆c蠊l蠐q蠑r蠓m蠔h蠖h蠛m蠟l蠡l蠣l蠱g蠲j蠹d蠼q衄n術s衛w衝c衢q衤y衩c衲n衹z衽r衾q衿j袂m袈j袞g袢p袤m袷q裊n裎c裏l裒p裘q補b裝z裟s裡l裥j裨b裰d裱b裼t製z裾j複f褊b褓b褙b褚c褡d褫c褰q褲k褳l褶z褻x襝l襞b襠d襤l襦r襪w襬b襯c襻p覃q見j規g覓m視s覘c覡x覦y親q覬j覯g覲j覷q覺j覽l覿d觖j觚g觜z觥g觫s觳h觴s觶z觸c訂d訃f訇h訊x訌h討t訐j訓x訕s訖q託t記j訛e訝y訢x訣j訪f設s許x訴s診z註z証z訾z詁g詆d詈l詎j詐z詒y詔z評p詘q詛z詞c詠y詡x詢x詣y詩s詫c詭g詮q話h該g詵s詼h誅z誆k誇k誌z認r誑k誕d誘y誚q語y誠c誡j誣w誤w誥g誨h誰s課k誶s誼y調d諂c諄z談t諉w請q諍z諏z諑z諒l論l諗s諛y諜d諞p諢h諤e諧x諫j諮z諱h諳a諶c諷f諸z諺y諾n謀m謁y謂w謅z謇j謊h謎m謐m謔x謗b謙q謚s講j謝x謠y謦q謨m謫z謬m謳o謹j譁h證z譎j譖z識s譙q譚t譜p譟z譫z譯y議y譴q護h譽y讀d讎c讒c讓r讕l讖c讚z谫j豇j豈q豉c豎s豐f豔y豕s豚t豬z豳b豸z貂d貅x貊m貍l貓m貔p貘m貝b負f財c貢g貧p貨h販f貪t貫g責z貯z貰s貲z貳e貴g貶b貸d貺k貼t貾c貿m賁b賂l賃l賄h賅g賆p資z賈j賉x賊z賋j賌g賎j賏y賐j賑z賒s賓b賔b賕q賖s賗c賘z賙z賛z賜c賝c賞s賟t賠p賡g賢x賣m賤j賥s賧d賨c賩c質z賬z賭d賮j賯x賰c賳z賴l賵f賶c賷j賸s賹y賺z賻f購g賽s賾z賿l贀y贂c贃w贄z贅z贆b贇y贈z贉d贊z贋y贌p贍s贎w贏y贐j贑g贒x贓z贔b贕d贗y贘s贙x贚l贛g贜z贠y贲b贻y贽z赅g赆j赇q赈z赉l赍j赑b赒z赓g赕d赗f赙f赟y赥x赧n赨t赩x赪c赬c赭z赮x赯t赱z赲l赳j赸s赹q赺y赻x赼z赽j赿c趂c趃d趄j趆d趇x趈z趉j趌j趍q趎c趏g趐x趑z趔l趖s趗c趘x趚s趜j趝j趞q趠c趡c趤d趥q趧t趨q趩c趪h趫q趭j趮z趯t趰e趱z趲z趵b趷k趹j趺f趻c趼j趽f趿t跁b跂q跄q跅t跆t跇y跈j跉l跍k跎t跏j跐c跒q跓z跔j跕d跖z跗f跘p跙j跚s跛b跜n跞l跠y跡j跢d跣x跤j跦z跧q跩z跫q跬k跭x跰p跱z跲j跴c跶d跷q跸b跹x跻j跼j跽j跾s跿t踀c踁j踂n踃x踄b踅x踆c踈s踉l踍q踎m踑j踒w踓w踔c踕j踗n踘j踙n踚l踛l踝h踟c踡j踣b踥q踦q踧c踫p踬z踭z踮d踯z踰y踱d踲d踳c踴y踵z踶d踷z踸c踹c踺j踻g踽j踾f踿c蹀d蹁p蹂r蹃n蹇j蹉c蹊q蹍n蹐j蹑n蹒p蹓l蹔z蹕b蹖c蹗l蹘l蹙c蹚t蹛d蹜s蹝x蹞k蹟j蹠z蹡q蹢d蹣p蹤z蹥l蹧z蹨n蹩b蹪t蹫j蹮x蹯f蹰c蹱z蹳b蹴c蹵c蹶g蹷j蹸l蹹t蹺q蹻q蹼p蹽l蹾d躀g躂d躃b躄b躅z躆j躈q躉d躊c躋j躍y躎n躏l躐l躑z躒l躓z躔c躕c躖d躗w躘l躙l躚x躛w躜z躝l躞x躟r躠s躡n躢t躣q躥c躦z躧x躨k躩j躭d躮s躰t躱d躵h躶l躷a躸j躹j躻w躽y躾x躿k軀q軁l軃d軄z軆t軇d軉y車c軋y軌g軎w軏y軐x軑d軒x軓f軔r軕s軖k軗s軘t軙c軚d軜n軝q軟r軠k軡q転z軣h軤h軥q軦k軧d軨l軩d軪a軫z軬f軮y軰b軱g軲g軴z軵r軶e軷b軹z軺y軻k軼y軽q軾s軿p輀e輁g輂j較j輄g輅l輆k輈z載z輋s輌l輍y輎s輏y輐w輓w輔f輕q輖z輗n輘l輙z輚z輛l輝h輞w輟c輡k輢y輣p輤q輥g輦n輨g輩b輫p輬l輭r輮r輰y輱x輲c輴c輵g輶y輷h輸s輹f輺z輻f輽f輾z輿y轀w轁t轂g轃z轄x轅y轆l轇j轈c轉z轊w轍z轎j轏z轐b轑l轔l轖s轗k轘h俁y係x轛d轝y轞j轟h轠l轡p轢l倀c轤l轥l轪d轫r轭e轱g轲k轳l轵z轶y轷h轸z轹l轺y轼s轾z辁q辂l辄z辇n辋w辌l辍c辏c辒w辔p辘l傑j辚l辝c辠z辡b辢l辥x辦b辪x辬b辮b辯b農n辳n辵c辶c辷y辸r辻s込y辿c迃y迆y迉q迊b迋w迌t迍z迏d儈k迕w迖d迗e迚d迤y迥j迨d迩e迬z迮z迯t迱y迲k迳j迴h迵d迺n迻y凜l迾l逄p逅h逇d逈j逋b逍x逎q逑q逓d逕j逖t這z逜w逡q連l逥h逦l逧g逨l逪c逬b逭h逯l週z進j逳y逴c逵k逶w逷t逹d逺y勸q遀s遄c遅c遈s遊y運y遌e過g遐x遑h遒q遖n遘g遙y遛l遜x遝t遞d遟c遠y遡s遢t遤h遦g遨a遪c遫c遯d遲c咴h遴l遶r遷q選x遹y遺y遻e遼l遽j遾s邁m邂x邃s還h邅z邆t邇e邈m邉b邊b邋l邌l邏l邒t邔q邕y邖s邘y邙m邛q邜x邝k邟k邠b邡f邥s邧y邬w邭j邰t邲b邳p邴b邶b邷w邸d邺y邼k邾z邿s喹k郀k郂g郃h郄q郅z郆j郇x郈h郉x郍n嗩s郏j郐k郒l郓y郔y郕c郖d郗x郘l郙f嘆t郚w郛f郜g郟j郠g嘗c郢y郤x郥b郦l郪q郫p郮z郯t郱p郳n郵y郶b郷x郹j郻q郾y郿m鄀r鄁b鄃s鄄j鄆y鄇h鄈k鄉x嚕l鄊x鄌t鄎x鄏r鄐c鄑z鄓y嚶y鄔w鄕x鄗h鄚m鄛c鄜f鄝l鄞y鄟z鄠h鄡q鄢y鄣z鄥q鄦x鄨b鄫z鄬w鄭z鄮m鄯s鄰l鄱p鄲d鄴y鄵c鄶k鄷f鄸m團t鄺k鄻l鄼z鄽c鄾y酀y酁c酂z酃l酄h酆f酇z酈l酊d酎z酏y酐g酑y酓y酔z酕m酖d酘d酙z酛k酜f酟t酠q酡t酢c酤g酦f垸y酧c酩m酫c酭y酯z酰x酲c酴t酹l酺p酻z堝g酾s醀w醁l醂l醃y醄t醅p醊z醌k醍t醎x醏d醐h醑x醕c醖y醗p醘k醙s醜c醝c醞y醟y醠a醡z醢h醣t醤j醥p醧y醨l醩z醪l醫y醬j醭b醮j醯x醰t醱p醲n醳y醴l醵j醶y醷y醸n醹r醺x醻c醼y醽l醾m醿m墼j釁x釃s釄m釅y壎x釆b壘l釐l釓g釖d奩l釘d釚q釛h針z釞z釟b釡f釣d釦k釧c釨z釩f釬h釭g釮q釰r釱d釲s釳x釴y釵c釶s釷t釸x釹n釺q釻q釼r釽p釾y鈀b鈁f鈂c鈅y鈆q嬋c鈉n鈊x鈋e鈌j鈍d嬪p孌l鈐q鈒s鈓r鈔c鈕n鈗y鈘y鈛g鈜h鈞j導d鈡z鈢x鈣g鈤r鈥h鈦t鈧k屝f鈫q鈬d鈭z鈮n鈯t鈰s鈲g鈳k鈴l屨j鈶s鈷g鈸b鈹p鈺y鈻s鈼z鈽b鉁z鉂s鉃s鉄t鉆z鉈t鉉x鉊z鉋b鉌h鉍b鉎s鉏c鉐s鉑b鉓c鉕p鉖t鉘f鉙z鉚m鉛q鉜f鉝l鉟p鉠y鉣j鉤g鉦z崳y鉨x鉩x鉪d鉫j鉭t鉮s嵐l鉯y鉰s鉱k鉶x鉷h鉸j鉹c鉺e鉻g鉼b嶝d鉿h嶧y銀y銂z巒l銄x銆m銇l銈j銉y銊x銋r銌z師s銎q銏s銒x銓q銔p銖z銙k銚d銛x銜x銝x銞j銟c銢p銥y銦y銧g銩d銪y銭q銯k銲h銳r銴s廟m銵k廠c銶q銷x銸z銺z銻t鋀t鋁l鋂m鋄w鋅x鋆y鋇b鋈w鋉s鋋c鋌t鋎h鋑j鋕z鋖s鋗x鋘h鋙w鋚t鋛k忄x鋞x鋟q鋠s鋡h鋢l鋣y鋤c鋥z鋦j鋧x鋨e鋩m鋪p鋬p鋭r鋮c鋯g鋰l鋳z鋴z鋵t惚h鋷z鋸j鋹c鋺y愷k鋼g鋽d鋿s錀l慪o錁k錂l錃p慳q憒k錅l憮w錇p錉m錊z錋p錌a錍p錎x錏y懸x錑l錒a錓k錕k錗n錘c錙z錚z錜n錞c錟t錠d錡q錢q錣z錤j錥y錦j錧g錨m錩c錪t捲j錬l錭d錮g錯c錱z録l錳m錴l錵h錷g錸l錹k錺k錻b揮h錼n錽w錾z錿h鍀d鍁x鍄l鍆m鍇k鍈y鍉c鍊l鍋g鍌x鍍d鍏w鍐z鍑f鍒r鍓j鍔e鍕j鍖c鍗t撐c鍘z鍙h鍚y撖h鍛d撘d撢d撳q擋d鍞k鍟s鍠h鍡w鍢f鍣z鍤c鍥q鍦s鍧h鍨k鍩n鍪m鍫q鍬q鍭h鍯c鍱y鍲m鍳j鍵j鍶s鍷k鍸h鍹x攪j鍺z鍻j鍼z鍽b鍾z鍿z鎀x鎁y鎂m鎃p鎄a鎅j鎆q鎇m鎈c鎉d鎊b攵p鎋x鎌l鎍s數s鎏l鎐y鎑y鎒n鎓w鎔r鎕t鎖s鎘g鎙s鎛b鎜p鎝d鎞b鎟s鎠g鎡z鎤h暢c鎦l鎧k鎨s鎩s鎪s鎫w鎬g鎭z鎮z鎯l鎰y鎱y鎲t鎳n鎴x鎵j鎶g鎷m鎸j鎹k鎺h鎻s鎼x鎽f鎾w鎿n鏀l鏁s鏂o鏃z鏄t鏅x鏆g鏇x鏈l鏉s鏊a鏋m鏌m鏍l鏎b鏏w鏐l鏑d鏒s鏔y鏕l鏖a鏗k鏘q鏙c鏚q鏛s鏝m鏞y鏟c鏠f鏡j鏢b鏣s鏤l鏥x枧j枴g柙x鏧l鏨z鏩j鏪c鏫l鏬x鏭x鏮k鏯s鏰b鏱z鏲q鏳z鏴l鏵h鏶j鏸h鏹q鏺p鏻l鏼s鏽x鏾s鏿c鐀g鐁s鐂l鐃n鐄h鐅p鐆s鐇f鐈q鐉q鐊x鐋t鐌x鐎j鐏z鐐l鐑q鐒l鐓d鐔x鐕z鐖j鐗j鐘z鐙d鐚y鐛y鐜d鐝j鐞n鐟z鐠p鐡t鐣c鐤d鐥s鐦k鐧j鐨f鐩s鐪l鐫j鐬h鐭y鐮l鐯z鐰q鐱j鐲z鐴b鐵t榦g鐷y鐸d鐹g鐻j鐽d鐾b鐿y鑀a構g鑁z鑂x槔g鑄z鑅h鑆z鑇j鑈n鑉h鑊h鑋q鑌b樣y鑎g鑏n鑐x鑑j鑒j鑓y鑔c鑕z鑖m鑗l鑘l檑l鑜s鑝p檣q鑞l鑟d鑠s鑡c鑢l鑣b鑤b鑥l鑦x鑧k鑨l鑩e櫃g鑪l鑫x鑬j櫞y鑮b鑯j鑰y鑱c鑲x鑳j鑴x鑵g鑷n鑸l鑹c鑺q鑻p鑼l鑽z鑾l鑿z钀n钁j欽q钃z钄l钅j钆g钇y钊z钋p钌l钍t钏c钐s钑s钔m钕n钖y钗c钚b钛t钜j钣b钤q钪k钫f钬h钭t钯b钰y钲z钴g钶k钷p钸b钹b钼m钽t铄s铈s铉x铊s铋b铌n铍p铎d铏x铐k铑l铒e铓m铔y铕y铖c铗j铘y铙n铚z铛c铞d铟y铠k铢z汙w铤d铥d铦x铧h铨q铩s铪h铫d铮z铯s铳c铴t铵a铷r铹l铻w铼l铽t铿k锂l锃z锆g锇e锉c锊l锍l锎k锏j況k锒l锓q锔j锕a锖q锘n锛b锜q锝d锞k锟k锠c锢g锧z锩j锪h锫p锬t锱z锲q锴k锵q锶s锷e锸c锺z锼s锽h锾h锿a镂l镃z镄f镅m镆m镈b镉g镋t镌j镎n镏l镒y镓j镔b镕r镖b镗t镘m镙l镚b镛y镝d镞z镟x镠l镡t镢j镤p淺q镥l镦d镧l镨p镩c镫d镬h镯z镱y镲c镳b镴l镵c長c镸c镹j溈w镻d镼j镽l門m閂s閃s閄h滌d閆y閇b閈h閉b閊c開k閌k閍b閎h閏r閐s閑x閒x漁y閔m閕x閖l閗d閘z閙n閚z閛p閜x閝l閞b閠r閡h関g閣g閤g閦c閧h閨g閩m閪s閫k閬l閭l閮t閰j閱y閲y潿w閳c閴q閶c閷s閸k閹y閺w閻y閼e閽h閾y閿w闀h闁b濁z闄y闅w闆b闈w闉y闊k闋q闌l闍d闎q闏p闐t濾l闓k瀾l闕q闖c闗g闘d闙q闚k闛t關g闝p闞k闟x闠h闡c闤h闥t闦w闩s闫y闬h闱w闳h闵m闶k闼t闾l闿k阃k阄j阆l阇d阈y阊c阋x阌w阍h阏e阒q阓h阕q阖h阗t阘t阙j阚k阛h阝f阞l阠x烴t阡q阢w阣y阤t阥y阦y阧d阨a阩s阪b阫p阬k阭y阯z阰p阱j阷c阸e阹q阺d阼z阽d阾l陁t陂b陃b陉x陊d煥h陎s陏d陑e陒g陓y陔g陖j陗q陘x陙c陚w陜x陝s陞s陟z陠p陣z陦d陧n陫f燈d燜m陭q陮d爍s陰y陱j陲c陳c陴p陸l陹s険x陻y陼z陽y陾r陿x隀c隁y隂y隃y隄d隇w隈w隉n隊d隌a牾w隍h階j隑g隒y隓h犋j隕y隖w隗k隚t際j犖l隝d隞a犢d隟x隠y隡s隢r隣l隤t隥d隦p隨s隩a險x隬n隭e隮j隯d隰x隱y隲z隴l隵x隷l隸l隹z隺h隻z隼s隽j隿y雂q雃j雈h雉z雊g雋j雎j雐h雑z雒l雓y雔c雖s雗h雘h雙s雚g雛c雜z雝y雞j雟g雡l離l難n雤y雥z雦c雧j雩y雫n雬f獎j雭s雮m雯w雰f雱p雲y雳l雴c雵y雸a獮x電d雼d雽h雿d霁j霂m霃c霅z霆t霈p霊l霋q霌z霎s霏f霐h霑z霒y霔s霕t霗l霘d霙y霚w霛l霝l霟h霠y霡m霢m霤l霥m霦b霧w霨w霩k霪y霫x霬y霭a霮d霯t霰s霱y霳l霴d霵j霶p霷y霺w霼x瑋w霽j霾m霿m靀m靁l靂l靃h靄a靅f靆d靇l靈l靉a靊f靋l靌b靍h靎h靏h靐b璁c靑q靓j靔t靕z靗c靘q靚j靜j靝t靟f靣m靤p靦m靧h靨y靪d靫c靬j靭r靮d靯d靰w靱r靲q靵n靷y環h靸s靹n靺m靻z靼d靽b靾x靿y鞀t鞁b瓔y鞂j鞃h鞄p鞅y鞆b鞇y鞈g鞉t鞊j鞌a鞎h鞏g鞐k鞑d鞒q鞓t甌o鞔m鞕b鞖s鞗t鞙x鞚k甕w鞛b鞜t鞝s鞞b鞟k鞡l鞢x鞣r鞤b鞥e鞦q鞧q鞨h鞩q鞪m鞫j鞬j鞮d鞯j鞰w鞱t鞲g鞳t鞴b鞵x畢b鞶p鞷g鞸b鞹k鞺t鞻l鞼g當d鞽q鞾x鞿j韀j疇c韂c韃d韅x韆q韇d韈w韉j韊l痠s韋w韌r韍f韎m韏q韐g韑w韒q韓h韔c韕k痺b韖r韗y韘s韙w韚g韛b韜t韝g瘋f韞y韟g韠b韡w韢s韣d韤w韥d韨f韪w韫y韬t韮j韯x韰x韱x韲j韴z韷l韸p韹h韺y韻y韼p韽a韾y響x頀h頁y頂d頃q項x癉d頇h須x頉y癘l頊x頋e頌s頍k頎q頏h癤j預y頑w頒b頓d頔d頕d頖p頗p領l頙c頚j頛l頜h頝q頞e頟e頠w頡j頢k頣s頤y頥y頦k頧d頨y頩p頪l頫f頬j頭t頮h頯k頰j頱l頲t頳c頴y頵j頶h頷h頸j頹t頺t頻b頼l頽t頾z頿z顀c顁d顂l顃t顄h顅q顆k顇c顈j顉q顊y顋s題t額e顎e顏y眙y顐w顒y顓z顔y顕x顖x顗y願y顙s顚d顛d顜j眾z顝k類l顟l顠p顡w顢m顣c顤y顥h顦q顧g顨x顩y顪h顫c顬r顭m顮b顯x顰p瞇m顱l顲l顳n顴q顸h顼x颀q颉j颋t颌g颎j颏k颒h颔h颕y颙y颚e颛z颞n颟m颡s颣l颥r颦p風f颩d颪g颫f颬x颭z颮b颯s颰b颱t颲l颳g颴x颵x颶j颷b颸s颹w颺y颻y颼s颽k颾s颿f飀l飁x飂l飃p飄p飅l飆b飇b飈b飉l飊b飋s飌f飍x飏y飐z飑b飒s飓j飔s飕s飖y砦z飗l飙b飚b飛f飜f飝f飡c飢j飣d飤s飥t飦z飧s飨x飩t飪r飫y飬y飭c飮y飯f飰f飱s碭d飲y飳z飴y飵z飶b飷j確q飸t飹b飺c飻t飼s飽b飾s飿d餀h餁r餂t餃j餄h餅b餆y餇t餈c餉x養y餋j餌e磽q餍y餎l餏x餑b餒n餓e餔b餕j餖d餗s餘y餙s餚y餛h餜g餝s餞j餟c餠b餡x餢b餣y餤d餥f餦z餧w館g餩e餪n餫y餬h餭h餮t餯h餰j餱h餲a餳x礬f餵w餶g餷c餸s餹t餺b餻g餼x餽k餾l餿s饀t饂w饃m饄t饅m饆b饇y饈x饉j饊s饋k饌z饍s饎x饏d饐y饑j饒r饔y饕t饖w饗x饘z饚h饛m饜y饝m饞c饟x饠l饡z饢n饣s饤d饦t饧x饨t禪s饩x饪r饫y饬c饳d饴y饷x饸h饹g饻x饽b饾d馀y馂j馃g馄h馇c馉g馊s馌y馎b馐x馑j馓s馔z馕n馘g馛b馜n馝b馞b馟t馠h馡f馢j馣a馤a馥f馦x馧y馨x穎y穡s馪p馫x馬m馭y馮f馯h馰d馱t馲t馳c馴x馵z馶z馷p馸x馹r馺s馻y馼w馽z馾d馿l駀y竇d駂b駃j筅x駅y駆q駇w駈q駉j駊p駋z駌y筧j駍p駎z駏j駐z駑n駒j駓p駔z駕j駖l駗z駘t駙f駚y駛s駜b駝t駞t駟s箢y駠l駡m駢p駣t駤z駥r駦t駧d駨x駩q駪s駫j駬e駭h駮b簞d駰y駱l駲z駳d駴h駵l駶j駷s駸q駹m駺l駻h駼t駽x駾t駿j騀e騁c騂x騃a騄l騅z騆z騇s騈p騉k騊t騋l騌z騍k騎q騏q騐y騑f騒s験y騔g騕y騖w騗p騙p騚q騛f紆y騜h騝q騞h騟y騠t騡q騢x騣z純c騥r騦s騧g騨t絕j騩g騪s騬c騭z騮l騯p騰t騱x騲c騳d騴y綽c緄g騶z騷s騸s騹q騺z騻s騼l騽x騾l騿z縋z驁a驂c驃p驄c驅q縲l驆b驇z驈y驉x驊h驋b驌s驍x驎l驏z驐d繃b驑l驒t驓c驔d驕j驖t驗y驘l驙z驚j驛y驜y繽b驝t驞p驟z驠y驡l驢l驣t驤x驥j驦s驧j驨x驩h驪l驫b驲r驵z驷s驸f驺z驽n驿y骀d骁x骃y骅h骈p骉b骊l骍x骎q骐q骒k骓z骔z骕s骖c骘z骙k罷b骛w骜a骝l骞q骟s骠b骢c骣c骥j骦s骧x骩w骪w骫w骬y骭g骮y骯a骰t骱j骲b骳b骴c骵t羨x骶d骷k骹q骺h骻k骼g骽t骾g骿p羻q髀b髁k髂q髃y髄s髅l髆b髇x髈b髉b髋k髌b髎l髏l聖s髐x髑d髒z體t髕b髖k髗l髙g髚q髛k髜q髝l髞s髟b髠k髡k髢d肀y髣f髤x髥r髦m髧d髩b髪f髫t髬p髭z髮f髯r髰t胙z髱b髲b髳m髴f髷q髸g髹x髺k髻j髽z髾s髿s鬀t鬁l膣z鬄t鬅p鬆s鬇z鬈q鬉z鬊s鬋j鬌d鬍h鬎l鬏j鬐q鬑l鬒z鬓b鬔p鬕m鬖s鬗m鬘m鬙s鬚x鬛l鬜q鬝q鬞n鬟h鬠k臘l鬡n鬢b鬣l鬤r鬥d臥w鬧n鬨h鬩x鬪d鬬d鬭d鬮j鬯c鬰y艙c鬳y艤y鬴f鬵z鬶g鬷z鬸l鬹g鬺s鬻y鬽m鬾j鬿q魀g魃b魅m魆x魇y芐h魉l魊y魋t魍w魎l魐g魑c魒p魕j魖x魗c魘y魙z魚y荮z莖j魜r魝j魞a魟h魠t魡d魢j魣x魤e魥j魦s魧h菪d菴a魩m萇c魪j魫s魬b魭y魮p魯l魰w葒h魲l魳z魴f魶n魷y魸n魹m魺h魻x魼q魽h魾p魿l鮀t蒹j蓀s鮂q鮃p鮄f鮅b鮆c鮇w鮈j鮉d蓮l鮊b鮋y鮌g鮍p鮎n鮏x鮐t鮑b蔆l鮒f鮓z鮔j鮕g鮖s蔞l蕆c蕘r鮘c鮙t鮚j鮛s鮜h鮝x鮞e鮟a鮠w鮡z鮢z鮣y鮤l鮥l鮦t鮧y鮨y鮩b鮪w鮫j鮬k鮭g鮮x鮯g鮰h鮱l鮲m鮳k鮴x鮵t鮶j鮷t鮸m鮹s鮺z鮻s鮼q鮽y鮾n鯀g鯁g鯂s鯃w鯄q鯅s鯆p鯇h鯈t蘞l鯊s鯋s鯌k鯍m鯎c鯏l虼g鯐s鯑k鯒y鯓s鯔z鯕q鯖q鯗x鯘n鯚j鯛d鯜q鯝g鯞z鯟d鯠l鯡f鯢n鯣y鯤k蜴y鯦j鯧c鯨j鯩l鯪l螄s螈y鯬l鯭m鯮z鯯z鯰n鯱x鯲d鯳s鯴s鯵s鯶h鯷t鯹x鯺z鯻l鯼z鯽j鯾b鯿b鰀h蟛p鰁q鰂z鰃w蟣j鰄w鰅y鰆c鰇r鰈d鰉h鰊l鰋y鰌q鰍q鰎j鰏b蠶c鰑y蠻m衊m鰓s鰔j鰕x鰖t鰗h鰘s鰙r鰚h鰛w鰜j鰝h鰞w鰟p鰠s鰡l鰢m鰣s鰤s鰥g鰦z鰧t鰨t鰩y鰪e鰫y鰬q鰭q鰮w鰯r鰰h鰱l鰲a袼g裉k鰴h鰵m鰶j鰷t鰸q鰹j鰺s鰻m鰼x鰽q鰿j鱀j鱁z鱂j鱃x鱄z鱅y鱆z鱇k鱈x襖a襲x鱊y鱋q鱌x鱍b鱎j鱏x鱐s鱑h鱒z覈h觀g觔j鱔s鱕f鱖g鱗l鱘x鱙y鱚x鱛a鱜k鱞g鱟h鱠k鱡z鱢s鱣z鱤g鱥g計j鱦y鱧l鱨c鱩h鱪s鱫a訟s訥n訶h鱭j鱮x鱯h鱰s鱱l鱲l鱳l鱴m鱵z鱶x鱷e鱸l鱹g鱺l鱻x鱽d鱾j試s鱿y鲀t鲂f詬g鲃b鲄h鲅b詰j鲆p鲇n詳x鲈l鲉y鲊z鲋f詿g鲌b鲎h誄l鲏p鲐t鲑g鲒j鲓k鲔w鲕e鲖t鲗z鲘h鲙k鲚j鲛j鲝z鲞x鲟x誦s鲠g鲡l說s鲢l鲣j鲥s鲦t誹f鲧g鲨s鲩h鲪j鲫j鲬y鲭q鲮l鲯q鲰z鲱f鲲k鲳c鲴g鲵n鲶n鲷d鲹s鲺s諦d鲻z鲼f諭y鲽d鲾b鲿c鳀t諼x謄t鳁w鳂w鳄e謖s鳅q鳆f謾m譏j鳇h鳈q鳉j鳊b變b鳌a鳍q鳎t鳏g鳐y鳑p讞y鳓l鳔b鳕x鳗m鳘m鳙y鳚w鳜g鳝s鳟z鳠h鳡g鳢l鳣z鳤g鳥n鳦y鳧f豊l鳨l鳪b鳫y鳬f鳭d鳮j鳯f鳰n鳱g鳲s鳳f鳴m鳵b鳶y貞z買m費f貽y鳸h賀h鳹q鳺f鳻b鳼w鳽j鳾s鳿y鴀f鴁y鴂j鴃j鴄p賍z鴅h鴆z鴇b鴈y鴉y鴊z鴋f鴌f賚l賦f賫l鴎o賱y鴏d賲b鴐j鴑r鴒l鴓m鴔f鴕t鴖m鴗l鴘b鴙z鴚g鴛y鴜c鴝q鴞x鴟c鴠d鴡j鴣g鴤z鴥y鴦y鴧y鴨y鴩d鴪y贖s鴬y鴭d赾q鴰g鴱a鴲z鴳y鴴h鴵x鴶j鴷l鴸z鴹y鴺y鴻h鴼l鴽r趒t鴾m鴿g趕g鵁j鵂x鵃z鵄c鵅l鵆q鵇t鵈e趛y鵊j鵋j趢l鵌t鵍h鵎t趦z趬q趶k鵐w鵒y鵓b鵔j鵕j跊m鵖b鵗x鵘j鵙j鵚t鵛j鵜t鵝e鵞e鵟k鵠h鵢s鵣l鵤z跮d鵦l鵧p鵨s鵩f鵪a鵫z鵬p踇m鵭q鵮q鵯b踋j鵰d鵱l鵲q踐j鵳j鵴j鵵t鵶y鵷y踖j鵸q鵹l鵺y鵻z鵼k鵽d踜l鵾k鵿s鶀q踠w鶁j鶂y踤z踨z踼t鶄j鶅z鶆l鶇d蹅c蹆t蹌q蹎d蹏t鶉c鶊g鶋j鶌q鶍y鶎k鶏j鶐s鶑y鶒c鶓m躌w躤j鶖q躪l鶗t鶘h鶙t鶚e躳g躴l躼l軂l軅y軈y軍j鶜m鶝f鶞c鶟t鶠y鶡h鶢y鶣p鶤k鶥m鶦h軛e鶧y軞m軭k軯p軳p鶩w鶪j軸z輇q鶬c鶭f鶮h鶯y鶰y鶱x鶲w輑y鶴h鶵c輜z鶶t鶷x鶸r輠g鶹l鶺j鶻g鶼j輧p輪l輯j輳c輼w鶾h鶿c鷀c鷁y鷂y轋h轌x轓f鷄j鷅l鷆t鷇k鷈t鷉t鷊y鷋t鷌m鷍x鷎g鷏t鷐c鷑j鷒t鷓z轙y鷔a轚j鷕y鷖y轜e鷗o鷘c鷙z鷚l鷛y轣l鷝b鷞s鷟z鷠y鷡w鷢j鷣y鷤t鷥s鷦j鷨h鷩b鷪y鷫s鷬h辀z鷮j辎z鷯l辤c鷱g辧b鷲j鷳x鷴x鷵t鷶m鷷z鷸y鷹y鷺l鷻t鷼x鷽x辭c鷿p鸀z鸁l鸂x鸃y鸄j鸅z鸆y鸇z辴z鸈y鸊p鸋n鸌h辺d鸍m鸎y鸏m鸐d鸑y迀g鸒y鸓l鸔b鸕l鸖h鸗l鸘s鸙y鸚y鸛g鸜q鸝l鸞l鸠j鸢y鸤s鸧c鸨b鸩z鸪g鸫d鸬l鸮x鸰l鸱c鸲q鸴x鸶s鸷z鸸e鸹g鸺x鸻h鸼z鸾l鹀w鹁b鹂l鹄g鹆y鹇x迒h鹈t迓y鹉w鹋m鹌a鹍k迠c鹎b迡c鹐q鹑c迣z迦j迧c鹓y鹔s迶y鹖h鹗e迼j鹘g迿x鹙q鹚c鹛m逌y逘y鹜w鹝y鹞y鹟w鹠l鹡j鹢y鹣j鹥y鹦y鹨l鹩l鹪j逤s鹫j逩b逫z逰y鹬y鹭l鹮h鹯z鹱h鹲m鹳g鹵l鹷l鹸j鹹x鹻j鹼j鹽y鹾c逽n逿d遃y遆t遉z麁c麂j麃b麄c麅p麆z麇j麈z麉j麊m麋b麌y麍l麎c麏j達d麐l違w麑n麒q麔j遚c麕j麖j麗l麘x麙x麚j麛m麜l麝s麞z麟l麠j麢l麣y麤c麥m麧h麨c麩f麪m麫m麬f麭p麮q麯q麰m麱f麲x麳l麴q麵m麶c麷f麸f麹q麺m適s麼m麽m遬s麾h麿m遰d黀z遱l黁n遳c黃h黅j黆g黇t黈t黉h黊h黋k黌h黏n黐c黒h黓y黕d黖x黗t黙m黚q黛d黜c黝y點d黟y黠x黡y黢q黣m黤y黥q黦y黧l黨d黩d黪c黫y邍y黬y邎y黭y黮d邐l黯a黰z黱d黲c黳y黴m黵d黶y黷d黸l黹z黻f黼f黽m邗h黾m黿y鼀c鼁q鼂c鼃w鼄z鼅z鼆m鼇a邞f鼊b鼋y邨c鼌c邩h鼍t邫b邽g鼑d鼒z鼔g鼕d鼘y鼙p鼚c鼛g鼜c鼝y鼞t鼟t鼡n鼢f鼣f鼤w鼥b鼦d鼧t郋x鼨z郌g鼩q鼪s鼫s鼬y鼭s鼮t鼯w鼰j鼱j鼲h鼳j鼴y鼵t鼶s鼷x鼸x郞l鼹y鼺l鼼y鼽q鼾h鼿w齀w齁h齂x齃e齄z齅x郣b郩x齆w齇z齈n齉n齊q郰z郲l齌j齍z齎j齏j齑j齒c齓c齔c齕h齖y齗y齘x郼y齚z齛x齜z齝c齞y齟j齠t齡l齢l齣c齤q齥x鄅y鄋s齧n齨j鄍m齪c齫y齬y齭c鄒z齯n鄖y鄘y鄤m齱z齲q齳y齴y鄧d鄩x鄪b齶e齷w齸y齹c齺z齻d齼c齾y龀c龁h龂y鄳m鄹z龃j龅b龆t龇z龈y龉y龊c龌w龍l龏g鄿q酅x龑y龒l龓l龔g龕k龗l龘d龛k龜g龝q酨z龞b龢h龣j龤x龥y鳩j鳷z鴍w鴢y鴫t鴮w鴯e鵀r鵉l鵏b鵑j鵡w鵥k鶃y鶛j鶨c鶫d鶳s鶽s鷃y鷜l鷧y鷭f鷰y鷾y鸉y鹒g鹕h鹶j鹺c麀y麡q鼈b鼉t鼏m齋z齙b齦y齮y齰z齵y齽j龎p龖d龡c癷b唉a苯b瞓f硸n秎f斗d稥x坊f竕f告g龟g哼h解j擂l罖r芈m羒f羘z羛y羜z羣q羦h羪y羫q羭y羮g羳f羵f羶s羷l翂f裂l聁u膹f艈u漂p骑q砌q雀q蒊h蒶f蕒m蕡f是s伺c毝c苔t虲u蚠f蝊u蟇m衁h衇m衈e衖x衚h衜d衞w衟d衠z衯f衮g袰b袴k呀y訜f子z豶f亂l傯z僨f償c兇x喲Y嗯E堯Y塏K墳F墾K鶕A鶔r鶈q鱬r鱝f魵f髍m馩f馚f饙f餴f颃h霻f霣y雺w隫f闧u闇a閥f閟b間j镪q钿d鐼f鐢f鏦c鏜t鍂p奮f婁l媵y屢l嶠j幀z幗g憤f錖d錆q銽x橥z歸g殛j炷z甯n瘧n瘵z碡z糞f紛f羥q腳j膩n臺t莜y蓿x褸l誒e讜d讠y贁b趀c趓d趙z趸d跀y跥d輊z輒z轒f轕g遧z邚r邤x郬q郺y酳y酼h酽y醆z醈t醓t醔q醦c釀n釂j釈s釋s釒j釔y釕l釗z釙p釠l釢n釤s釥q鉀j釪h釫h釯m釿j鈃x鈄d鈇f鈈b鈎g鈏y鈑b鈖f鈙q鈚p鈝y鈟d鈠y鈨y鈩h鈱m鈵b鈾y鈿d鉅j鉇s鉒z鉔z鉗q鉞y鉡b鉢b鉥s鉧m鉬m鉲k鉳b鉵t鉽s鉾m銁j銃c銅t銍z銐c銑x銕t銗h銘m銠l銡j銣r銤m銨a銫s銬k銰a銱d銹x銼c銾h銿z鋃l鋊y鋍b鋏j鋐h鋒f鋓c鋔w鋜z鋝l鋫l鋱t鋲b鋶l鋻j鋾t錄l錈j錐z錔t錛b錝c錫x錰s錶b鍃h鍅f鍎t鍜x鍝y鍮t鍰h鍴d鎎k鎗q鎚c鎢w鎣y鎥t鏓c鏷p鐍j鐳l鐶h鐺d鑃d鑍y鑙j鑚z鑛k鑭l鑶c钂t钘x铇b锳y镮h镺a镾m閁m閅m閯s閵l闂h闃g闑n闒t闔h闢p闣d陥x陬z陯l韁j韄h頄q順s顑k飠s饁y饓c駁b駄t駯z騘c騤k騫q騵y鰐e鰒f鰳l鰾p鱉b鱓s鳋s鳒j鳛x鹧z鹴s黂f黺f鼖f齩y驀m髊c髨k髵e髶e髼p鬂b鬦d鬫k鬱y魈x魌q魓b魛d魨t魱h鮁b鮗d鮿z鯙c鯉l鯥l鯫z鯸h龐p".Substring(num + 1, 1); + } + // + // 摘要: + // 获取类名 + // + // 参数: + // dbColumnName: + public static string CsharpName(string dbColumnName) + { + if (dbColumnName.Contains("_")) + { + string[] value = (from it in dbColumnName.Split('_') + select FirstUpper(it)).ToArray(); + return string.Join("", value); + } + + return FirstUpper(dbColumnName); + } + // + // 摘要: + // 将值的首字母大写 + // + // 参数: + // value: + // 值 + public static string FirstUpper(string value) + { + string text = value.Substring(0, 1).ToUpper(); + return text + value.Substring(1, value.Length - 1); + } + } +} \ No newline at end of file diff --git a/Infrastructure/Filter.cs b/Infrastructure/Filter.cs new file mode 100644 index 0000000..ae70ce3 --- /dev/null +++ b/Infrastructure/Filter.cs @@ -0,0 +1,25 @@ +namespace Infrastructure +{ + + public class Filter + { + public string Key { get; set; } + public string Value { get; set; } + public string Contrast { get; set; } + + public string Text { get; set; } + } + + public class FilterGroup + { + /// + /// or /and + /// + public string Operation { get; set; } + public Filter[] Filters { get; set; } + public FilterGroup[] Children { get; set; } + } + + + +} \ No newline at end of file diff --git a/Infrastructure/GenerateId.cs b/Infrastructure/GenerateId.cs new file mode 100644 index 0000000..6277b60 --- /dev/null +++ b/Infrastructure/GenerateId.cs @@ -0,0 +1,126 @@ +// *********************************************************************** +// Assembly : FairUtility +// Author : Yubao Li +// Created : 10-13-2015 +// +// Last Modified By : Yubao Li +// Last Modified On : 10-13-2015 +// *********************************************************************** +// +// Copyright (c) . All rights reserved. +// +// 创建唯一ID +// *********************************************************************** + +using System; +using System.Security.Cryptography; + +namespace Infrastructure +{ + public class GenerateId + { + public static string GetGuidHash() + { + return Guid.NewGuid().ToString().GetHashCode().ToString("x"); + } + + /// + /// 生成一个长整型,可以转成19字节长的字符串 + /// + /// System.Int64. + public static long GenerateLong() + { + byte[] buffer = Guid.NewGuid().ToByteArray(); + return BitConverter.ToInt64(buffer, 0); + } + + /// + /// 生成16个字节长度的数据与英文组合串 + /// + public static string GenerateStr() + { + long i = 1; + + foreach (byte b in Guid.NewGuid().ToByteArray()) + { + i *= ((int)b + 1); + } + + return String.Format("{0:x}", i - DateTime.Now.Ticks); + } + + /// + /// 创建11位的英文与数字组合 + /// + /// System.String. + public static string ShortStr() + { + return Convert(GenerateLong()); + } + + /// + /// 唯一订单号生成 + /// + /// + public static string GenerateOrderNumber() + { + string strDateTimeNumber = DateTime.Now.ToString("yyyyMMddHHmmssffff"); + string strRandomResult = NextRandom(1000, 1).ToString("0000"); + + return strDateTimeNumber + strRandomResult; + } + + #region private + + /// + /// 参考:msdn上的RNGCryptoServiceProvider例子 + /// + /// + /// + /// + private static int NextRandom(int numSeeds, int length) + { + // Create a byte array to hold the random value. + byte[] randomNumber = new byte[length]; + // Create a new instance of the RNGCryptoServiceProvider. + RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); + // Fill the array with a random value. + rng.GetBytes(randomNumber); + // Convert the byte to an uint value to make the modulus operation easier. + uint randomResult = 0x0; + for (int i = 0; i < length; i++) + { + randomResult |= ((uint) randomNumber[i] << ((length - 1 - i)*8)); + } + + return (int) (randomResult%numSeeds) + 1; + } + + + + static string Seq = "s9LFkgy5RovixI1aOf8UhdY3r4DMplQZJXPqebE0WSjBn7wVzmN2Gc6THCAKut"; + + /// + /// 10进制转换为62进制 + /// + /// + /// + + private static string Convert(long id) + { + if (id < 62) + { + return Seq[(int) id].ToString(); + } + int y = (int) (id%62); + long x = (long) (id/62); + + return Convert(x) + Seq[y]; + } + + #endregion + + + + } +} \ No newline at end of file diff --git a/Infrastructure/Helpers/AESHelper.cs b/Infrastructure/Helpers/AESHelper.cs new file mode 100644 index 0000000..35dad75 --- /dev/null +++ b/Infrastructure/Helpers/AESHelper.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace Infrastructure.Helpers +{ + public class AESHelper + { + // + // 摘要: + // 32位处理key + // + // 参数: + // key: + // 原字节 + private static string GetAesKey(string key) + { + int length = key.Length; + if (length < 32) + { + for (int i = 0; i < 32 - length; i++) + { + key += "0"; + } + + return key; + } + + return key[..32]; + } + + // + // 摘要: + // 使用AES加密字符串 + // + // 参数: + // content: + // 加密内容 + // + // key: + // 秘钥 + // + // vi: + // 偏移量 + // + // 返回结果: + // Base64字符串结果 + public static string AesEncrypt(string content, string key, string vi = "1234567890000000") + { + byte[] bytes = Encoding.UTF8.GetBytes(GetAesKey(key)); + byte[] bytes2 = Encoding.UTF8.GetBytes(vi); + byte[] bytes3 = Encoding.UTF8.GetBytes(content); + SymmetricAlgorithm symmetricAlgorithm = Aes.Create(); + symmetricAlgorithm.IV = bytes2; + symmetricAlgorithm.Key = bytes; + symmetricAlgorithm.Mode = CipherMode.CBC; + symmetricAlgorithm.Padding = PaddingMode.PKCS7; + ICryptoTransform cryptoTransform = symmetricAlgorithm.CreateEncryptor(); + byte[] inArray = cryptoTransform.TransformFinalBlock(bytes3, 0, bytes3.Length); + return Convert.ToBase64String(inArray); + } + + // + // 摘要: + // 使用AES解密字符串 + // + // 参数: + // content: + // 内容 + // + // key: + // 秘钥 + // + // vi: + // 偏移量 + // + // 返回结果: + // UTF8解密结果 + public static string AesDecrypt(string content, string key, string vi = "1234567890000000") + { + byte[] bytes = Encoding.UTF8.GetBytes(GetAesKey(key)); + byte[] bytes2 = Encoding.UTF8.GetBytes(vi); + byte[] array = Convert.FromBase64String(content); + SymmetricAlgorithm symmetricAlgorithm = Aes.Create(); + symmetricAlgorithm.IV = bytes2; + symmetricAlgorithm.Key = bytes; + symmetricAlgorithm.Mode = CipherMode.CBC; + symmetricAlgorithm.Padding = PaddingMode.PKCS7; + ICryptoTransform cryptoTransform = symmetricAlgorithm.CreateDecryptor(); + byte[] bytes3 = cryptoTransform.TransformFinalBlock(array, 0, array.Length); + return Encoding.UTF8.GetString(bytes3); + } + } +} diff --git a/Infrastructure/Helpers/CommonHelper.cs b/Infrastructure/Helpers/CommonHelper.cs new file mode 100644 index 0000000..81752e6 --- /dev/null +++ b/Infrastructure/Helpers/CommonHelper.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + +namespace Infrastructure.Helpers +{ + /// + /// 常用公共类 + /// + public class CommonHelper + { + #region Stopwatch计时器 + /// + /// 计时器开始 + /// + /// + public static Stopwatch TimerStart() + { + Stopwatch watch = new Stopwatch(); + watch.Reset(); + watch.Start(); + return watch; + } + /// + /// 计时器结束 + /// + /// + /// + public static string TimerEnd(Stopwatch watch) + { + watch.Stop(); + double costtime = watch.ElapsedMilliseconds; + return costtime.ToString(); + } + #endregion + + #region 删除数组中的重复项 + /// + /// 删除数组中的重复项 + /// + /// + /// + public static string[] RemoveDup(string[] values) + { + List list = new List(); + for (int i = 0; i < values.Length; i++)//遍历数组成员 + { + if (!list.Contains(values[i])) + { + list.Add(values[i]); + }; + } + return list.ToArray(); + } + #endregion + + #region 自动生成日期编号 + /// + /// 自动生成编号 201008251145409865 + /// + /// + public static string CreateNo() + { + Random random = new Random(); + string strRandom = random.Next(1000, 10000).ToString(); //生成编号 + string code = DateTime.Now.ToString("yyyyMMddHHmmss") + strRandom;//形如 + return code; + } + #endregion + + #region 生成0-9随机数 + /// + /// 生成0-9随机数 + /// + /// 生成长度 + /// + public static string RndNum(int codeNum) + { + StringBuilder sb = new StringBuilder(codeNum); + Random rand = new Random(); + for (int i = 1; i < codeNum + 1; i++) + { + int t = rand.Next(9); + sb.AppendFormat("{0}", t); + } + return sb.ToString(); + + } + #endregion + + #region 删除最后一个字符之后的字符 + /// + /// 删除最后结尾的一个逗号 + /// + public static string DelLastComma(string str) + { + return str.Substring(0, str.LastIndexOf(",")); + } + /// + /// 删除最后结尾的指定字符后的字符 + /// + public static string DelLastChar(string str, string strchar) + { + return str.Substring(0, str.LastIndexOf(strchar)); + } + /// + /// 删除最后结尾的长度 + /// + /// + /// + /// + public static string DelLastLength(string str, int Length) + { + if (string.IsNullOrEmpty(str)) + return ""; + str = str.Substring(0, str.Length - Length); + return str; + } + #endregion + } +} diff --git a/Infrastructure/Helpers/ConfigHelper.cs b/Infrastructure/Helpers/ConfigHelper.cs new file mode 100644 index 0000000..5574f7a --- /dev/null +++ b/Infrastructure/Helpers/ConfigHelper.cs @@ -0,0 +1,23 @@ +using System; +using Enyim.Caching.Configuration; +using Microsoft.Extensions.Configuration; + +namespace Infrastructure.Helpers +{ + public class ConfigHelper + { + public static IConfigurationRoot GetConfigRoot() + { + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.SetBasePath(System.IO.Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddJsonFile( + $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development"}.json", + optional: true) + .AddEnvironmentVariables(); + + var configuration = configurationBuilder.Build(); + return configuration; + } + } +} \ No newline at end of file diff --git a/Infrastructure/Helpers/DateTimeHelper.cs b/Infrastructure/Helpers/DateTimeHelper.cs new file mode 100644 index 0000000..07a29ce --- /dev/null +++ b/Infrastructure/Helpers/DateTimeHelper.cs @@ -0,0 +1,42 @@ +using System; + +namespace Infrastructure.Helpers +{ + public class DateTimeHelper + { + public static string FriendlyDate(DateTime? date) + { + if (!date.HasValue) return string.Empty; + + string strDate = date.Value.ToString("yyyy-MM-dd"); + string vDate = string.Empty; + if(DateTime.Now.ToString("yyyy-MM-dd")==strDate) + { + vDate = "今天"; + } + else if (DateTime.Now.AddDays(1).ToString("yyyy-MM-dd") == strDate) + { + vDate = "明天"; + } + else if (DateTime.Now.AddDays(2).ToString("yyyy-MM-dd") == strDate) + { + vDate = "后天"; + } + else if (DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd") == strDate) + { + vDate = "昨天"; + } + else if (DateTime.Now.AddDays(2).ToString("yyyy-MM-dd") == strDate) + { + vDate = "前天"; + } + else + { + vDate = strDate; + } + + return vDate; + } + } +} + diff --git a/Infrastructure/Helpers/Excel/ExcelConfig.cs b/Infrastructure/Helpers/Excel/ExcelConfig.cs new file mode 100644 index 0000000..f7c38b7 --- /dev/null +++ b/Infrastructure/Helpers/Excel/ExcelConfig.cs @@ -0,0 +1,122 @@ +using Infrastructure.Helpers.Excel.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Infrastructure.Helpers.Excel +{ + public class ExcelConfig + { + /// + /// 文件名 + /// + public string FileName { get; set; } + /// + /// 标题 + /// + public string Title { get; set; } + /// + /// 前景色 + /// + public System.Drawing.Color ForeColor { get; set; } + /// + /// 背景色 + /// + public System.Drawing.Color Background { get; set; } + private short _titlepoint; + /// + /// 标题字号 + /// + public short TitlePoint + { + get + { + if (_titlepoint == 0) + { + return 20; + } + else + { + return _titlepoint; + } + } + set { _titlepoint = value; } + } + private short _headpoint; + /// + /// 列头字号 + /// + public short HeadPoint + { + get + { + if (_headpoint == 0) + { + return 10; + } + else + { + return _headpoint; + } + } + set { _headpoint = value; } + } + /// + /// 标题高度 + /// + public short TitleHeight { get; set; } + /// + /// 列标题高度 + /// + public short HeadHeight { get; set; } + private string _titlefont; + /// + /// 标题字体 + /// + public string TitleFont + { + get + { + if (_titlefont == null) + { + return "微软雅黑"; + } + else + { + return _titlefont; + } + } + set { _titlefont = value; } + } + private string _headfont; + /// + /// 列头字体 + /// + public string HeadFont + { + get + { + if (_headfont == null) + { + return "微软雅黑"; + } + else + { + return _headfont; + } + } + set { _headfont = value; } + } + /// + /// 是否按内容长度来适应表格宽度 + /// + public bool IsAllSizeColumn { get; set; } + /// + /// 列设置 + /// + public List ColumnEntity { get; set; } + + } +} diff --git a/Infrastructure/Helpers/Excel/ExcelHelper.cs b/Infrastructure/Helpers/Excel/ExcelHelper.cs new file mode 100644 index 0000000..21a2ff8 --- /dev/null +++ b/Infrastructure/Helpers/Excel/ExcelHelper.cs @@ -0,0 +1,505 @@ +using NPOI.HPSF; +using NPOI.HSSF.UserModel; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Infrastructure.Helpers.Excel +{ + public class ExcelHelper + { + #region DataTable导出到Excel的MemoryStream + /// + /// DataTable导出到Excel的MemoryStream Export() + /// + /// DataTable数据源 + /// 导出设置包含文件名、标题、列设置 + public static MemoryStream ExportMemoryStream(DataTable dtSource, ExcelConfig excelConfig) + { + Dictionary DataColumnMap = new Dictionary(); + + //DataTable dt = dtSource.Clone(); + //var columns = dt.Columns; + foreach (DataColumn column in dtSource.Columns) + { + bool v = excelConfig.ColumnEntity.Exists(t => t.Column == column.ColumnName); + if (v) + { + DataColumnMap.Add(column.ColumnName, column); + //dtSource.Columns.Remove(column.ColumnName); + } + /*else { + DataColumnMap.Add(column.ColumnName, column); + }*/ + } + + HSSFWorkbook workbook = new HSSFWorkbook(); + ISheet sheet = workbook.CreateSheet(); + #region 右击文件 属性信息 + { + DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation(); + dsi.Company = "山东慧创信息科技有限公司"; + workbook.DocumentSummaryInformation = dsi; + + SummaryInformation si = PropertySetFactory.CreateSummaryInformation(); + si.Title = "标题信息"; //填加xls文件标题信息 + si.Subject = "主题信息";//填加文件主题信息 + si.CreateDateTime = System.DateTime.Now; + workbook.SummaryInformation = si; + } + #endregion + + #region 设置标题样式 + ICellStyle headStyle = workbook.CreateCellStyle(); + int[] arrColWidth = new int[excelConfig.ColumnEntity.Count]; + string[] arrColName = new string[excelConfig.ColumnEntity.Count];//列名 + ICellStyle[] arryColumStyle = new ICellStyle[excelConfig.ColumnEntity.Count];//样式表 + headStyle.Alignment = HorizontalAlignment.Center; // ------------------ + if (excelConfig.Background != new System.Drawing.Color()) + { + if (excelConfig.Background != new System.Drawing.Color()) + { + headStyle.FillPattern = FillPattern.SolidForeground; + headStyle.FillForegroundColor = GetXLColour(workbook, excelConfig.Background); + } + } + IFont font = workbook.CreateFont(); + font.FontHeightInPoints = excelConfig.TitlePoint; + if (excelConfig.ForeColor != new System.Drawing.Color()) + { + font.Color = GetXLColour(workbook, excelConfig.ForeColor); + } + font.IsBold = true; + headStyle.SetFont(font); + #endregion + + #region 列头及样式 + ICellStyle cHeadStyle = workbook.CreateCellStyle(); + cHeadStyle.Alignment = HorizontalAlignment.Center; // ------------------ + IFont cfont = workbook.CreateFont(); + cfont.FontHeightInPoints = excelConfig.HeadPoint; + cHeadStyle.SetFont(cfont); + #endregion + + #region 设置内容单元格样式 + int colNum = 0; + foreach (var columnentity in excelConfig.ColumnEntity) + { + //DataColumn item = DataColumnMap[column.Column]; + + + + ICellStyle columnStyle = workbook.CreateCellStyle(); + columnStyle.Alignment = HorizontalAlignment.Center; + //Encoding.GetEncoding(936) + arrColWidth[colNum] = Encoding.UTF8.GetBytes(columnentity.Column).Length; + arrColName[colNum] = columnentity.Column.ToString(); + arrColName[colNum] = columnentity.ExcelColumn; + if (columnentity.Width != 0) + { + arrColWidth[colNum] = columnentity.Width; + } + if (columnentity.Background != new System.Drawing.Color()) + { + if (columnentity.Background != new System.Drawing.Color()) + { + columnStyle.FillPattern = FillPattern.SolidForeground; + columnStyle.FillForegroundColor = GetXLColour(workbook, columnentity.Background); + } + } + if (columnentity.Font != null || columnentity.Point != 0 || columnentity.ForeColor != new System.Drawing.Color()) + { + IFont columnFont = workbook.CreateFont(); + columnFont.FontHeightInPoints = 10; + if (columnentity.Font != null) + { + columnFont.FontName = columnentity.Font; + } + if (columnentity.Point != 0) + { + columnFont.FontHeightInPoints = columnentity.Point; + } + if (columnentity.ForeColor != new System.Drawing.Color()) + { + columnFont.Color = GetXLColour(workbook, columnentity.ForeColor); + } + columnStyle.SetFont(font); + } + columnStyle.Alignment = getAlignment(columnentity.Alignment); + arryColumStyle[colNum] = columnStyle; + + colNum++; + } + if (excelConfig.IsAllSizeColumn) + { + #region 根据列中最长列的长度取得列宽 + for (int i = 0; i < dtSource.Rows.Count; i++) + { + for (int j = 0; j < excelConfig.ColumnEntity.Count; j++) + { + if (arrColWidth[j] != 0) + { + //Encoding.GetEncoding(936) + int intTemp = Encoding.UTF8.GetBytes(dtSource.Rows[i][excelConfig.ColumnEntity[j].Column].ToString()).Length; + if (intTemp > arrColWidth[j]) + { + arrColWidth[j] = intTemp; + } + } + + } + } + #endregion + } + #endregion + + int rowIndex = 0; + + #region 表头及样式 + if (excelConfig.Title != null) + { + IRow headerRow = sheet.CreateRow(rowIndex); + rowIndex++; + if (excelConfig.TitleHeight != 0) + { + headerRow.Height = (short)(excelConfig.TitleHeight * 20); + } + headerRow.HeightInPoints = 25; + headerRow.CreateCell(0).SetCellValue(excelConfig.Title); + headerRow.GetCell(0).CellStyle = headStyle; + if (excelConfig.ColumnEntity.Count > 1) + { + sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, excelConfig.ColumnEntity.Count - 1)); // ------------------ + } + } + #endregion + + #region 列头及样式 + { + IRow headerRow = sheet.CreateRow(rowIndex); + rowIndex++; + colNum = 0; + #region 如果设置了列标题就按列标题定义列头,没定义直接按字段名输出 + foreach (var column in excelConfig.ColumnEntity) + { + headerRow.CreateCell(colNum).SetCellValue(arrColName[colNum]); + headerRow.GetCell(colNum).CellStyle = cHeadStyle; + //设置列宽 + //sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256); + + int colWidth = (arrColWidth[colNum] + 1) * 256; + if (colWidth < 255 * 256) + { + sheet.SetColumnWidth(colNum, colWidth < 3000 ? 3000 : colWidth); + } + else + { + sheet.SetColumnWidth(colNum, 6000); + } + colNum++; + } + #endregion + } + #endregion + + ICellStyle dateStyle = workbook.CreateCellStyle(); + IDataFormat format = workbook.CreateDataFormat(); + dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); + Dictionary dateStyleMap = new Dictionary(); + dateStyleMap.Add("yyyy-mm-dd", dateStyle); + + + + + foreach (DataRow row in dtSource.Rows) + { + #region 新建表,填充表头,填充列头,样式 + if (rowIndex == 65535) + { + sheet = workbook.CreateSheet(); + rowIndex = 0; + #region 表头及样式 + { + if (excelConfig.Title != null) + { + IRow headerRow = sheet.CreateRow(rowIndex); + rowIndex++; + if (excelConfig.TitleHeight != 0) + { + headerRow.Height = (short)(excelConfig.TitleHeight * 20); + } + headerRow.HeightInPoints = 25; + headerRow.CreateCell(0).SetCellValue(excelConfig.Title); + headerRow.GetCell(0).CellStyle = headStyle; + sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, excelConfig.ColumnEntity.Count - 1)); // ------------------ + } + + } + #endregion + + #region 列头及样式 + { + IRow headerRow = sheet.CreateRow(rowIndex); + rowIndex++; + #region 如果设置了列标题就按列标题定义列头,没定义直接按字段名输出 + colNum = 0; + foreach (var column in excelConfig.ColumnEntity) + { + headerRow.CreateCell(colNum).SetCellValue(arrColName[colNum]); + headerRow.GetCell(colNum).CellStyle = cHeadStyle; + //设置列宽 + sheet.SetColumnWidth(colNum, (arrColWidth[colNum] + 1) * 256); + colNum++; + } + #endregion + } + #endregion + } + #endregion + + + #region 填充内容 + IRow dataRow = sheet.CreateRow(rowIndex); + colNum = 0; + foreach (var columnentity in excelConfig.ColumnEntity) + { + ICell newCell = dataRow.CreateCell(colNum); + newCell.CellStyle = arryColumStyle[colNum]; + string drValue = row[columnentity.Column].ToString(); + + //ColumnModel columnentity = excelConfig.ColumnEntity.Find(t => t.Column == column.ColumnName); + if (!string.IsNullOrEmpty(columnentity.DateFormat)) + { + if (!dateStyleMap.ContainsKey(columnentity.DateFormat)) + { + ICellStyle dateStyle2 = workbook.CreateCellStyle(); + IDataFormat format2 = workbook.CreateDataFormat(); + dateStyle2.DataFormat = format.GetFormat(columnentity.DateFormat); + dateStyleMap.Add(columnentity.DateFormat, dateStyle2); + } + + + SetCell(newCell, dateStyleMap[columnentity.DateFormat], DataColumnMap[columnentity.Column].DataType, drValue); + } + else + { + + SetCell(newCell, dateStyle, DataColumnMap[columnentity.Column].DataType, drValue); + } + + + + colNum++; + } + #endregion + rowIndex++; + } + MemoryStream ms = new MemoryStream(); + workbook.Write(ms); + ms.Flush(); + ms.Position = 0; + return ms; + } + #endregion + #region 设置表格内容 + private static void SetCell(ICell newCell, ICellStyle dateStyle, Type dataType, string drValue) + { + switch (dataType.ToString()) + { + case "System.String"://字符串类型 + newCell.SetCellValue(drValue); + break; + case "System.DateTime"://日期类型 + System.DateTime dateV; + if (System.DateTime.TryParse(drValue, out dateV)) + { + newCell.SetCellValue(dateV); + } + else + { + newCell.SetCellValue(""); + } + newCell.CellStyle = dateStyle;//格式化显示 + break; + case "System.Boolean"://布尔型 + bool boolV = false; + bool.TryParse(drValue, out boolV); + newCell.SetCellValue(boolV); + break; + case "System.Int16"://整型 + case "System.Int32": + case "System.Int64": + case "System.Byte": + int intV = 0; + int.TryParse(drValue, out intV); + newCell.SetCellValue(intV); + break; + case "System.Decimal"://浮点型 + case "System.Double": + double doubV = 0; + double.TryParse(drValue, out doubV); + newCell.SetCellValue(doubV); + break; + case "System.DBNull"://空值处理 + newCell.SetCellValue(""); + break; + default: + newCell.SetCellValue(""); + break; + } + } + #endregion + + #region 从Excel导入 + /// + /// 读取excel ,默认第一行为标头 + /// + /// excel文档路径 + /// + public static DataTable ExcelImport(string strFileName) + { + DataTable dt = new DataTable(); + + ISheet sheet = null; + using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read)) + { + if (strFileName.IndexOf(".xlsx") == -1)//2003 + { + HSSFWorkbook hssfworkbook = new HSSFWorkbook(file); + sheet = hssfworkbook.GetSheetAt(0); + } + else//2007 + { + XSSFWorkbook xssfworkbook = new XSSFWorkbook(file); + sheet = xssfworkbook.GetSheetAt(0); + } + } + + System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); + + IRow headerRow = sheet.GetRow(0); + int cellCount = headerRow.LastCellNum; + + for (int j = 0; j < cellCount; j++) + { + ICell cell = headerRow.GetCell(j); + dt.Columns.Add(cell.ToString()); + } + + for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) + { + IRow row = sheet.GetRow(i); + DataRow dataRow = dt.NewRow(); + + for (int j = row.FirstCellNum; j < cellCount; j++) + { + if (row.GetCell(j) != null) + dataRow[j] = row.GetCell(j).ToString(); + } + + dt.Rows.Add(dataRow); + } + return dt; + } + /// + /// 读取excel ,默认第一行为标头 + /// + /// 文件数据流 + /// 文件类型 + /// + public static DataTable ExcelImport(Stream fileStream, string flieType) + { + DataTable dt = new DataTable(); + ISheet sheet = null; + if (flieType == ".xls") + { + HSSFWorkbook hssfworkbook = new HSSFWorkbook(fileStream); + sheet = hssfworkbook.GetSheetAt(0); + } + else + { + XSSFWorkbook xssfworkbook = new XSSFWorkbook(fileStream); + sheet = xssfworkbook.GetSheetAt(0); + } + System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); + IRow headerRow = sheet.GetRow(0); + int cellCount = headerRow.LastCellNum; + for (int j = 0; j < cellCount; j++) + { + ICell cell = headerRow.GetCell(j); + dt.Columns.Add(cell.ToString()); + } + for (int i = (sheet.FirstRowNum + 1); i <= sheet.LastRowNum; i++) + { + IRow row = sheet.GetRow(i); + DataRow dataRow = dt.NewRow(); + + for (int j = row.FirstCellNum; j < cellCount; j++) + { + if (row.GetCell(j) != null) + dataRow[j] = row.GetCell(j).ToString(); + } + + dt.Rows.Add(dataRow); + } + return dt; + } + #endregion + + #region RGB颜色转NPOI颜色 + private static short GetXLColour(HSSFWorkbook workbook, System.Drawing.Color SystemColour) + { + short s = 0; + HSSFPalette XlPalette = workbook.GetCustomPalette(); + NPOI.HSSF.Util.HSSFColor XlColour = XlPalette.FindColor(SystemColour.R, SystemColour.G, SystemColour.B); + if (XlColour == null) + { + if (NPOI.HSSF.Record.PaletteRecord.STANDARD_PALETTE_SIZE < 255) + { + XlColour = XlPalette.FindSimilarColor(SystemColour.R, SystemColour.G, SystemColour.B); + s = XlColour.Indexed; + } + + } + else + s = XlColour.Indexed; + return s; + } + #endregion + + #region 设置列的对齐方式 + /// + /// 设置对齐方式 + /// + /// + /// + private static HorizontalAlignment getAlignment(string style) + { + switch (style) + { + case "center": + return HorizontalAlignment.Center; + case "left": + return HorizontalAlignment.Left; + case "right": + return HorizontalAlignment.Right; + case "fill": + return HorizontalAlignment.Fill; + case "justify": + return HorizontalAlignment.Justify; + case "centerselection": + return HorizontalAlignment.CenterSelection; + case "distributed": + return HorizontalAlignment.Distributed; + } + return NPOI.SS.UserModel.HorizontalAlignment.General; + } + + #endregion + } +} diff --git a/Infrastructure/Helpers/Excel/Model/ColumnModel.cs b/Infrastructure/Helpers/Excel/Model/ColumnModel.cs new file mode 100644 index 0000000..c2d73e6 --- /dev/null +++ b/Infrastructure/Helpers/Excel/Model/ColumnModel.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Infrastructure.Helpers.Excel.Model +{ + public class ColumnModel + { + /// + /// 列名 + /// + public string Column { get; set; } + /// + /// Excel列名 + /// + public string ExcelColumn { get; set; } + /// + /// 宽度 + /// + public int Width { get; set; } + /// + /// 前景色 + /// + public System.Drawing.Color ForeColor { get; set; } + /// + /// 背景色 + /// + public System.Drawing.Color Background { get; set; } + /// + /// 字体 + /// + public string Font { get; set; } + /// + /// 字号 + /// + public short Point { get; set; } + /// + ///对齐方式 + ///left 左 + ///center 中间 + ///right 右 + ///fill 填充 + ///justify 两端对齐 + ///centerselection 跨行居中 + ///distributed + /// + public string Alignment { get; set; } + /// + /// 时间格式化 + /// + public string DateFormat { get; set; } + } +} diff --git a/Infrastructure/Helpers/FileHelper.cs b/Infrastructure/Helpers/FileHelper.cs new file mode 100644 index 0000000..238526e --- /dev/null +++ b/Infrastructure/Helpers/FileHelper.cs @@ -0,0 +1,407 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Infrastructure.Extensions; + +namespace Infrastructure.Helpers +{ + public class FileHelper + { + private static object _filePathObj = new object(); + + /// + /// 通过迭代器读取平面文件行内容(必须是带有\r\n换行的文件,百万行以上的内容读取效率存在问题,适用于100M左右文件,行100W内,超出的会有卡顿) + /// + /// 文件全路径 + /// 分页页数 + /// 分页大小 + /// 是否最后一行向前读取,默认从前向后读取 + /// + public static IEnumerable ReadPageLine(string fullPath, int page, int pageSize, bool seekEnd = false) + { + if (page <= 0) + { + page = 1; + } + fullPath = StringExtension.ReplacePath(fullPath); + var lines = File.ReadLines(fullPath, Encoding.UTF8); + if (seekEnd) + { + int lineCount = lines.Count(); + int linPageCount = (int)Math.Ceiling(lineCount / (pageSize * 1.00)); + //超过总页数,不处理 + if (page > linPageCount) + { + page = 0; + pageSize = 0; + } + else if (page == linPageCount)//最后一页,取最后一页剩下所有的行 + { + pageSize = lineCount - (page - 1) * pageSize; + if (page == 1) + { + page = 0; + } + else + { + page = lines.Count() - page * pageSize; + } + } + else + { + page = lines.Count() - page * pageSize; + } + } + else + { + page = (page - 1) * pageSize; + } + lines = lines.Skip(page).Take(pageSize); + + var enumerator = lines.GetEnumerator(); + int count = 1; + while (enumerator.MoveNext() || count <= pageSize) + { + yield return enumerator.Current; + count++; + } + enumerator.Dispose(); + } + public static bool FileExists(string path) + { + return File.Exists(StringExtension.ReplacePath(path)); + } + + public static string GetCurrentDownLoadPath() + { + return ("Download\\").MapPath(); + } + + public static bool DirectoryExists(string path) + { + return Directory.Exists(StringExtension.ReplacePath(path)); + } + + + public static string Read_File(string fullpath, string filename, string suffix) + { + return ReadFile((fullpath + "\\" + filename + suffix).MapPath()); + } + public static string ReadFile(string fullName) + { + // Encoding code = Encoding.GetEncoding(); //Encoding.GetEncoding("gb2312"); + string temp = fullName.MapPath().ReplacePath(); + string str = ""; + if (!File.Exists(temp)) + { + return str; + } + StreamReader sr = null; + try + { + sr = new StreamReader(temp); + str = sr.ReadToEnd(); // 读取文件 + } + catch { } + sr?.Close(); + sr?.Dispose(); + return str; + } + + + + /// + /// 取后缀名 + /// + /// 文件名 + /// .gif|.html格式 + public static string GetPostfixStr(string filename) + { + int start = filename.LastIndexOf("."); + int length = filename.Length; + string postfix = filename.Substring(start, length - start); + return postfix; + } + + + /// + /// + /// + /// 路径 + /// 文件名 + /// 写入的内容 + /// 是否将内容添加到未尾,默认不添加 + public static void WriteFile(string path, string fileName, string content, bool appendToLast = false) + { + path = StringExtension.ReplacePath(path); + fileName = StringExtension.ReplacePath(fileName); + if (!Directory.Exists(path))//如果不存在就创建file文件夹 + Directory.CreateDirectory(path); + + using (FileStream stream = File.Open(Path.Combine(path, fileName), FileMode.OpenOrCreate, FileAccess.Write)) + { + byte[] by = Encoding.Default.GetBytes(content); + if (appendToLast) + { + stream.Position = stream.Length; + } + else + { + stream.SetLength(0); + } + stream.Write(by, 0, by.Length); + } + } + + + + /// + /// 追加文件 + /// + /// 文件路径 + /// 内容 + public static void FileAdd(string Path, string strings) + { + StreamWriter sw = File.AppendText(StringExtension.ReplacePath(Path)); + sw.Write(strings); + sw.Flush(); + sw.Close(); + sw.Dispose(); + } + + + /// + /// 拷贝文件 + /// + /// 原始文件 + /// 新文件路径 + public static void FileCoppy(string OrignFile, string NewFile) + { + File.Copy(StringExtension.ReplacePath(OrignFile), StringExtension.ReplacePath(NewFile), true); + } + + + /// + /// 删除文件 + /// + /// 路径 + public static void FileDel(string Path) + { + File.Delete(StringExtension.ReplacePath(Path)); + } + + /// + /// 移动文件 + /// + /// 原始路径 + /// 新路径 + public static void FileMove(string OrignFile, string NewFile) + { + File.Move(StringExtension.ReplacePath(OrignFile), StringExtension.ReplacePath(NewFile)); + } + + /// + /// 在当前目录下创建目录 + /// + /// 当前目录 + /// 新目录 + public static void FolderCreate(string OrignFolder, string NewFloder) + { + Directory.SetCurrentDirectory(StringExtension.ReplacePath(OrignFolder)); + Directory.CreateDirectory(StringExtension.ReplacePath(NewFloder)); + } + + /// + /// 创建文件夹 + /// + /// + public static void FolderCreate(string Path) + { + // 判断目标目录是否存在如果不存在则新建之 + if (!Directory.Exists(StringExtension.ReplacePath(Path))) + Directory.CreateDirectory(StringExtension.ReplacePath(Path)); + } + + + public static void FileCreate(string Path) + { + FileInfo CreateFile = new FileInfo(StringExtension.ReplacePath(Path)); //创建文件 + if (!CreateFile.Exists) + { + FileStream FS = CreateFile.Create(); + FS.Close(); + } + } + /// + /// 递归删除文件夹目录及文件 + /// + /// + /// + public static void DeleteFolder(string dir) + { + dir = StringExtension.ReplacePath(dir); + if (Directory.Exists(dir)) //如果存在这个文件夹删除之 + { + foreach (string d in Directory.GetFileSystemEntries(dir)) + { + if (File.Exists(d)) + File.Delete(d); //直接删除其中的文件 + else + DeleteFolder(d); //递归删除子文件夹 + } + Directory.Delete(dir, true); //删除已空文件夹 + } + } + + + /// + /// 指定文件夹下面的所有内容copy到目标文件夹下面 + /// + /// 原始路径 + /// 目标文件夹 + public static void CopyDir(string srcPath, string aimPath) + { + try + { + aimPath = StringExtension.ReplacePath(aimPath); + // 检查目标目录是否以目录分割字符结束如果不是则添加之 + if (aimPath[aimPath.Length - 1] != Path.DirectorySeparatorChar) + aimPath += Path.DirectorySeparatorChar; + // 判断目标目录是否存在如果不存在则新建之 + if (!Directory.Exists(aimPath)) + Directory.CreateDirectory(aimPath); + // 得到源目录的文件列表,该里面是包含文件以及目录路径的一个数组 + //如果你指向copy目标文件下面的文件而不包含目录请使用下面的方法 + //string[] fileList = Directory.GetFiles(srcPath); + string[] fileList = Directory.GetFileSystemEntries(StringExtension.ReplacePath(srcPath)); + //遍历所有的文件和目录 + foreach (string file in fileList) + { + //先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 + + if (Directory.Exists(file)) + CopyDir(file, aimPath + Path.GetFileName(file)); + //否则直接Copy文件 + else + File.Copy(file, aimPath + Path.GetFileName(file), true); + } + } + catch (Exception ee) + { + throw new Exception(ee.ToString()); + } + } + + /// + /// 获取文件夹大小 + /// + /// 文件夹路径 + /// + public static long GetDirectoryLength(string dirPath) + { + dirPath = StringExtension.ReplacePath(dirPath); + if (!Directory.Exists(dirPath)) + return 0; + long len = 0; + DirectoryInfo di = new DirectoryInfo(dirPath); + foreach (FileInfo fi in di.GetFiles()) + { + len += fi.Length; + } + DirectoryInfo[] dis = di.GetDirectories(); + if (dis.Length > 0) + { + for (int i = 0; i < dis.Length; i++) + { + len += GetDirectoryLength(dis[i].FullName); + } + } + return len; + } + + /// + /// 获取指定文件详细属性 + /// + /// 文件详细路径 + /// + public static string GetFileAttibe(string filePath) + { + string str = ""; + filePath = StringExtension.ReplacePath(filePath); + System.IO.FileInfo objFI = new System.IO.FileInfo(filePath); + str += "详细路径:" + objFI.FullName + "
文件名称:" + objFI.Name + "
文件长度:" + objFI.Length.ToString() + "字节
创建时间" + objFI.CreationTime.ToString() + "
最后访问时间:" + objFI.LastAccessTime.ToString() + "
修改时间:" + objFI.LastWriteTime.ToString() + "
所在目录:" + objFI.DirectoryName + "
扩展名:" + objFI.Extension; + return str; + } + + + /// + /// 括号匹配算法 + /// + /// 原始字符串 + /// 左匹配符号 + /// 右匹配符号 + /// + private static string parenthesisMatch(string dataStr, char leftCode, char rightCode) + { + Stack stack = new Stack(); + + string cut_text = ""; + + for (int i = 0; i < dataStr.Length; ++i) + { + char ch = dataStr[i]; + if (stack.Count > 0) + { + cut_text += ch; + } + if (ch == leftCode) + { + stack.Push(ch); + } + if (ch == rightCode) + { + stack.Pop(); + if (0 == stack.Count) + { + return cut_text.Substring(0, cut_text.Length - 1); + } + } + } + return ""; + } + + /// + /// 替换内容(正则 + 括号匹配算法) + /// + /// 文件路径 + /// 追加内容 + public static void RegxAddContentByParenthesis(string path, string addStr) + { + path = StringExtension.ReplacePath(path); + FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); + StreamReader sr = new StreamReader(fs); + string originStr = sr.ReadToEnd(); + + string pattern = @"DbContext\s*?({.*)"; + if (Regex.IsMatch(originStr, pattern)) + { + Match match = Regex.Match(originStr, pattern, RegexOptions.Singleline); + string cut_str = parenthesisMatch(match.Groups[1].Value, '{', '}'); // 剪切内容(原内容) + string new_str = cut_str + "\r\n " + addStr + "\r\n"; // 实际更新内容 + originStr = originStr.Replace(cut_str, new_str); + } + + sr.Close(); + fs.Close(); + FileStream fs2 = new FileStream(path, FileMode.Open, FileAccess.Write); + StreamWriter sw = new StreamWriter(fs2); + sw.WriteLine(originStr); + sw.Close(); + fs2.Close(); + } + } +} diff --git a/Infrastructure/Helpers/GenericHelper.cs b/Infrastructure/Helpers/GenericHelper.cs new file mode 100644 index 0000000..5c2fa64 --- /dev/null +++ b/Infrastructure/Helpers/GenericHelper.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Infrastructure.Helpers +{ + /// + /// List转成Tree + /// 李玉宝新增于2016-10-09 19:54:07 + /// + public static class GenericHelpers + { + /// + /// Generates tree of items from item list + /// + /// + /// Type of item in collection + /// Type of parent_id + /// + /// Collection of items + /// Function extracting item's id + /// Function extracting item's parent_id + /// Root element id + /// + /// Tree of items + public static IEnumerable> GenerateTree( + this IEnumerable collection, + Func idSelector, + Func parentIdSelector, + K rootId = default(K)) + { + foreach (var c in collection.Where(u => + { + var selector = parentIdSelector(u); + return (rootId == null && selector == null) + || (rootId != null && rootId.Equals(selector)); + })) + { + yield return new TreeItem + { + Item = c, + Children = collection.GenerateTree(idSelector, parentIdSelector, idSelector(c)) + }; + } + } + + /// + /// 把数组转为逗号连接的字符串 + /// + /// + /// + /// + public static string ArrayToString(dynamic data, string Str) + { + string resStr = Str; + foreach (var item in data) + { + if (resStr != "") + { + resStr += ","; + } + + if (item is string) + { + resStr += item; + } + else + { + resStr += item.Value; + + } + } + return resStr; + } + } +} \ No newline at end of file diff --git a/Infrastructure/Helpers/HIKOpenAPI.cs b/Infrastructure/Helpers/HIKOpenAPI.cs new file mode 100644 index 0000000..48539ee --- /dev/null +++ b/Infrastructure/Helpers/HIKOpenAPI.cs @@ -0,0 +1,478 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Security; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace Infrastructure.Helpers +{ + public class HIKOpenAPI + { + + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static string HttpPost(string url, string api, string body, string ak, string sk) + { + + var headers = new Dictionary { { "Accept", "*/*" }, { "Content-Type", "application/json" } }; + + var request = new Request(Method.POST_STRING, url, api, ak, sk, 10000) + { + Headers = headers, + SignHeaderPrefixList = null, + Querys = null, + StringBody = body + }; + + var result = DoPoststring(request.Host, request.Path, request.Timeout, request.Headers, request.Querys, request.StringBody, request.SignHeaderPrefixList, request.AppKey, request.AppSecret, false); + return result; + } + + //Post请求方法 + public static string DoPoststring(string host, string path, int connectTimeout, Dictionary headers, + Dictionary querys, string body, List signHeaderPrefixList, string appKey, + string appSecret, bool autoDown) + { + try + { + headers = initialBasicHeader("POST", path, headers, querys, null, signHeaderPrefixList, appKey, + appSecret); + ServicePointManager.ServerCertificateValidationCallback = + RemoteCertificateValidate; + //验证服务器证书回调自动验证 + //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | + // SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; + + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(initUrl(host, path, querys)); + request.KeepAlive = false; + request.ProtocolVersion = HttpVersion.Version10; + //设置HTTP协议的并发连接数 + //ServicePointManager.DefaultConnectionLimit = 512; + //关闭重定向 + request.AllowAutoRedirect = true; + request.Method = "POST"; + request.Timeout = connectTimeout; + string accept = headers["Accept"]; + request.Accept = accept; + string contentType = headers["Content-Type"]; + request.ContentType = contentType; + + foreach (string headerKey in headers.Keys) + { + if (headerKey.Contains("x-ca-")) + { + request.Headers.Add(headerKey + ":" + + (string.IsNullOrWhiteSpace(headers[headerKey]) ? "" : headers[headerKey])); + } + if (headerKey.Equals("tagId")) + { + request.Headers.Add(headerKey + ":" + + (string.IsNullOrWhiteSpace(headers[headerKey]) ? "" : headers[headerKey])); + } + } + + + + if (!string.IsNullOrWhiteSpace(body)) + { + byte[] postBytes = Encoding.UTF8.GetBytes(body); + request.ContentLength = postBytes.Length; + Stream requestStream = request.GetRequestStream(); + + requestStream.Write(postBytes, 0, postBytes.Length); + requestStream.Close(); + } + + + var response = (HttpWebResponse)request.GetResponse(); + var result = ""; + if (response.StatusCode != HttpStatusCode.OK) return result; + using (StreamReader rdr = new StreamReader(response.GetResponseStream())) + { + result = rdr.ReadToEnd(); + } + + return result; + } + catch (Exception ex) + { + return Newtonsoft.Json.JsonConvert.SerializeObject(new { code = "404", msg = ex.Message }); + } + } + + + //获取当时时间戳 + public static long GetTimestamp(DateTime time) + { + System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0)); + long t = (time.Ticks - startTime.Ticks) / 10000; //除10000调整为13位 + return t; + + } + + private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, + SslPolicyErrors error) + { + //为了通过证书验证,总是返回true + return true; + } + + public static Dictionary initialBasicHeader(string method, string path, + Dictionary headers, Dictionary querys, Dictionary bodys, + List signHeaderPrefixList, string appKey, string appSecret) //throws MalformedURLException + { + if (headers == null) + { + headers = new Dictionary(); + } + headers["x-ca-timestamp"] = GetTimestamp(DateTime.Now).ToString(); + headers["x-ca-nonce"] = System.Guid.NewGuid().ToString(); + headers["x-ca-key"] = appKey; + headers["x-ca-signature"] = sign(appSecret, method, path, headers, querys, bodys, signHeaderPrefixList); + + return headers; + //https://223.99.16.253:6114/pic? + //5d00=a202l94-do7b18*35d69188-64fbf0ebc**561===sp**715=7t7662209067=1l3*1513o6*720-=46fe44pi1e9o=0-9e00b0 + //&AccessKeyId=Qrq2LsyWF6GSM0zm&Expires=1677046120&Signature=Bw7dKuV6CX7w3ev56u6jBwRuGwU= + } + + public static string initUrl(string host, string path, Dictionary querys) + //throws UnsupportedEncodingException + { + StringBuilder sbUrl = new StringBuilder(); + sbUrl.Append(host); + if (!string.IsNullOrWhiteSpace(path)) + { + sbUrl.Append(path); + } + + if (null != querys) + { + StringBuilder sbQuery = new StringBuilder(); + + foreach (string queryKey in querys.Keys) + { + if (0 < sbQuery.Length) + { + sbQuery.Append("&"); + } + + if (string.IsNullOrWhiteSpace(queryKey) && !string.IsNullOrWhiteSpace(querys[queryKey])) + { + sbQuery.Append(querys[queryKey]); + } + + if (!string.IsNullOrWhiteSpace(queryKey)) + { + sbQuery.Append(queryKey); + if (!string.IsNullOrWhiteSpace(querys[queryKey])) + { + sbQuery.Append("=").Append(HttpUtility.UrlEncode(querys[queryKey], Encoding.UTF8)); + } + } + } + + if (0 < sbQuery.Length) + { + sbUrl.Append("?").Append(sbQuery); + } + } + return sbUrl.ToString(); + } + + public static string sign(string secret, string method, string path, Dictionary headers, + Dictionary querys, Dictionary bodys, List signHeaderPrefixList) + { + try + { + //return HmacSHA256(buildstringToSign(method, path, headers, querys, bodys, signHeaderPrefixList), secret); + + /*---message里的内容---*/ + //POST + //*/* + //application/json + //x-ca-key:23125513 + //x-ca-nonce:12d28d90-a7c3-45cc-ae6a-0cc8d5e22118 + //x-ca-timestamp:1544495633599 + //artemis/api/resource/v1/org/advance/orgList + string message = buildstringToSign(method, path, headers, querys, bodys, signHeaderPrefixList); + + + + return HmacSHA256(message, secret); + } + catch (Exception ex) + { + return ex.Message; + } + } + + public static string buildstringToSign(string method, string path, Dictionary headers, + Dictionary querys, Dictionary bodys, List signHeaderPrefixList) + { + StringBuilder sb = new StringBuilder(); + sb.Append(method.ToUpper()).Append("\n"); + if (null != headers) + { + if (null != headers["Accept"]) + { + sb.Append((string)headers["Accept"]); + sb.Append("\n"); + } + + if (headers.Keys.Contains("Content-MD5") && null != headers["Content-MD5"]) + { + sb.Append((string)headers["Content-MD5"]); + sb.Append("\n"); + } + + if (null != headers["Content-Type"]) + { + sb.Append((string)headers["Content-Type"]); + sb.Append("\n"); + } + + if (headers.Keys.Contains("Date") && null != headers["Date"]) + { + sb.Append((string)headers["Date"]); + sb.Append("\n"); + } + } + + sb.Append(buildHeaders(headers, signHeaderPrefixList)); + sb.Append(buildResource(path, querys, bodys)); + return sb.ToString(); + } + + public static string buildHeaders(Dictionary headers, List signHeaderPrefixList) + { + StringBuilder sb = new StringBuilder(); + if (null != signHeaderPrefixList) + { + signHeaderPrefixList.Remove("x-ca-signature"); + signHeaderPrefixList.Remove("Accept"); + signHeaderPrefixList.Remove("Content-MD5"); + signHeaderPrefixList.Remove("Content-Type"); + signHeaderPrefixList.Remove("Date"); + signHeaderPrefixList.Sort(); + } + + if (null != headers) + { + Dictionary sortDictionary = new Dictionary(); + sortDictionary = headers; + //按key值升序排序 + var dicSort = from objDic in sortDictionary orderby objDic.Key ascending select objDic; + + StringBuilder signHeadersStringBuilder = new StringBuilder(); + + foreach (KeyValuePair kvp in dicSort) + { + if (kvp.Key.Replace(" ", "").Contains("x-ca-")) + { + sb.Append(kvp.Key + ":"); + if (!string.IsNullOrWhiteSpace(kvp.Value)) + { + sb.Append(kvp.Value); + } + sb.Append("\n"); + if (signHeadersStringBuilder.Length > 0) + { + signHeadersStringBuilder.Append(","); + } + signHeadersStringBuilder.Append(kvp.Key); + } + } + + headers.Add("x-ca-signature-headers", signHeadersStringBuilder.ToString()); + } + + //x-ca-key:23125513 + //x-ca-nonce:12d28d90-a7c3-45cc-ae6a-0cc8d5e22118 + //x-ca-timestamp:1544495633599 + + return sb.ToString(); + } + + public static string buildResource(string path, Dictionary querys, Dictionary bodys) + { + StringBuilder sb = new StringBuilder(); + if (!string.IsNullOrWhiteSpace(path)) + { + sb.Append(path); + } + + Dictionary sortDictionary = new Dictionary(); + if (querys != null) + { + //按key值升序排序 + var dicSort = from objDic in querys orderby objDic.Key ascending select objDic; + foreach (KeyValuePair kvp in dicSort) + { + if (!string.IsNullOrWhiteSpace(kvp.Key)) + { + sortDictionary[kvp.Key] = kvp.Value; + } + } + } + + if (bodys != null) + { + //按key值升序排序 + var dicSort = from objDic in bodys orderby objDic.Key ascending select objDic; + foreach (KeyValuePair kvp in dicSort) + { + if (!string.IsNullOrWhiteSpace(kvp.Key)) + { + sortDictionary[kvp.Key] = kvp.Value; + } + } + } + + StringBuilder sbParam = new StringBuilder(); + + //按key值升序排序 + var dicSortDictionary = from objDic in sortDictionary orderby objDic.Key ascending select objDic; + foreach (KeyValuePair kvp in dicSortDictionary) + { + if (!string.IsNullOrWhiteSpace(kvp.Key)) + { + if (sbParam.Length > 0) + { + sbParam.Append("&"); + } + sbParam.Append(kvp.Key); + if (!string.IsNullOrWhiteSpace(kvp.Value)) + { + sbParam.Append("=").Append(kvp.Value); + } + } + } + + if (0 < sbParam.Length) + { + sb.Append("?"); + sb.Append(sbParam); + } + //artemis/api/resource/v1/org/advance/orgList + return sb.ToString(); + } + + public static string HmacSHA256(string message, string secret) + { + secret = secret ?? ""; + var encoding = new System.Text.UTF8Encoding(); + byte[] keyByte = encoding.GetBytes(secret); + byte[] messageBytes = encoding.GetBytes(message); + using (var hmacsha256 = new HMACSHA256(keyByte)) + { + byte[] hashmessage = hmacsha256.ComputeHash(messageBytes); + return Convert.ToBase64String(hashmessage); + } + } + + public static Dictionary ConvertMapTimeStyle(Dictionary paramMap) + { + Dictionary timeMap = new Dictionary(); + try + { + foreach (string key in paramMap.Keys) + { + + object mapValueObj = paramMap[key]; + Dictionary dic = mapValueObj as Dictionary; + if (dic != null) + { + ConvertMapTimeStyle(dic); + } + //时间格式参数转为ISO8601 + DateTime mapDate; + if (DateTime.TryParse(paramMap[key].ToString(), out mapDate)) + { + string ISO8601time = mapDate.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz"); + timeMap.Add(key, ISO8601time); + } + } + if (timeMap.Count > 0) + { + foreach (string key in timeMap.Keys) + { + paramMap[key] = timeMap[key]; + } + } + return paramMap; + } + catch (Exception ex) + { + return paramMap; + } + } + + + + public enum Method + { + GET, + POST_FORM, + POST_STRING, + POST_BYTES, + PUT_FORM, + PUT_STRING, + PUT_BYTES, + DELETE + } + + public class Request + { + public Request() + { + } + + public Request(Method method, string host, string path, string appKey, string appSecret, int timeout) + { + this.Method = method; + this.Host = host; + this.Path = path; + this.AppKey = appKey; + this.AppSecret = appSecret; + this.Timeout = timeout; + } + + public Method Method { get; set; } + + public string Host { get; set; } + + public string Path { get; set; } + + public string AppKey { get; set; } + + public string AppSecret { get; set; } + + public int Timeout { get; set; } + + public Dictionary Headers { get; set; } + + public Dictionary Querys { get; set; } + + public Dictionary Bodys { get; set; } + + public string StringBody { get; set; } + + public byte[] BytesBody { get; set; } + + public List SignHeaderPrefixList { get; set; } + } + } +} diff --git a/Infrastructure/Helpers/HttpHelper.cs b/Infrastructure/Helpers/HttpHelper.cs new file mode 100644 index 0000000..e80ac54 --- /dev/null +++ b/Infrastructure/Helpers/HttpHelper.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; + +namespace Infrastructure.Helpers +{ + /// + /// http请求类 + /// + public class HttpHelper + { + private HttpClient _httpClient; + private string _baseIPAddress; + + /// 请求的基础IP,例如:http://192.168.0.33:8080/ + public HttpHelper(string ipaddress = "") + { + this._baseIPAddress = ipaddress; + _httpClient = new HttpClient { BaseAddress = new Uri(_baseIPAddress) }; + } + + /// + /// 创建带用户信息的请求客户端 + /// + /// 用户账号 + /// 用户密码,当WebApi端不要求密码验证时,可传空串 + /// The URI string. + public HttpHelper(string userName, string pwd = "", string uriString = "") + : this(uriString) + { + if (!string.IsNullOrEmpty(userName)) + { + _httpClient.DefaultRequestHeaders.Authorization = CreateBasicCredentials(userName, pwd); + } + } + + /// + /// Get请求数据 + /// /// 最终以url参数的方式提交 + /// yubaolee 2016-3-3 重构与post同样异步调用 + /// + /// 参数字典,可为空 + /// 例如/api/Files/UploadFile + /// + public string Get(Dictionary parameters, string requestUri) + { + if (parameters != null) + { + var strParam = string.Join("&", parameters.Select(o => o.Key + "=" + o.Value)); + requestUri = string.Concat(ConcatURL(requestUri), '?', strParam); + } + else + { + requestUri = ConcatURL(requestUri); + } + + var result = _httpClient.GetStringAsync(requestUri); + return result.Result; + } + + /// + /// Get请求数据 + /// 最终以url参数的方式提交 + /// + /// 参数字典 + /// 例如/api/Files/UploadFile + /// 实体对象 + public T Get(Dictionary parameters, string requestUri) where T : class + { + string jsonString = Get(parameters, requestUri); + if (string.IsNullOrEmpty(jsonString)) + return null; + + return JsonHelper.Instance.Deserialize(jsonString); + } + + /// + /// 以json的方式Post数据 返回string类型 + /// 最终以json的方式放置在http体中 + /// + /// 实体 + /// 例如/api/Files/UploadFile + /// + public string Post(object entity, string requestUri) + { + string request = string.Empty; + if (entity != null) + request = JsonHelper.Instance.Serialize(entity); + HttpContent httpContent = new StringContent(request); + httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + return Post(requestUri, httpContent); + } + + /// + /// 提交字典类型的数据 + /// 最终以formurlencode的方式放置在http体中 + /// 李玉宝于2016-07-20 19:01:59 + /// + /// System.String. + public string PostDicObj(Dictionary para, string requestUri) + { + Dictionary temp = new Dictionary(); + foreach (var item in para) + { + if (item.Value != null) + { + if (item.Value.GetType().Name.ToLower() != "string") + { + temp.Add(item.Key, JsonHelper.Instance.Serialize(item.Value)); + } + else + { + temp.Add(item.Key, item.Value.ToString()); + } + } + else { + temp.Add(item.Key, ""); + } + } + + return PostDic(temp, requestUri); + } + + /// + /// Post Dic数据 + /// 最终以formurlencode的方式放置在http体中 + /// 李玉宝于2016-07-15 15:28:41 + /// + /// System.String. + public string PostDic(Dictionary temp, string requestUri) + { + HttpContent httpContent = new FormUrlEncodedContent(temp); + httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); + return Post(requestUri, httpContent); + } + + public string PostByte(byte[] bytes, string requestUrl) + { + HttpContent content = new ByteArrayContent(bytes); + content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); + return Post(requestUrl, content); + } + + private string Post(string requestUrl, HttpContent content) + { + var result = _httpClient.PostAsync(ConcatURL(requestUrl), content); + return result.Result.Content.ReadAsStringAsync().Result; + } + + /// + /// 把请求的URL相对路径组合成绝对路径 + /// 李玉宝于2016-07-21 9:54:07 + /// + private string ConcatURL(string requestUrl) + { + return new Uri(_httpClient.BaseAddress, requestUrl).OriginalString; + } + + private AuthenticationHeaderValue CreateBasicCredentials(string userName, string password) + { + string toEncode = userName + ":" + password; + // The current HTTP specification says characters here are ISO-8859-1. + // However, the draft specification for the next version of HTTP indicates this encoding is infrequently + // used in practice and defines behavior only for ASCII. + Encoding encoding = Encoding.GetEncoding("utf-8"); + byte[] toBase64 = encoding.GetBytes(toEncode); + string parameter = Convert.ToBase64String(toBase64); + + return new AuthenticationHeaderValue("Basic", parameter); + } + } +} \ No newline at end of file diff --git a/Infrastructure/Helpers/HttpMethods.cs b/Infrastructure/Helpers/HttpMethods.cs new file mode 100644 index 0000000..86d19f0 --- /dev/null +++ b/Infrastructure/Helpers/HttpMethods.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Security; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; +using System.Net.Http.Headers; + +namespace Infrastructure.Helpers +{ + public class HttpMethods + { + // + // 摘要: + // 创建HttpClient + public static HttpClient CreateHttpClient(string url, IDictionary cookies = null) + { + HttpClientHandler httpClientHandler = new HttpClientHandler(); + Uri uri = new Uri(url); + if (cookies != null) + { + foreach (string key in cookies.Keys) + { + string cookieHeader = key + "=" + cookies[key]; + httpClientHandler.CookieContainer.SetCookies(uri, cookieHeader); + } + } + + if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) + { + ServicePointManager.ServerCertificateValidationCallback = (RemoteCertificateValidationCallback)Delegate.Combine(ServicePointManager.ServerCertificateValidationCallback, (RemoteCertificateValidationCallback)((object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true)); + return new HttpClient(httpClientHandler); + } + + return new HttpClient(httpClientHandler); + } + + // + // 摘要: + // post 请求 + // + // 参数: + // url: + // 请求地址 + // + // jsonData: + // 请求参数 + public static Task Post(string url, string jsonData) + { + HttpClient httpClient = CreateHttpClient(url); + StringContent stringContent = new StringContent(jsonData); + stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); + return httpClient.PostAsync(url, stringContent).Result.Content.ReadAsStringAsync(); + } + + // + // 摘要: + // post 请求 + // + // 参数: + // url: + // 请求地址 + public static Task Post(string url) + { + HttpClient httpClient = CreateHttpClient(url); + StringContent stringContent = new StringContent(""); + stringContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); + return httpClient.PostAsync(url, stringContent).Result.Content.ReadAsStringAsync(); + } + + // + // 摘要: + // post 请求 + // + // 参数: + // url: + // 请求地址 + // + // req: + // 请求参数 + public static Task Post(string url, byte[] req) + { + HttpClient httpClient = CreateHttpClient(url); + ByteArrayContent content = new ByteArrayContent(req); + return httpClient.PostAsync(url, content).Result.Content.ReadAsStringAsync(); + } + + // + // 摘要: + // get 请求 + // + // 参数: + // url: + // 请求地址 + public static Task Get(string url) + { + HttpClient httpClient = CreateHttpClient(url); + return httpClient.GetAsync(url).Result.Content.ReadAsStringAsync(); + } + } +} diff --git a/Infrastructure/Helpers/ImageHelper.cs b/Infrastructure/Helpers/ImageHelper.cs new file mode 100644 index 0000000..eefe604 --- /dev/null +++ b/Infrastructure/Helpers/ImageHelper.cs @@ -0,0 +1,34 @@ +using System.Drawing.Imaging; +using Image = System.Drawing.Image; + +namespace Hopetry.App.Common; + +public class ImageHelper +{ + /// + /// 图片转换成字节流 + /// + /// 要转换的Image对象 + /// 转换后返回的字节流 + public static Stream ImgToStream(Image img) + { + byte[] imgByte = ImgToByt(img); + //img.Save(ms, img.RawFormat);//System.Drawing.Imaging.ImageFormat.Jpeg + Stream stream = new MemoryStream(imgByte); + return stream; + } + + /// + /// 图片转换成字节流 + /// + /// 要转换的Image对象 + /// 转换后返回的字节流 + public static byte[] ImgToByt(Image img) + { + MemoryStream ms = new MemoryStream(); + byte[] imagedata = null; + img.Save(ms, ImageFormat.Jpeg); + imagedata = ms.GetBuffer(); + return imagedata; + } +} \ No newline at end of file diff --git a/Infrastructure/Helpers/ImgHelper.cs b/Infrastructure/Helpers/ImgHelper.cs new file mode 100644 index 0000000..6503542 --- /dev/null +++ b/Infrastructure/Helpers/ImgHelper.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) 2019 openauth.net.cn. All rights reserved. +// +// www.cnblogs.com/yubaolee +// 生成缩略图 + +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Processing; + +namespace Infrastructure.Helpers +{ + public class ImgHelper + { + /// + /// 根据已有图片生成缩略图 + /// 用法:MakeThumbnail(path, tpath, 120, 90, "H"); + /// + /// 源图片路径 + /// 缩略图保存路径 + /// 缩略图的宽度 + /// 缩略图高度 + /// 缩略模式:H:指定高度,宽度按比例处理;W:指定宽度,高度按比例处理;HW按参数指定的高度和宽度 + public static void MakeThumbnail(string originalImagePath, + string thumbnailPath, + int width = 120, int height = 90, string mode = "H") + { + using (var originalImage = Image.Load(originalImagePath)) + { + int towidth = width; //缩略图宽度 + int toheight = height; //缩略图高度 + switch (mode) + { + case "HW": //指定高宽缩放(可能变形) + break; + case "W": //指定宽,高按比例 + toheight = originalImage.Height * width / originalImage.Width; + break; + case "H": //指定高,宽按比例 + towidth = originalImage.Width * height / originalImage.Height; + break; + default: + break; + } + + originalImage.Mutate(x => x.Resize(towidth, toheight)); + originalImage.Save(thumbnailPath); + } + } + } +} \ No newline at end of file diff --git a/Infrastructure/Helpers/Md5.cs b/Infrastructure/Helpers/Md5.cs new file mode 100644 index 0000000..05ae4df --- /dev/null +++ b/Infrastructure/Helpers/Md5.cs @@ -0,0 +1,31 @@ +using System; +using System.Security.Cryptography; +using System.Text; + +namespace Infrastructure.Helpers +{ + public class Md5 + { + public static string Encrypt(string str) + { + + string pwd = String.Empty; + + MD5 md5 = MD5.Create(); + + // 编码UTF8/Unicode  + byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); + + // 转换成字符串 + for (int i = 0; i < s.Length; i++) + { + //格式后的字符是小写的字母 + //如果使用大写(X)则格式后的字符是大写字符 + pwd = pwd + s[i].ToString("X"); + + } + + return pwd; + } + } +} diff --git a/Infrastructure/Helpers/Md5Helper.cs b/Infrastructure/Helpers/Md5Helper.cs new file mode 100644 index 0000000..7e4179d --- /dev/null +++ b/Infrastructure/Helpers/Md5Helper.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Security.Cryptography; + +namespace Infrastructure.Helpers +{ + public class Md5Helper + { + // + // 摘要: + // MD5加密 + // + // 参数: + // str: + // 加密字符 + // + // code: + // 加密位数16/32 + public static string Encrypt(string str, int code) + { + string result = string.Empty; + if (code == 16) + { + result = Hash(str).Substring(8, 16); + } + + if (code == 32) + { + result = Hash(str); + } + + return result; + } + + // + // 摘要: + // 32位MD5加密(小写) + // + // 参数: + // input: + // 输入字段 + public static string Hash(string input) + { + MD5CryptoServiceProvider mD5CryptoServiceProvider = new MD5CryptoServiceProvider(); + byte[] array = mD5CryptoServiceProvider.ComputeHash(Encoding.Default.GetBytes(input)); + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < array.Length; i++) + { + stringBuilder.Append(array[i].ToString("x2")); + } + + return stringBuilder.ToString(); + } + } +} diff --git a/Infrastructure/Helpers/ObjectHelper.cs b/Infrastructure/Helpers/ObjectHelper.cs new file mode 100644 index 0000000..4e169ca --- /dev/null +++ b/Infrastructure/Helpers/ObjectHelper.cs @@ -0,0 +1,65 @@ +// *********************************************************************** +// Assembly : Infrastructure +// Author : Yubao Li +// Created : 11-23-2015 +// +// Last Modified By : Yubao Li +// Last Modified On : 11-23-2015 +// *********************************************************************** +// +// Copyright (c) . All rights reserved. +// +// +//对象COPY/初始化帮助,通常是防止从视图中传过来的对象属性为空,这其赋初始值 +// +// *********************************************************************** + +using System.Reflection; + +namespace Infrastructure.Helpers +{ + public static class ObjectHelper + { + public static T CopyTo(this object source) where T:class, new() + { + var result = new T(); + source.CopyTo(result); + return result; + } + + public static void CopyTo(this object source, T target) + where T : class,new() + { + if (source == null) + return; + + if (target == null) + { + target = new T(); + } + + foreach (var property in target.GetType().GetProperties()) + { + var propertyValue = source.GetType().GetProperty(property.Name).GetValue(source, null); + if (propertyValue != null) + { + if (propertyValue.GetType().IsClass) + { + + } + target.GetType().InvokeMember(property.Name, BindingFlags.SetProperty, null, target, new object[] { propertyValue }); + } + + } + + foreach (var field in target.GetType().GetFields()) + { + var fieldValue = source.GetType().GetField(field.Name).GetValue(source); + if (fieldValue != null) + { + target.GetType().InvokeMember(field.Name, BindingFlags.SetField, null, target, new object[] { fieldValue }); + } + } + } + } +} diff --git a/Infrastructure/Helpers/WordHelper.cs b/Infrastructure/Helpers/WordHelper.cs new file mode 100644 index 0000000..843f3db --- /dev/null +++ b/Infrastructure/Helpers/WordHelper.cs @@ -0,0 +1,347 @@ +using System.Collections; +using System.Text.RegularExpressions; +using NetModular.DocX.Core; + + +namespace Infrastructure.Helpers; + +public class WordHelper +{ + /// + /// 导出word + /// + /// 模板路径 + /// 保存路径 + /// 数据 + public static void Export(string tempFilePath, string outPath, Dictionary data) + { + bool isrewrite = true; // true=覆盖已存在的同名文件,false则反之 + //if (!System.IO.Directory.Exists(outPath)) + //{ + // System.IO.Directory.CreateDirectory(outPath); + //} + File.Copy(tempFilePath, outPath, isrewrite); + //新建一个Word文档,加载Load的方法和Create使用一样。 + using (DocX document = DocX.Load(outPath)) + { + ReplaceDoc(document, data); //普通文本替换 + ReplaceTable(document, data); //表格处理 + ReplaceList(document, data); //文本列表处理 + + document.Save(); //保存 + } + } + + private static void ReplaceDoc(DocX doc, Dictionary data) + { + foreach (var item in doc.Paragraphs) + { + ReplaceParagraph(item, data); + } + } + + private static void ReplaceList(DocX doc, Dictionary data) + { + //一定要在 普通文本替换和表格处理之后 + foreach (var p in doc.Paragraphs) + { + var li = GetListInfo(p, data); + if (li.IsList) + { + var pc = li.PTemp; + for (int i = 0; i < li.Data.Count; i++) + { + var pt = pc.InsertParagraphAfterSelf(p); + if (li.IsDict) + { + pc = ReplaceParagraph(pt, (Dictionary)li.Data[i]); + } + else + { + pc = ReplaceParagraph(pt, li.Data[i]); + } + } + + //删除模板行 + li.PTemp.Remove(false); + } + else + { + //do nonthing + } + } + } + + private static void ReplaceTable(DocX doc, Dictionary data) + { + var tbs = doc.Tables; + foreach (var table in tbs) + { + //需要先判断表格是列表还是表单 + var ti = GetTableInfo(table, data); + if (ti.IsList) + { + for (int i = 0; i < ti.Data.Count; i++) + { + var rt = table.InsertRow(ti.RowTemp); + rt.Height = ti.RowTemp.Height; + rt.MinHeight = ti.RowTemp.MinHeight; + if (ti.IsDict) + { + ReplaceRow(rt, (Dictionary)ti.Data[i]); + } + else + { + ReplaceRow(rt, ti.Data[i]); + } + } + + //删除模板行 + ti.RowTemp.Remove(); + } + else + { + //do nonthing + } + } + } + + private static void ReplaceRow(Row row, Dictionary data) + { + foreach (var cell in row.Cells) + { + foreach (var item in cell.Paragraphs) + { + ReplaceParagraph(item, data); + } + } + } + + private static void ReplaceRow(Row row, object data) + { + foreach (var cell in row.Cells) + { + foreach (var item in cell.Paragraphs) + { + ReplaceParagraph(item, data); + } + } + } + + private static Paragraph ReplaceParagraph(Paragraph p, Dictionary data) + { + Paragraph pr = p; + var ms = GetMatches(p.Text); + var ks = new List(); + var rs = new List(); + foreach (Match m in ms) + { + if (m.Groups.Count > 1) + { + string text = m.Groups[1].Value; + if (text.Contains(".")) + { + var ts = text.Split("."); + text = ts[ts.Length - 1]; + } + + ks.Add(text); + rs.Add(m.Value); + } + } + + bool isCt = data.Any(op => ks.Any(o => o.Contains(op.Key))); + bool isReplace = false; + + if (isCt) + { + if (ks.Count > 1) + { + for (int i = 0; i < ks.Count; i++) + { + if (data.ContainsKey(ks[i])) + { + p.ReplaceText(rs[i], data[ks[i]]?.ToString()); + } + } + } + else if (ks.Count == 1) + { + string text = ks[0]; + if (data.ContainsKey(text)) + { + var ct = data[text]?.ToString(); + var cts = ResolveText(ct); + var pc = p; + foreach (var item2 in cts) + { + if (string.IsNullOrWhiteSpace(item2)) continue; + var pt = pc.InsertParagraphAfterSelf(p); + pt.ReplaceText(rs[0], item2); + pc = pt; + pr = pc; + } + + isReplace = true; + } + } + + if (isReplace) + { + //删除原来段落 + p.Remove(false); + } + } + + return pr; + } + + private static Paragraph ReplaceParagraph(Paragraph p, object data) + { + var ms = GetMatches(p.Text); + var isReplace = false; + Paragraph pr = p; + foreach (Match item1 in ms) + { + if (item1.Groups.Count > 1) + { + string text = item1.Groups[1].Value; + + var ct = data?.ToString(); + var cts = ResolveText(ct); + var pc = p; + foreach (var item2 in cts) + { + var pt = pc.InsertParagraphAfterSelf(p); + pt.ReplaceText(item1.Value, item2); + pc = pt; + pr = pc; + } + + isReplace = true; + } + } + + if (isReplace) + { + //删除原来段落 + p.Remove(false); + } + + return pr; + } + + private static IList ResolveText(string text) + { + if (string.IsNullOrEmpty(text)) return new List(); + text = text.Replace("\r\n", "\n").Replace("\r", "\n"); + return text.Split('\n'); + } + + private static MatchCollection GetMatches(string text) + { + if (string.IsNullOrEmpty(text)) text = ""; + Regex regex = new Regex("[#|\\$]([a-zA-Z0-9_.]+?)[#|\\$]", + RegexOptions.IgnoreCase | RegexOptions.Multiline); + return regex.Matches(text); + } + + /// + /// 只获取列表匹配项 + /// + /// + /// + private static MatchCollection GetListMatches(string text) + { + if (string.IsNullOrEmpty(text)) text = ""; + Regex regex = new Regex("\\$([a-zA-Z0-9_.]+?)\\$", RegexOptions.IgnoreCase | RegexOptions.Multiline); + return regex.Matches(text); + } + + //纯辅助方法 + private class TableInfo + { + public bool IsList { get; set; } + public bool IsDict { get; set; } + public Row RowTemp { get; set; } + public IList Data { get; set; } + } + + //判断表格是列表还是表单 + private static TableInfo GetTableInfo(Table table, Dictionary data) + { + TableInfo result = new TableInfo(); + var r0 = table.Rows[table.Rows.Count - 1]; + var c0 = r0.Cells[r0.Cells.Count - 1]; + var ct = c0.Paragraphs[0].Text; + var ms = GetListMatches(ct); + foreach (Match item in ms) + { + if (item.Groups.Count > 1) + { + string text = item.Groups[1].Value; + if (text.Contains(".")) + { + result.IsDict = true; + text = text.Split('.')[0]; + } + + if (data.ContainsKey(text) && (data[text] is IList)) //判断是否是列表 + { + result.RowTemp = r0; + result.IsList = true; + result.Data = new List(); + foreach (var item1 in (data[text] as IList)) + { + result.Data.Add(item1); + } + + break; + } + } + } + + return result; + } + + private class ListInfo + { + public bool IsList { get; set; } + public bool IsDict { get; set; } + public Paragraph PTemp { get; set; } + public IList Data { get; set; } + } + + private static ListInfo GetListInfo(Paragraph p, Dictionary data) + { + ListInfo result = new ListInfo(); + var ms = GetListMatches(p.Text); + foreach (Match item in ms) + { + if (item.Groups.Count > 1) + { + string text = item.Groups[1].Value; + if (text.Contains(".")) + { + result.IsDict = true; + text = text.Split('.')[0]; + } + + if (data.ContainsKey(text) && (data[text] is IList)) //判断是否是列表 + { + result.PTemp = p; + result.IsList = true; + result.Data = new List(); + foreach (var item1 in (data[text] as IList)) + { + result.Data.Add(item1); + } + + break; + } + } + } + + return result; + } +} \ No newline at end of file diff --git a/Infrastructure/Helpers/XmlHelper.cs b/Infrastructure/Helpers/XmlHelper.cs new file mode 100644 index 0000000..8583287 --- /dev/null +++ b/Infrastructure/Helpers/XmlHelper.cs @@ -0,0 +1,710 @@ +using System.Xml; + +namespace Infrastructure.Helpers +{ + /// + /// XMLHelper参数 + /// + public class XmlParameter + { + private string _name; + private string _innerText; + private string _namespaceOfPrefix; + private AttributeParameter[] _attributes; + + public XmlParameter() { } + public XmlParameter(string name, params AttributeParameter[] attParas) : this(name, null, null, attParas) { } + public XmlParameter(string name, string innerText, params AttributeParameter[] attParas) : this(name, innerText, null, attParas) { } + public XmlParameter(string name, string innerText, string namespaceOfPrefix, params AttributeParameter[] attParas) + { + this._name = name; + this._innerText = innerText; + this._namespaceOfPrefix = namespaceOfPrefix; + this._attributes = attParas; + } + /// + /// 节点名称 + /// + public string Name + { + get { return this._name; } + set { this._name = value; } + } + /// + /// 节点文本 + /// + public string InnerText + { + get { return this._innerText; } + set { this._innerText = value; } + } + /// + /// 节点前缀xmlns声明(命名空间URI) + /// + public string NamespaceOfPrefix + { + get { return this._namespaceOfPrefix; } + set { this._namespaceOfPrefix = value; } + } + /// + /// 节点属性集 + /// + public AttributeParameter[] Attributes + { + get { return this._attributes; } + set { this._attributes = value; } + } + } + + /// + /// 节点属性参数 + /// + public class AttributeParameter + { + private string _name; + private string _value; + + public AttributeParameter() { } + public AttributeParameter(string attributeName, string attributeValue) + { + this._name = attributeName; + this._value = attributeValue; + } + /// + /// 属性名称 + /// + public string Name + { + get { return this._name; } + set { this._name = value; } + } + /// + /// 属性值 + /// + public string Value + { + get { return this._value; } + set { this._value = value; } + } + } + + public class XMLHelper + { + private static string _xPath; + /// + /// xml文件路径 + /// + public static string XmlPath + { + get { return _xPath; } + set { _xPath = value; } + } + private static string _configName = "XmlPath"; + /// + /// 配置文件节点名称,请设置在AppSettings节点下 + /// + public static string ConfigName + { + get { return _configName; } + set { _configName = value; GetConfig(); } + } + /// + /// 从配置文件读取xml路径 + /// + static void GetConfig() + { + //if (string.IsNullOrEmpty(_xPath)) + //{ + // try + // { + // _xPath = ConfigurationManager.AppSettings[_configName]; + // } + // catch { } + //} + } + static XMLHelper() { GetConfig(); } + + #region private AppendChild + /// + /// 添加一个子节点 + /// + /// XmlDocument对象 + /// 父节点 + /// Xml参数 + private static void AppendChild(XmlDocument xDoc, XmlNode parentNode, params XmlParameter[] xlParameter) + { + foreach (XmlParameter xpar in xlParameter) + { + XmlNode newNode = xDoc.CreateNode(XmlNodeType.Element, xpar.Name, null); + string ns = string.IsNullOrEmpty(xpar.NamespaceOfPrefix) ? "" : newNode.GetNamespaceOfPrefix(xpar.NamespaceOfPrefix); + foreach (AttributeParameter attp in xpar.Attributes) + { + XmlNode attr = xDoc.CreateNode(XmlNodeType.Attribute, attp.Name, ns == "" ? null : ns); + attr.Value = attp.Value; + newNode.Attributes.SetNamedItem(attr); + } + newNode.InnerText = xpar.InnerText; + parentNode.AppendChild(newNode); + } + } + #endregion + + #region private AddEveryNode + private static void AddEveryNode(XmlDocument xDoc, XmlNode parentNode, params XmlParameter[] paras) + { + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + foreach (XmlNode xns in nlst) + { + if (xns.Name == parentNode.Name) + { + AppendChild(xDoc, xns, paras); + } + else + { + foreach (XmlNode xn in xns) + { + if (xn.Name == parentNode.Name) + { + AppendChild(xDoc, xn, paras); + } + } + } + } + } + #endregion + + #region private GetXmlDom + /// + /// 获得一个XmlDocument对象 + /// + /// + private static XmlDocument GetXmlDom() + { + XmlDocument xdoc = new XmlDocument(); + xdoc.Load(_xPath); + return xdoc; + } + #endregion + + #region CreateXmlFile + /// + /// 创建一个XML文档,成功创建后操作路径将直接指向该文件 + /// + /// 文件物理路径名 + /// 根结点名称 + /// 元素节点名称 + /// XML参数 + public static void CreateXmlFile(string fileName, string rootNode, string elementName, params XmlParameter[] xmlParameter) + { + XmlDocument xDoc = new XmlDocument(); + XmlNode xn = xDoc.CreateXmlDeclaration("1.0", "UTF-8", null); + xDoc.AppendChild(xn); + XmlNode root = xDoc.CreateElement(rootNode); + xDoc.AppendChild(root); + XmlNode ln = xDoc.CreateNode(XmlNodeType.Element, elementName, null); + AppendChild(xDoc, ln, xmlParameter); + root.AppendChild(ln); + try + { + xDoc.Save(fileName); + _xPath = fileName; + } + catch + { + throw; + } + } + /// + /// 创建一个XML文档,成功创建后操作路径将直接指向该文件 + /// + /// 文件物理路径名 + /// xml字符串 + public static void CreateXmlFile(string fileName, string xmlString) + { + XmlDocument xDoc = new XmlDocument(); + try + { + xDoc.LoadXml(xmlString); + xDoc.Save(fileName); + _xPath = fileName; + } + catch { throw; } + } + #endregion + + #region AddNewNode + /// + /// 添加新节点 + /// + /// 新节点的父节点对象 + /// Xml参数对象 + public static void AddNewNode(XmlNode parentNode, params XmlParameter[] xmlParameter) + { + XmlDocument xDoc = GetXmlDom(); + if (parentNode.Name == xDoc.DocumentElement.Name) + { + XmlNode newNode = xDoc.CreateNode(XmlNodeType.Element, xDoc.DocumentElement.ChildNodes[0].Name, null); + AppendChild(xDoc, newNode, xmlParameter); + xDoc.DocumentElement.AppendChild(newNode); + } + else + { + AddEveryNode(xDoc, parentNode, xmlParameter); + } + xDoc.Save(_xPath); + } + /// + /// 添加新节点 + /// + /// XmlDocument对象 + /// 新节点的父节点名称 + /// XML参数对象 + public static void AddNewNode(string parentName, params XmlParameter[] xmlParameter) + { + XmlDocument xDoc = GetXmlDom(); + XmlNode parentNode = GetNode(xDoc, parentName); + if (parentNode == null) return; + if (parentNode.Name == xDoc.DocumentElement.Name) + { + XmlNode newNode = xDoc.CreateNode(XmlNodeType.Element, xDoc.DocumentElement.ChildNodes[0].Name, null); + AppendChild(xDoc, newNode, xmlParameter); + xDoc.DocumentElement.AppendChild(newNode); + } + else + { + AddEveryNode(xDoc, parentNode, xmlParameter); + } + xDoc.Save(_xPath); + } + #endregion + + #region AddAttribute + /// + /// 添加节点属性 + /// + /// 节点对象 + /// 该节点的命名空间URI + /// 新属性名称 + /// 属性值 + public static void AddAttribute(XmlNode node, string namespaceOfPrefix, string attributeName, string attributeValue) + { + XmlDocument xDoc = GetXmlDom(); + string ns = string.IsNullOrEmpty(namespaceOfPrefix) ? "" : node.GetNamespaceOfPrefix(namespaceOfPrefix); + XmlNode xn = xDoc.CreateNode(XmlNodeType.Attribute, attributeName, ns == "" ? null : ns); + xn.Value = attributeValue; + node.Attributes.SetNamedItem(xn); + xDoc.Save(_xPath); + } + /// + /// 添加节点属性 + /// + /// 节点对象 + /// 该节点的命名空间URI + /// 节点属性参数 + public static void AddAttribute(XmlNode node, string namespaceOfPrefix, params AttributeParameter[] attributeParameters) + { + XmlDocument xDoc = GetXmlDom(); + string ns = string.IsNullOrEmpty(namespaceOfPrefix) ? "" : node.GetNamespaceOfPrefix(namespaceOfPrefix); + foreach (AttributeParameter attp in attributeParameters) + { + XmlNode xn = xDoc.CreateNode(XmlNodeType.Attribute, attp.Name, ns == "" ? null : ns); + xn.Value = attp.Value; + node.Attributes.SetNamedItem(xn); + } + xDoc.Save(_xPath); + } + /// + /// 添加节点属性 + /// + /// 节点名称 + /// 该节点的命名空间URI + /// 新属性名称 + /// 属性值 + public static void AddAttribute(string nodeName, string namespaceOfPrefix, string attributeName, string attributeValue) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList xlst = xDoc.DocumentElement.ChildNodes; + for (int i = 0; i < xlst.Count; i++) + { + XmlNode node = GetNode(xlst[i], nodeName); + if (node == null) break; + AddAttribute(node, namespaceOfPrefix, attributeName, attributeValue); + } + xDoc.Save(_xPath); + } + /// + /// 添加节点属性 + /// + /// 节点名称 + /// 该节点的命名空间URI + /// 节点属性参数 + public static void AddAttribute(string nodeName, string namespaceOfPrefix, params AttributeParameter[] attributeParameters) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList xlst = xDoc.DocumentElement.ChildNodes; + for (int i = 0; i < xlst.Count; i++) + { + XmlNode node = GetNode(xlst[i], nodeName); + if (node == null) break; + AddAttribute(node, namespaceOfPrefix, attributeParameters); + } + xDoc.Save(_xPath); + } + #endregion + + #region GetNode + /// + /// 获取指定节点名称的节点对象 + /// + /// 节点名称 + /// + public static XmlNode GetNode(string nodeName) + { + XmlDocument xDoc = GetXmlDom(); + if (xDoc.DocumentElement.Name == nodeName) return (XmlNode)xDoc.DocumentElement; + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + foreach (XmlNode xns in nlst) // 遍历所有子节点 + { + if (xns.Name == nodeName) return xns; + else + { + XmlNode xn = GetNode(xns, nodeName); + if (xn != null) return xn; + } + } + return null; + } + /// + /// 获取指定节点名称的节点对象 + /// + /// 节点对象 + /// 节点名称 + /// + public static XmlNode GetNode(XmlNode node, string nodeName) + { + foreach (XmlNode xn in node) + { + if (xn.Name == nodeName) return xn; + else + { + XmlNode tmp = GetNode(xn, nodeName); + if (tmp != null) return tmp; + } + } + return null; + } + /// + /// 获取指定节点名称的节点对象 + /// + /// 节点索引 + /// 节点名称 + public static XmlNode GetNode(int index, string nodeName) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + if (nlst.Count <= index) return null; + if (nlst[index].Name == nodeName) return (XmlNode)nlst[index]; + foreach (XmlNode xn in nlst[index]) + { + return GetNode(xn, nodeName); + } + return null; + } + /// + /// 获取指定节点名称的节点对象 + /// + /// 节点对象 + /// 节点名称 + /// 节点内容 + public static XmlNode GetNode(XmlNode node, string nodeName, string innerText) + { + foreach (XmlNode xn in node) + { + if (xn.Name == nodeName && xn.InnerText == innerText) return xn; + else + { + XmlNode tmp = GetNode(xn, nodeName, innerText); + if (tmp != null) return tmp; + } + } + return null; + } + /// + /// 获取指定节点名称的节点对象 + /// + /// 节点名称 + /// 节点内容 + public static XmlNode GetNode(string nodeName, string innerText) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + foreach (XmlNode xns in nlst) // 遍历所有子节点 + { + if (xns.Name == nodeName && xns.InnerText == innerText) return xns; + XmlNode tmp = GetNode(xns, nodeName, innerText); + if (tmp != null) return tmp; + } + return null; + } + /// + /// 获取指定节点名称的节点对象 + /// + /// XML参数 + public static XmlNode GetNode(XmlParameter xmlParameter) + { + return GetNode(xmlParameter.Name, xmlParameter.InnerText); + } + /// + /// 获取指定节点名称的节点对象 + /// + /// 节点对象 + /// XML参数 + public static XmlNode GetNode(XmlNode node, XmlParameter xmlParameter) + { + return GetNode(node, xmlParameter.Name, node.InnerText); + } + #endregion + + #region UpdateNode + private static void UpdateNode(XmlNode node, XmlParameter xmlParameter) + { + node.InnerText = xmlParameter.InnerText; + for (int i = 0; i < xmlParameter.Attributes.Length; i++) + { + for (int j = 0; j < node.Attributes.Count; j++) + { + if (node.Attributes[j].Name == xmlParameter.Attributes[i].Name) + { + node.Attributes[j].Value = xmlParameter.Attributes[i].Value; + } + } + } + } + private static void UpdateNode(XmlNode node, string innerText, AttributeParameter[] attributeParameters) + { + node.InnerText = innerText; + for (int i = 0; i < attributeParameters.Length; i++) + { + for (int j = 0; j < node.Attributes.Count; j++) + { + if (node.Attributes[j].Name == attributeParameters[i].Name) + { + node.Attributes[j].Value = attributeParameters[i].Value; + } + } + } + } + /// + /// 修改节点的内容 + /// + /// 节点索引 + /// XML参数对象 + public static void UpdateNode(int index, XmlParameter xmlParameter) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + if (nlst.Count <= index) return; + if (nlst[index].Name == xmlParameter.Name) + { + UpdateNode(nlst[index], xmlParameter); + } + else + { + foreach (XmlNode xn in nlst[index]) + { + XmlNode xnd = GetNode(xn, xmlParameter.Name); + if (xnd != null) + { + UpdateNode(xnd, xmlParameter); + } + } + } + xDoc.Save(_xPath); + } + /// + /// 修改节点的内容 + /// + /// 节点索引 + /// 节点名称 + /// 修改后的内容 + public static void UpdateNode(int index, string nodeName, string newInnerText) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + if (nlst.Count <= index) return; + if (nlst[index].Name == nodeName) + { + nlst[index].InnerText = newInnerText; + } + else + { + foreach (XmlNode xn in nlst[index]) + { + XmlNode xnd = GetNode(xn, nodeName); + if (xnd != null) + { + xnd.InnerText = newInnerText; + } + } + } + xDoc.Save(_xPath); + } + /// + /// 修改节点的内容 + /// + /// XmlParameter对象 + /// 修改后的内容 + /// 需要修改的属性 + public static void UpdateNode(XmlParameter xmlParameter, string innerText, params AttributeParameter[] attributeParameters) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + foreach (XmlNode xns in nlst) // 遍历所有子节点 + { + if (xns.Name == xmlParameter.Name && xns.InnerText == xmlParameter.InnerText) + { + UpdateNode(xns, innerText, attributeParameters); + break; + } + XmlNode tmp = GetNode(xns, xmlParameter); + if (tmp != null) + { + UpdateNode(tmp, innerText, attributeParameters); + break; + } + } + xDoc.Save(_xPath); + } + #endregion + + #region DeleteNode + /// + /// 删除节点 + /// + /// 节点索引 + public static void DeleteNode(int index) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + nlst[index].ParentNode.RemoveChild(nlst[index]); + xDoc.Save(_xPath); + } + /// + /// 删除节点 + /// + /// 需要删除的节点对象 + public static void DeleteNode(params XmlNode[] nodeList) + { + XmlDocument xDoc = GetXmlDom(); + foreach (XmlNode xnl in nodeList) + { + foreach (XmlNode xn in xDoc.DocumentElement.ChildNodes) + { + if (xnl.Equals(xn)) + { + xn.ParentNode.RemoveChild(xn); + break; + } + } + } + xDoc.Save(_xPath); + } + /// + /// 删除节点 + /// + /// XmlDocument对象 + /// 节点名称 + /// 节点内容 + public static void DeleteNode(string nodeName, string nodeText) + { + XmlDocument xDoc = GetXmlDom(); + foreach (XmlNode xn in xDoc.DocumentElement.ChildNodes) + { + if (xn.Name == nodeName) + { + if (xn.InnerText == nodeText) + { + xn.ParentNode.RemoveChild(xn); + return; + } + } + else + { + XmlNode node = GetNode(xn, nodeName); + if (node != null && node.InnerText == nodeText) + { + node.ParentNode.ParentNode.RemoveChild(node.ParentNode); + return; + } + } + } + xDoc.Save(_xPath); + } + #endregion + + #region SetAttribute + /// + /// 修改属性值 + /// + /// 元素对象 + /// 属性参数 + private static void SetAttribute(XmlElement elem, params AttributeParameter[] attps) + { + foreach (AttributeParameter attp in attps) + { + elem.SetAttribute(attp.Name, attp.Value); + } + } + /// + /// 修改属性值 + /// + /// XML参数 + /// 属性参数 + public static void SetAttribute(XmlParameter xmlParameter, params AttributeParameter[] attributeParameters) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + foreach (XmlNode xns in nlst) // 遍历所有子节点 + { + if (xns.Name == xmlParameter.Name && xns.InnerText == xmlParameter.InnerText) + { + SetAttribute((XmlElement)xns, attributeParameters); + break; + } + XmlNode tmp = GetNode(xns, xmlParameter); + if (tmp != null) + { + SetAttribute((XmlElement)tmp, attributeParameters); + break; + } + } + xDoc.Save(_xPath); + } + /// + /// 修改属性值 + /// + /// XML参数 + /// 新属性值 + public static void SetAttribute(XmlParameter xmlParameter, string attributeName, string attributeValue) + { + XmlDocument xDoc = GetXmlDom(); + XmlNodeList nlst = xDoc.DocumentElement.ChildNodes; + foreach (XmlNode xns in nlst) // 遍历所有子节点 + { + if (xns.Name == xmlParameter.Name && xns.InnerText == xmlParameter.InnerText) + { + ((XmlElement)xns).SetAttribute(attributeName, attributeValue); + break; + } + XmlNode tmp = GetNode(xns, xmlParameter); + if (tmp != null) + { + ((XmlElement)tmp).SetAttribute(attributeName, attributeValue); + break; + } + } + xDoc.Save(_xPath); + } + #endregion + } +} diff --git a/Infrastructure/Infrastructure.csproj b/Infrastructure/Infrastructure.csproj new file mode 100644 index 0000000..0a9fd22 --- /dev/null +++ b/Infrastructure/Infrastructure.csproj @@ -0,0 +1,39 @@ + + + + net6.0 + enable + + + + bin\Debug\net5.0\Infrastructure.xml + 1701;1702;1591;1573;1572;1570 + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/Infrastructure/Json.cs b/Infrastructure/Json.cs new file mode 100644 index 0000000..94d7572 --- /dev/null +++ b/Infrastructure/Json.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using System.Data; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; + +namespace Infrastructure +{ + /// + /// Json操作 + /// + public static class Json + { + public static object ToJson(this string Json) + { + return Json == null ? null : JsonConvert.DeserializeObject(Json); + } + public static string ToJson(this object obj) + { + var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }; + return JsonConvert.SerializeObject(obj, timeConverter); + } + public static string ToJson(this object obj, string datetimeformats) + { + var timeConverter = new IsoDateTimeConverter { DateTimeFormat = datetimeformats }; + return JsonConvert.SerializeObject(obj, timeConverter); + } + public static T ToObject(this string Json) + { + return Json == null ? default(T) : JsonConvert.DeserializeObject(Json); + } + public static List ToList(this string Json) + { + return Json == null ? null : JsonConvert.DeserializeObject>(Json); + } + public static DataTable ToTable(this string Json) + { + return Json == null ? null : JsonConvert.DeserializeObject(Json); + } + public static JObject ToJObject(this string Json) + { + return Json == null ? JObject.Parse("{}") : JObject.Parse(Json.Replace(" ", "")); + } + /// + /// 转换成JToken + /// + /// + /// + public static JToken ToJToken(this string str) + { + try + { + var jToken = (JToken)JsonConvert.DeserializeObject(str); + return jToken; + } + catch (Exception ex) + { + return null; + } + } + + /// + /// 检查请求参数是否异常 + /// + /// + public static void CheckReqIsNull(this object obj) + { + if (obj == null) throw new Exception("数据异常,请检查输入信息是否正确。"); + } + + /// + /// 初始化数据 + /// + /// + /// + /// + public static List InitListData(this List list) + { + if (list == null) list = new List(); + return list; + } + } +} diff --git a/Infrastructure/JsonConverter.cs b/Infrastructure/JsonConverter.cs new file mode 100644 index 0000000..fae1047 --- /dev/null +++ b/Infrastructure/JsonConverter.cs @@ -0,0 +1,61 @@ +// *********************************************************************** +// Assembly : Infrastructure +// Author : Yubao Li +// Created : 09-07-2015 +// +// Last Modified By : Yubao Li +// Last Modified On : 09-07-2015 +// *********************************************************************** +// +// Copyright (c) . All rights reserved. +// +// 解决JSON转换空GUID问题 +// *********************************************************************** + +using System; +using Newtonsoft.Json; + +namespace Infrastructure +{ + public class GuidConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return objectType.IsAssignableFrom(typeof(Guid)); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + Guid result = Guid.Empty; + if (reader.Value == null) return result; + Guid.TryParse(reader.Value.ToString(), out result); + return result; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + serializer.Serialize(writer, value); + } + } + + public class DecimalConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return objectType.IsAssignableFrom(typeof(decimal)); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + decimal result = 0; + if (reader.Value == null) return result; + decimal.TryParse(reader.Value.ToString(), out result); + return result; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + serializer.Serialize(writer, value); + } + } +} \ No newline at end of file diff --git a/Infrastructure/JsonHelper.cs b/Infrastructure/JsonHelper.cs new file mode 100644 index 0000000..3a0a2ee --- /dev/null +++ b/Infrastructure/JsonHelper.cs @@ -0,0 +1,55 @@ +// *********************************************************************** +// Assembly : FairUtility +// Author : Yubao Li +// Created : 08-12-2015 +// +// Last Modified By : Yubao Li +// Last Modified On : 08-12-2015 +// *********************************************************************** +// +// Copyright (c) . All rights reserved. +// +// json序列化帮助类 +// *********************************************************************** + +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Infrastructure +{ + public class JsonHelper + { + private static JsonHelper _jsonHelper = new JsonHelper(); + public static JsonHelper Instance { get { return _jsonHelper; } } + + public string Serialize(object obj) + { + return JsonConvert.SerializeObject(obj, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }); + } + + public string SerializeByConverter(object obj, params JsonConverter[] converters) + { + return JsonConvert.SerializeObject(obj, converters); + } + + public T Deserialize(string input) + { + return JsonConvert.DeserializeObject(input); + } + + public T DeserializeByConverter(string input,params JsonConverter[] converter) + { + return JsonConvert.DeserializeObject(input, converter); + } + + public T DeserializeBySetting(string input, JsonSerializerSettings settings) + { + return JsonConvert.DeserializeObject(input, settings); + } + + private object NullToEmpty(object obj) + { + return null; + } + } +} \ No newline at end of file diff --git a/Infrastructure/KeyDescription.cs b/Infrastructure/KeyDescription.cs new file mode 100644 index 0000000..9eca976 --- /dev/null +++ b/Infrastructure/KeyDescription.cs @@ -0,0 +1,24 @@ +namespace Infrastructure +{ + public class KeyDescription + { + /// + /// 键值 + /// + public string Key { get; set; } + /// + /// 键的描述 + /// + public string Description { get; set; } + + /// + /// 前端是否显示 + /// + public bool Browsable { get; set; } + + /// + /// 字段类型 + /// + public string Type { get; set; } + } +} diff --git a/Infrastructure/Middleware/IApplicationBuilderExtension.cs b/Infrastructure/Middleware/IApplicationBuilderExtension.cs new file mode 100644 index 0000000..cc98115 --- /dev/null +++ b/Infrastructure/Middleware/IApplicationBuilderExtension.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Builder; + +namespace Infrastructure.Middleware +{ + /// + /// + /// + public static class ApplicationBuilderExtension + { + /// + /// 注入日志中间件 + /// + /// + /// + public static IApplicationBuilder UseLogMiddleware(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } +} \ No newline at end of file diff --git a/Infrastructure/Middleware/RequestResponseLoggingMiddleware.cs b/Infrastructure/Middleware/RequestResponseLoggingMiddleware.cs new file mode 100644 index 0000000..8170759 --- /dev/null +++ b/Infrastructure/Middleware/RequestResponseLoggingMiddleware.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; + +namespace Infrastructure.Middleware +{ + /// + /// 请求与返回中间件 + /// + public class RequestResponseLoggingMiddleware + { + private readonly RequestDelegate _next; + private readonly ILogger _log; + + /// + /// + /// + public RequestResponseLoggingMiddleware(RequestDelegate next, ILogger log) + { + _next = next; + _log = log; + } + + /// + /// + /// + /// + /// + public async Task Invoke(HttpContext context) + { + #region 这里可以加入正则验证context.Path。 过滤不需要记录日志的api + + //var path = context.Request.Path.ToString().ToLower(); + + //if (path.Contains("/index") || path.Contains("/check") || + // path.Contains("/swagger") || path.Contains("/getsysdatas") || path.Contains("/load")) + //{ + await CatchNext(context); + // return; + //} + + #endregion + + #region 日志 + // 启用耗时 日志记录 + //var stopwatch = new Stopwatch(); + //stopwatch.Start(); + //var logData = new Dictionary(); + //var request = context.Request; + //logData.Add("request.url", request.Path.ToString()); + //logData.Add("request.headers", + // request.Headers.ToDictionary(x => x.Key, v => string.Join(";", v.Value.ToList()))); + //logData.Add("request.method", request.Method); + //logData.Add("request.executeStartTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); + ////追踪实别器 + //logData.Add("traceIdentifier", context.TraceIdentifier); + //// 获取请求body内容 + //if (request.Method.ToLower().Equals("post")) + //{ + // // 启用倒带功能,就可以让 Request.Body 可以再次读取 + // request.EnableBuffering(); + // // 文件上传 记录文件信息 + // if (path.Contains("/upload")) + // { + // var content = string.Join(",", request.Form.Files.Select(item => item.FileName)); + // logData.Add("request.body", $"收到上传文件:{content}"); + // } + // else + // { + // var sr = new StreamReader(request.Body, Encoding.UTF8); + // var content = sr.ReadToEndAsync().Result; + // logData.Add("request.body", content); + // request.Body.Position = 0; + // } + //} + //else if (request.Method.ToLower().Equals("get")) + //{ + // logData.Add("request.body", request.QueryString.Value); + //} + + //// 获取Response.Body内容 + //var originalBodyStream = context.Response.Body; + //using (var responseBody = new MemoryStream()) + //{ + // context.Response.Body = responseBody; + // await CatchNext(context); + // if (!logData.ContainsKey("response.body")) + // { + // logData.Add("response.body", await GetResponse(context.Response)); + // } + + // logData.Add("response.executeEndTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); + // logData.Add("response.statusCode", context.Response.StatusCode); + // await responseBody.CopyToAsync(originalBodyStream); + //} + + //// 响应完成记录时间和存入日志 + //context.Response.OnCompleted(() => + //{ + // try + // { + // stopwatch.Stop(); + // logData.Add("elapsedTime", stopwatch.ElapsedMilliseconds + "ms"); + // var json = JsonHelper.Instance.Serialize(logData); + // _log.LogInformation(json); + // return Task.CompletedTask; + // } + // catch (Exception ex) + // { + // return Task.FromException(ex); + // } + //}); + #endregion + } + + private async Task CatchNext(HttpContext context) + { + var logData = new Dictionary(); + try + { + var request = context.Request; + request.EnableBuffering(); + + // 获取请求body内容 + if (request.Method.ToLower().Equals("post")) + { + // 启用倒带功能,就可以让 Request.Body 可以再次读取 + request.EnableBuffering(); + // 文件上传 记录文件信息 + var sr = new StreamReader(request.Body, Encoding.UTF8); + var content = sr.ReadToEndAsync().Result; + logData.Add("request.body", content); + request.Body.Position = 0; + } + else if (request.Method.ToLower().Equals("get")) + { + logData.Add("request.body", request.QueryString.Value); + } + + await _next(context); + } + catch (Exception ex) + { + _log.LogError(JsonHelper.Instance.Serialize(logData)); + _log.LogError(ex, "系统错误日志,管道捕获"); + context.Response.StatusCode = 200; + context.Response.ContentType = "application/json; charset=utf-8"; + var result = new { code = 500, message = ex.Message ?? "系统错误,请稍后再试" }; + await context.Response.WriteAsync(JsonHelper.Instance.Serialize(result)); + } + } + + /// + /// 获取响应内容 + /// + /// + /// + private static async Task GetResponse(HttpResponse response) + { + response.Body.Seek(0, SeekOrigin.Begin); + var text = await new StreamReader(response.Body).ReadToEndAsync(); + response.Body.Seek(0, SeekOrigin.Begin); + return text; + } + } +} \ No newline at end of file diff --git a/Infrastructure/PredicateBuilder.cs b/Infrastructure/PredicateBuilder.cs new file mode 100644 index 0000000..c277b72 --- /dev/null +++ b/Infrastructure/PredicateBuilder.cs @@ -0,0 +1,28 @@ +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace Infrastructure +{ + public static class PredicateBuilder + { + public static Expression> True() { return f => true; } + public static Expression> False() { return f => false; } + + public static Expression> Or(this Expression> expr1, + Expression> expr2) + { + var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast()); + return Expression.Lambda> + (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); + } + + public static Expression> And(this Expression> expr1, + Expression> expr2) + { + var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast()); + return Expression.Lambda> + (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters); + } + } +} \ No newline at end of file diff --git a/Infrastructure/Provider/PathProvider.cs b/Infrastructure/Provider/PathProvider.cs new file mode 100644 index 0000000..87dbb5f --- /dev/null +++ b/Infrastructure/Provider/PathProvider.cs @@ -0,0 +1,52 @@ +using System.IO; +using Infrastructure.Extensions; +using Infrastructure.Extensions.AutofacManager; +using Microsoft.Extensions.Hosting; + +namespace Infrastructure.Provider +{ + public interface IPathProvider : IDependency + { + string MapPath(string path); + string MapPath(string path, bool rootPath); + IHostEnvironment GetHostingEnvironment(); + } + + public class PathProvider : IPathProvider + { + private IHostEnvironment _hostingEnvironment; + + public PathProvider(IHostEnvironment environment) + { + _hostingEnvironment = environment; + } + public IHostEnvironment GetHostingEnvironment() + { + return _hostingEnvironment; + } + + /// + /// 获取服务器文件路径 + /// + /// + /// + public string MapPath(string path) + { + return MapPath(path, false); + } + /// + /// 获取wwwroot路径 + /// + /// + /// 是否获取wwwroot路径 + /// + public string MapPath(string path, bool rootPath) + { + if (rootPath) + { + return Path.Combine(_hostingEnvironment.ContentRootPath,"wwwroot").ReplacePath(); + } + return Path.Combine(_hostingEnvironment.ContentRootPath, path).ReplacePath(); + } + } +} diff --git a/Infrastructure/Response.cs b/Infrastructure/Response.cs new file mode 100644 index 0000000..2e6bbab --- /dev/null +++ b/Infrastructure/Response.cs @@ -0,0 +1,45 @@ +namespace Infrastructure +{ + public class Response + { + /// + /// 操作消息【当Status不为 200时,显示详细的错误信息】 + /// + public string Message { get; set; } + + /// + /// 操作状态码,200为正常 + /// + public int Code { get; set; } + + public Response() + { + Code = 200; + Message = "操作成功"; + } + } + + public class ResponsePage : Response + { + public int Count { get; set; } + } + + public class PageInfo + { + public T Items { get; set; } + + public int Total { get; set; } + } + + /// + /// WEBAPI通用返回泛型基类 + /// + /// + public class Response : Response + { + /// + /// 回传的结果 + /// + public T Result { get; set; } + } +} diff --git a/Infrastructure/Snowflake/Contract/IIdGenerator.cs b/Infrastructure/Snowflake/Contract/IIdGenerator.cs new file mode 100644 index 0000000..3884c30 --- /dev/null +++ b/Infrastructure/Snowflake/Contract/IIdGenerator.cs @@ -0,0 +1,29 @@ +/* + * 版权属于:yitter(yitter@126.com) + * 开源地址:https://github.com/yitter/idgenerator + * 版权协议:MIT + * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 + * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 + * + */ + +using System; + +namespace Yitter.IdGenerator +{ + public interface IIdGenerator + { + /// + /// 生成过程中产生的事件 + /// + //Action GenIdActionAsync { get; set; } + + /// + /// 生成新的long型Id + /// + /// + long NewLong(); + + // Guid NewGuid(); + } +} diff --git a/Infrastructure/Snowflake/Contract/ISnowWorker.cs b/Infrastructure/Snowflake/Contract/ISnowWorker.cs new file mode 100644 index 0000000..52e6183 --- /dev/null +++ b/Infrastructure/Snowflake/Contract/ISnowWorker.cs @@ -0,0 +1,22 @@ +/* + * 版权属于:yitter(yitter@126.com) + * 开源地址:https://github.com/yitter/idgenerator + * 版权协议:MIT + * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 + * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 + * + */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Yitter.IdGenerator +{ + internal interface ISnowWorker + { + //Action GenAction { get; set; } + + long NextId(); + } +} diff --git a/Infrastructure/Snowflake/Contract/IdGeneratorOptions.cs b/Infrastructure/Snowflake/Contract/IdGeneratorOptions.cs new file mode 100644 index 0000000..ce577b7 --- /dev/null +++ b/Infrastructure/Snowflake/Contract/IdGeneratorOptions.cs @@ -0,0 +1,92 @@ +/* + * 版权属于:yitter(yitter@126.com) + * 开源地址:https://github.com/yitter/idgenerator + * 版权协议:MIT + * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 + * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 + * + */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Yitter.IdGenerator +{ + public class IdGeneratorOptions + { + /// + /// 雪花计算方法 + /// (1-漂移算法|2-传统算法),默认1 + /// + public virtual short Method { get; set; } = 1; + + /// + /// 基础时间(UTC格式) + /// 不能超过当前系统时间 + /// + public virtual DateTime BaseTime { get; set; } = new DateTime(2020, 2, 20, 2, 20, 2, 20, DateTimeKind.Utc); + + /// + /// 机器码 + /// 必须由外部设定,最大值 2^WorkerIdBitLength-1 + /// + public virtual ushort WorkerId { get; set; } = 0; + + /// + /// 机器码位长 + /// 默认值6,取值范围 [1, 15](要求:序列数位长+机器码位长不超过22) + /// + public virtual byte WorkerIdBitLength { get; set; } = 6;//10; + + /// + /// 序列数位长 + /// 默认值6,取值范围 [3, 21](要求:序列数位长+机器码位长不超过22) + /// + public virtual byte SeqBitLength { get; set; } = 6;//10; + + /// + /// 最大序列数(含) + /// 设置范围 [MinSeqNumber, 2^SeqBitLength-1],默认值0,表示最大序列数取最大值(2^SeqBitLength-1]) + /// + public virtual int MaxSeqNumber { get; set; } = 0; + + /// + /// 最小序列数(含) + /// 默认值5,取值范围 [5, MaxSeqNumber],每毫秒的前5个序列数对应编号0-4是保留位,其中1-4是时间回拨相应预留位,0是手工新值预留位 + /// + public virtual ushort MinSeqNumber { get; set; } = 5; + + /// + /// 最大漂移次数(含), + /// 默认2000,推荐范围500-10000(与计算能力有关) + /// + public virtual int TopOverCostCount { get; set; } = 2000; + + /// + /// 数据中心ID(默认0) + /// + public virtual uint DataCenterId { get; set; } = 0; + + /// + /// 数据中心ID长度(默认0) + /// + public virtual byte DataCenterIdBitLength { get; set; } = 0; + + /// + /// 时间戳类型(0-毫秒,1-秒),默认0 + /// + public virtual byte TimestampType { get; set; } = 0; + + + public IdGeneratorOptions() + { + + } + + public IdGeneratorOptions(ushort workerId) + { + WorkerId = workerId; + } + } +} diff --git a/Infrastructure/Snowflake/Contract/OverCostActionArg.cs b/Infrastructure/Snowflake/Contract/OverCostActionArg.cs new file mode 100644 index 0000000..bf46ff3 --- /dev/null +++ b/Infrastructure/Snowflake/Contract/OverCostActionArg.cs @@ -0,0 +1,57 @@ +/* + * 版权属于:yitter(yitter@126.com) + * 开源地址:https://github.com/yitter/idgenerator + * 版权协议:MIT + * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 + * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 + * + */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Yitter.IdGenerator +{ + /// + /// Id生成时回调参数 + /// + public class OverCostActionArg + { + /// + /// 事件类型 + /// 1-开始,2-结束,8-漂移 + /// + public virtual int ActionType { get; set; } + /// + /// 时间戳 + /// + public virtual long TimeTick { get; set; } + /// + /// 机器码 + /// + public virtual ushort WorkerId { get; set; } + /// + /// 漂移计算次数 + /// + public virtual int OverCostCountInOneTerm { get; set; } + /// + /// 漂移期间生产ID个数 + /// + public virtual int GenCountInOneTerm { get; set; } + /// + /// 漂移周期 + /// + public virtual int TermIndex { get; set; } + + public OverCostActionArg(ushort workerId, long timeTick, int actionType = 0, int overCostCountInOneTerm = 0, int genCountWhenOverCost = 0, int index = 0) + { + ActionType = actionType; + TimeTick = timeTick; + WorkerId = workerId; + OverCostCountInOneTerm = overCostCountInOneTerm; + GenCountInOneTerm = genCountWhenOverCost; + TermIndex = index; + } + } +} diff --git a/Infrastructure/Snowflake/Core/SnowWorkerM1.cs b/Infrastructure/Snowflake/Core/SnowWorkerM1.cs new file mode 100644 index 0000000..c71f7ee --- /dev/null +++ b/Infrastructure/Snowflake/Core/SnowWorkerM1.cs @@ -0,0 +1,379 @@ +/* + * 版权属于:yitter(yitter@126.com) + * 开源地址:https://github.com/yitter/idgenerator + * 版权协议:MIT + * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 + * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 + * + */ + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Yitter.IdGenerator +{ + /// + /// 雪花漂移算法 + /// + internal class SnowWorkerM1 : ISnowWorker + { + /// + /// 基础时间 + /// + protected readonly DateTime BaseTime; + + /// + /// 机器码 + /// + protected readonly ushort WorkerId = 0; + + /// + /// 机器码位长 + /// + protected readonly byte WorkerIdBitLength = 0; + + /// + /// 自增序列数位长 + /// + protected readonly byte SeqBitLength = 0; + + /// + /// 最大序列数(含) + /// + protected readonly int MaxSeqNumber = 0; + + /// + /// 最小序列数(含) + /// + protected readonly ushort MinSeqNumber = 0; + + /// + /// 最大漂移次数(含) + /// + protected int TopOverCostCount = 0; + + protected byte _TimestampShift = 0; + protected static object _SyncLock = new object(); + + protected ushort _CurrentSeqNumber = 0; + protected long _LastTimeTick = 0; // -1L + protected long _TurnBackTimeTick = 0; // -1L; + protected byte _TurnBackIndex = 0; + protected bool _IsOverCost = false; + protected int _OverCostCountInOneTerm = 0; + +#if DEBUG + protected int _GenCountInOneTerm = 0; + protected int _TermIndex = 0; +#endif + + public Action GenAction { get; set; } + + //private static long _StartTimeTick = 0; + //private static long _BaseTimeTick = 0; + + + public SnowWorkerM1(IdGeneratorOptions options) + { + // 1.BaseTime + if (options.BaseTime != DateTime.MinValue) + { + BaseTime = options.BaseTime; + } + + // 2.WorkerIdBitLength + if (options.WorkerIdBitLength == 0) + { + WorkerIdBitLength = 6; + } + else + { + WorkerIdBitLength = options.WorkerIdBitLength; + } + + // 3.WorkerId + WorkerId = options.WorkerId; + + // 4.SeqBitLength + if (options.SeqBitLength == 0) + { + SeqBitLength = 6; + } + else + { + SeqBitLength = options.SeqBitLength; + } + + // 5.MaxSeqNumber + if (options.MaxSeqNumber <= 0) + { + MaxSeqNumber = (1 << SeqBitLength) - 1; + } + else + { + MaxSeqNumber = options.MaxSeqNumber; + } + + // 6.MinSeqNumber + MinSeqNumber = options.MinSeqNumber; + + // 7.Others + TopOverCostCount = options.TopOverCostCount; + //if (TopOverCostCount == 0) + //{ + // TopOverCostCount = 2000; + //} + + _TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength); + _CurrentSeqNumber = options.MinSeqNumber; + + //_BaseTimeTick = BaseTime.Ticks; + //_StartTimeTick = (long)(DateTime.UtcNow.Subtract(BaseTime).TotalMilliseconds) - Environment.TickCount; + } + +#if DEBUG + private void DoGenIdAction(OverCostActionArg arg) + { + //return; + Task.Run(() => + { + GenAction(arg); + }); + } + + private void BeginOverCostAction(in long useTimeTick) + { + if (GenAction == null) + { + return; + } + + DoGenIdAction(new OverCostActionArg( + WorkerId, + useTimeTick, + 1, + _OverCostCountInOneTerm, + _GenCountInOneTerm, + _TermIndex)); + } + + private void EndOverCostAction(in long useTimeTick) + { + //if (_TermIndex > 10000) + //{ + // _TermIndex = 0; + //} + + if (GenAction == null) + { + return; + } + + DoGenIdAction(new OverCostActionArg( + WorkerId, + useTimeTick, + 2, + _OverCostCountInOneTerm, + _GenCountInOneTerm, + _TermIndex)); + } + + private void BeginTurnBackAction(in long useTimeTick) + { + if (GenAction == null) + { + return; + } + + DoGenIdAction(new OverCostActionArg( + WorkerId, + useTimeTick, + 8, + 0, + 0, + _TurnBackIndex)); + } + + private void EndTurnBackAction(in long useTimeTick) + { + if (GenAction == null) + { + return; + } + + DoGenIdAction(new OverCostActionArg( + WorkerId, + useTimeTick, + 9, + 0, + 0, + _TurnBackIndex)); + } +#endif + + protected virtual long NextOverCostId() + { + long currentTimeTick = GetCurrentTimeTick(); + + if (currentTimeTick > _LastTimeTick) + { +#if DEBUG + EndOverCostAction(currentTimeTick); + _GenCountInOneTerm = 0; +#endif + _LastTimeTick = currentTimeTick; + _CurrentSeqNumber = MinSeqNumber; + _IsOverCost = false; + _OverCostCountInOneTerm = 0; + + return CalcId(_LastTimeTick); + } + + if (_OverCostCountInOneTerm >= TopOverCostCount) + { +#if DEBUG + EndOverCostAction(currentTimeTick); + _GenCountInOneTerm = 0; +#endif + // TODO: 在漂移终止,等待时间对齐时,如果发生时间回拨较长,则此处可能等待较长时间。可优化为:在漂移终止时增加时间回拨应对逻辑。(该情况发生概率低,暂不处理) + + _LastTimeTick = GetNextTimeTick(); + _CurrentSeqNumber = MinSeqNumber; + _IsOverCost = false; + _OverCostCountInOneTerm = 0; + + return CalcId(_LastTimeTick); + } + + if (_CurrentSeqNumber > MaxSeqNumber) + { +#if DEBUG + _GenCountInOneTerm++; +#endif + _LastTimeTick++; + _CurrentSeqNumber = MinSeqNumber; + _IsOverCost = true; + _OverCostCountInOneTerm++; + + return CalcId(_LastTimeTick); + } + +#if DEBUG + _GenCountInOneTerm++; +#endif + return CalcId(_LastTimeTick); + } + + protected virtual long NextNormalId() + { + long currentTimeTick = GetCurrentTimeTick(); + + if (currentTimeTick < _LastTimeTick) + { + if (_TurnBackTimeTick < 1) + { + _TurnBackTimeTick = _LastTimeTick - 1; + + _TurnBackIndex++; + // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 + // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 + if (_TurnBackIndex > 4) + { + _TurnBackIndex = 1; + } + +#if DEBUG + BeginTurnBackAction(_TurnBackTimeTick); +#endif + } + + //Thread.Sleep(1); + return CalcTurnBackId(_TurnBackTimeTick); + } + + // 时间追平时,_TurnBackTimeTick清零 + if (_TurnBackTimeTick > 0) + { +#if DEBUG + EndTurnBackAction(_TurnBackTimeTick); +#endif + _TurnBackTimeTick = 0; + } + + if (currentTimeTick > _LastTimeTick) + { + _LastTimeTick = currentTimeTick; + _CurrentSeqNumber = MinSeqNumber; + + return CalcId(_LastTimeTick); + } + + if (_CurrentSeqNumber > MaxSeqNumber) + { +#if DEBUG + BeginOverCostAction(currentTimeTick); + _TermIndex++; + _GenCountInOneTerm = 1; +#endif + _OverCostCountInOneTerm = 1; + _LastTimeTick++; + _CurrentSeqNumber = MinSeqNumber; + _IsOverCost = true; + + return CalcId(_LastTimeTick); + } + + return CalcId(_LastTimeTick); + } + + protected virtual long CalcId(long useTimeTick) + { + var result = ((useTimeTick << _TimestampShift) + + ((long)WorkerId << SeqBitLength) + + (uint)_CurrentSeqNumber); + + _CurrentSeqNumber++; + return result; + } + + protected virtual long CalcTurnBackId(long useTimeTick) + { + var result = ((useTimeTick << _TimestampShift) + + ((long)WorkerId << SeqBitLength) + _TurnBackIndex); + + _TurnBackTimeTick--; + return result; + } + + protected virtual long GetCurrentTimeTick() + { + //return (long)(DateTime.UtcNow - BaseTime).Ticks; + //return (long)(_StartTimeTick + Environment.TickCount); + return (long)(DateTime.UtcNow - BaseTime).TotalMilliseconds; + } + + protected virtual long GetNextTimeTick() + { + long tempTimeTicker = GetCurrentTimeTick(); + + while (tempTimeTicker <= _LastTimeTick) + { + //Thread.Sleep(1); + SpinWait.SpinUntil(() => false, 1); + tempTimeTicker = GetCurrentTimeTick(); + } + + return tempTimeTicker; + } + + + public virtual long NextId() + { + lock (_SyncLock) + { + return _IsOverCost ? NextOverCostId() : NextNormalId(); + } + } + } +} diff --git a/Infrastructure/Snowflake/Core/SnowWorkerM2.cs b/Infrastructure/Snowflake/Core/SnowWorkerM2.cs new file mode 100644 index 0000000..ab2b2db --- /dev/null +++ b/Infrastructure/Snowflake/Core/SnowWorkerM2.cs @@ -0,0 +1,58 @@ +/* + * 版权属于:yitter(yitter@126.com) + * 开源地址:https://github.com/yitter/idgenerator + * 版权协议:MIT + * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 + * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 + * + */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Yitter.IdGenerator +{ + /// + /// 常规雪花算法 + /// + internal class SnowWorkerM2 : SnowWorkerM1 + { + public SnowWorkerM2(IdGeneratorOptions options) : base(options) + { + + } + + public override long NextId() + { + lock (_SyncLock) + { + long currentTimeTick = GetCurrentTimeTick(); + + if (_LastTimeTick == currentTimeTick) + { + if (_CurrentSeqNumber++ > MaxSeqNumber) + { + _CurrentSeqNumber = MinSeqNumber; + currentTimeTick = GetNextTimeTick(); + } + } + else + { + _CurrentSeqNumber = MinSeqNumber; + } + + if (currentTimeTick < _LastTimeTick) + { + throw new Exception(string.Format("Time error for {0} milliseconds", _LastTimeTick - currentTimeTick)); + } + + _LastTimeTick = currentTimeTick; + var result = ((currentTimeTick << _TimestampShift) + ((long)WorkerId << SeqBitLength) + (uint)_CurrentSeqNumber); + + return result; + } + } + + } +} diff --git a/Infrastructure/Snowflake/Core/SnowWorkerM3.cs b/Infrastructure/Snowflake/Core/SnowWorkerM3.cs new file mode 100644 index 0000000..a70e97b --- /dev/null +++ b/Infrastructure/Snowflake/Core/SnowWorkerM3.cs @@ -0,0 +1,83 @@ +/* + * 版权属于:yitter(yitter@126.com) + * 开源地址:https://github.com/yitter/idgenerator + * 版权协议:MIT + * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 + * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 + * + */ + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Yitter.IdGenerator +{ + /// + /// 雪花漂移算法(支持数据中心ID和秒级时间戳) + /// + internal class SnowWorkerM3 : SnowWorkerM1 + { + /// + /// 数据中心ID(默认0) + /// + protected readonly uint DataCenterId = 0; + + /// + /// 数据中心ID长度(默认0) + /// + protected readonly byte DataCenterIdBitLength = 0; + + /// + /// 时间戳类型(0-毫秒,1-秒),默认0 + /// + protected readonly byte TimestampType = 0; + + + public SnowWorkerM3(IdGeneratorOptions options) : base(options) + { + // 秒级时间戳类型 + TimestampType = options.TimestampType; + + // DataCenter相关 + DataCenterId = options.DataCenterId; + DataCenterIdBitLength = options.DataCenterIdBitLength; + + if (TimestampType == 1) + { + TopOverCostCount = 0; + } + _TimestampShift = (byte)(DataCenterIdBitLength + WorkerIdBitLength + SeqBitLength); + } + + protected override long CalcId(long useTimeTick) + { + var result = ((useTimeTick << _TimestampShift) + + ((long)DataCenterId << DataCenterIdBitLength) + + ((long)WorkerId << SeqBitLength) + + (long)_CurrentSeqNumber); + + _CurrentSeqNumber++; + return result; + } + + protected override long CalcTurnBackId(long useTimeTick) + { + var result = ((useTimeTick << _TimestampShift) + + ((long)DataCenterId << DataCenterIdBitLength) + + ((long)WorkerId << SeqBitLength) + + _TurnBackIndex); + + _TurnBackTimeTick--; + return result; + } + + protected override long GetCurrentTimeTick() + { + return TimestampType == 0 ? + (long)(DateTime.UtcNow - BaseTime).TotalMilliseconds : + (long)(DateTime.UtcNow - BaseTime).TotalSeconds; + } + + } +} diff --git a/Infrastructure/Snowflake/DefaultIdGenerator.cs b/Infrastructure/Snowflake/DefaultIdGenerator.cs new file mode 100644 index 0000000..26d3dba --- /dev/null +++ b/Infrastructure/Snowflake/DefaultIdGenerator.cs @@ -0,0 +1,130 @@ +/* + * 版权属于:yitter(yitter@126.com) + * 开源地址:https://github.com/yitter/idgenerator + * 版权协议:MIT + * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 + * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 + * + */ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace Yitter.IdGenerator +{ + /// + /// 默认实现 + /// + public class DefaultIdGenerator : IIdGenerator + { + private ISnowWorker _SnowWorker { get; set; } + + //public Action GenIdActionAsync + //{ + // get => _SnowWorker.GenAction; + // set => _SnowWorker.GenAction = value; + //} + + + public DefaultIdGenerator(IdGeneratorOptions options) + { + if (options == null) + { + throw new ArgumentException("options error."); + } + + // 1.BaseTime + if (options.BaseTime < DateTime.Now.AddYears(-50) || options.BaseTime > DateTime.Now) + { + throw new ArgumentException("BaseTime error."); + } + + // 2.WorkerIdBitLength + int maxLength = options.TimestampType == 0 ? 22 : 31; // (秒级时间戳时放大到31位) + if (options.WorkerIdBitLength <= 0) + { + throw new ArgumentException("WorkerIdBitLength error.(range:[1, 21])"); + } + if (options.DataCenterIdBitLength + options.WorkerIdBitLength + options.SeqBitLength > maxLength) + { + throw new ArgumentException("error:DataCenterIdBitLength + WorkerIdBitLength + SeqBitLength <= " + maxLength); + } + + // 3.WorkerId & DataCenterId + var maxWorkerIdNumber = (1 << options.WorkerIdBitLength) - 1; + if (maxWorkerIdNumber == 0) + { + maxWorkerIdNumber = 63; + } + if (options.WorkerId < 0 || options.WorkerId > maxWorkerIdNumber) + { + throw new ArgumentException("WorkerId error. (range:[0, " + maxWorkerIdNumber + "]"); + } + + var maxDataCenterIdNumber = (1 << options.DataCenterIdBitLength) - 1; + if (options.DataCenterId < 0 || options.DataCenterId > maxDataCenterIdNumber) + { + throw new ArgumentException("DataCenterId error. (range:[0, " + maxDataCenterIdNumber + "]"); + } + + // 4.SeqBitLength + if (options.SeqBitLength < 2 || options.SeqBitLength > 21) + { + throw new ArgumentException("SeqBitLength error. (range:[2, 21])"); + } + + // 5.MaxSeqNumber + var maxSeqNumber = (1 << options.SeqBitLength) - 1; + if (maxSeqNumber == 0) + { + maxSeqNumber = 63; + } + if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber) + { + throw new ArgumentException("MaxSeqNumber error. (range:[1, " + maxSeqNumber + "]"); + } + + // 6.MinSeqNumber + if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber) + { + throw new ArgumentException("MinSeqNumber error. (range:[5, " + maxSeqNumber + "]"); + } + + // 7.TopOverCostCount + if (options.TopOverCostCount < 0 || options.TopOverCostCount > 10000) + { + throw new ArgumentException("TopOverCostCount error. (range:[0, 10000]"); + } + + switch (options.Method) + { + case 2: + _SnowWorker = new SnowWorkerM2(options); + break; + default: + if (options.DataCenterIdBitLength == 0 && options.TimestampType == 0) + { + _SnowWorker = new SnowWorkerM1(options); + } + else + { + _SnowWorker = new SnowWorkerM3(options); + } + break; + } + + if (options.Method != 2) + { + Thread.Sleep(500); + } + } + + + public long NewLong() + { + return _SnowWorker.NextId(); + } + } +} diff --git a/Infrastructure/Snowflake/YitIdHelper.cs b/Infrastructure/Snowflake/YitIdHelper.cs new file mode 100644 index 0000000..d5f1baa --- /dev/null +++ b/Infrastructure/Snowflake/YitIdHelper.cs @@ -0,0 +1,53 @@ +/* + * 版权属于:yitter(yitter@126.com) + * 开源地址:https://gitee.com/yitter/idgenerator + * 版权协议:MIT + * 版权说明:只要保留本版权,你可以免费使用、修改、分发本代码。 + * 免责条款:任何因为本代码产生的系统、法律、政治、宗教问题,均与版权所有者无关。 + * + */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Yitter.IdGenerator +{ + /// + /// 这是一个调用的例子,默认情况下,单机集成者可以直接使用 NextId()。 + /// + public class YitIdHelper + { + private static IIdGenerator _IdGenInstance = null; + + public static IIdGenerator IdGenInstance => _IdGenInstance; + + /// + /// 设置参数,建议程序初始化时执行一次 + /// + /// + public static void SetIdGenerator(IdGeneratorOptions options) + { + _IdGenInstance = new DefaultIdGenerator(options); + } + + /// + /// 生成新的Id + /// 调用本方法前,请确保调用了 SetIdGenerator 方法做初始化。 + /// 否则将会初始化一个WorkerId为1的对象。 + /// + /// + public static long NextId() + { + if (_IdGenInstance == null) + { + _IdGenInstance = new DefaultIdGenerator( + new IdGeneratorOptions() { WorkerId = 1 } + ); + } + + return _IdGenInstance.NewLong(); + } + + } +} diff --git a/Infrastructure/Test/TestAutoMapper.cs b/Infrastructure/Test/TestAutoMapper.cs new file mode 100644 index 0000000..47824e9 --- /dev/null +++ b/Infrastructure/Test/TestAutoMapper.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; + +namespace Infrastructure.Test +{ + class TestAutoMapper + { + [Test] + public void TestConvert() + { + var my = new MyClass + { + Name = "yubao" + }; + + var dest = my.MapTo(); + Console.WriteLine(JsonHelper.Instance.Serialize(dest)); + } + [Test] + public void TestConvertList() + { + var users = new List { + new MyClass {Name = "yubaolee1"} + , new MyClass{Name = "yubaolee2"} + + }; + + var dest = users.MapToList(); + Console.WriteLine(JsonHelper.Instance.Serialize(dest)); + + var dest2 = users.MapToList(); + Console.WriteLine(JsonHelper.Instance.Serialize(dest2)); + + } + } + + + class MyClass + { + public string Name { get; set; } + public string NickName { get; set; } + } + + class DestClass + { + public string Name { get; set; } + public int Age { get; set; } + } +} diff --git a/Infrastructure/Test/TestDynamicLinq.cs b/Infrastructure/Test/TestDynamicLinq.cs new file mode 100644 index 0000000..ddaef10 --- /dev/null +++ b/Infrastructure/Test/TestDynamicLinq.cs @@ -0,0 +1,54 @@ +using System; +using System.Linq.Expressions; +using NUnit.Framework; + +namespace Infrastructure.Test +{ + public class TestDynamicLinq + { + [Test] + public void Convert() + { + FilterGroup sub = new FilterGroup + { + Operation = "or" + }; + sub.Filters = new[] + { + new Filter {Key = "name", Value = "name", Contrast = "=="}, + new Filter {Key = "c3", Value = "10,20,30", Contrast = "in"} + }; + + FilterGroup filterGroup = new FilterGroup + { + Operation = "and" + }; + filterGroup.Filters = new[] + { + new Filter {Key = "c1", Value = "name", Contrast = "contains"}, + new Filter {Key = "10,20,30", Value = "40", Contrast = "intersect"} + }; + + filterGroup.Children = new[] + { + sub + }; + + var expression = DynamicLinq.ConvertGroup(filterGroup, + Expression.Parameter(typeof(TestOjb), "c")); + + Console.WriteLine(expression.ToString()); + + } + } + + public class TestOjb{ + public string c1 { get; set; } + public string c2 { get; set; } + public string c3 { get; set; } + public string c4 { get; set; } + public string c5 { get; set; } + public string c6 { get; set; } + public string c7 { get; set; } + } +} \ No newline at end of file diff --git a/Infrastructure/Test/TestSnowflake.cs b/Infrastructure/Test/TestSnowflake.cs new file mode 100644 index 0000000..40aa02c --- /dev/null +++ b/Infrastructure/Test/TestSnowflake.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; +using Yitter.IdGenerator; + +namespace Infrastructure.Test +{ + class TestSnowflake + { + [Test] + public void Generate() + { + // 全局初始化设置WorkerId,默认最大2^16-1。(初始化过程全局只需一次,且必须最先设置) + var options = new IdGeneratorOptions() + { + Method = 1, + WorkerId = 1 + }; + + YitIdHelper.SetIdGenerator(options); + long newId = YitIdHelper.NextId(); + Console.WriteLine("====================================="); + Console.WriteLine("生成的 Id:" + newId); + } + + } + + +} diff --git a/Infrastructure/TreeItem.cs b/Infrastructure/TreeItem.cs new file mode 100644 index 0000000..c4db87b --- /dev/null +++ b/Infrastructure/TreeItem.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Infrastructure +{ + public class TreeItem + { + public T Item { get; set; } + public IEnumerable> Children { get; set; } + } +} \ No newline at end of file diff --git a/Infrastructure/Utilities/DESEncrypt.cs b/Infrastructure/Utilities/DESEncrypt.cs new file mode 100644 index 0000000..622db70 --- /dev/null +++ b/Infrastructure/Utilities/DESEncrypt.cs @@ -0,0 +1,104 @@ +using Infrastructure.Helpers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace Infrastructure.Utilities +{ + public static class DESEncrypt + { + private static readonly string key = "hopetry###***"; + + // + // 摘要: + // 加密 + // + // 参数: + // Text: + // 需要加密的内容 + public static string Encrypt(string Text) + { + return Encrypt(Text, key); + } + + // + // 摘要: + // 加密数据 + // + // 参数: + // Text: + // 需要加密的内容 + // + // sKey: + // 秘钥 + public static string Encrypt(string Text, string sKey) + { + DESCryptoServiceProvider dESCryptoServiceProvider = new DESCryptoServiceProvider(); + byte[] bytes = Encoding.Default.GetBytes(Text); + dESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes(Md5Helper.Hash(sKey).ToUpper().Substring(0, 8)); + dESCryptoServiceProvider.IV = Encoding.ASCII.GetBytes(Md5Helper.Hash(sKey).ToUpper().Substring(0, 8)); + MemoryStream memoryStream = new MemoryStream(); + CryptoStream cryptoStream = new CryptoStream(memoryStream, dESCryptoServiceProvider.CreateEncryptor(), CryptoStreamMode.Write); + cryptoStream.Write(bytes, 0, bytes.Length); + cryptoStream.FlushFinalBlock(); + StringBuilder stringBuilder = new StringBuilder(); + byte[] array = memoryStream.ToArray(); + foreach (byte b in array) + { + stringBuilder.AppendFormat("{0:X2}", b); + } + + return stringBuilder.ToString(); + } + + // + // 摘要: + // 解密 + // + // 参数: + // Text: + // 需要解密的内容 + public static string Decrypt(string Text) + { + if (!string.IsNullOrEmpty(Text)) + { + return Decrypt(Text, key); + } + + return ""; + } + + // + // 摘要: + // 解密数据 + // + // 参数: + // Text: + // 需要解密的内容 + // + // sKey: + // 秘钥 + public static string Decrypt(string Text, string sKey) + { + DESCryptoServiceProvider dESCryptoServiceProvider = new DESCryptoServiceProvider(); + int num = Text.Length / 2; + byte[] array = new byte[num]; + for (int i = 0; i < num; i++) + { + int num2 = Convert.ToInt32(Text.Substring(i * 2, 2), 16); + array[i] = (byte)num2; + } + + dESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes(Md5Helper.Hash(sKey).ToUpper().Substring(0, 8)); + dESCryptoServiceProvider.IV = Encoding.ASCII.GetBytes(Md5Helper.Hash(sKey).ToUpper().Substring(0, 8)); + MemoryStream memoryStream = new MemoryStream(); + CryptoStream cryptoStream = new CryptoStream(memoryStream, dESCryptoServiceProvider.CreateDecryptor(), CryptoStreamMode.Write); + cryptoStream.Write(array, 0, array.Length); + cryptoStream.FlushFinalBlock(); + return Encoding.Default.GetString(memoryStream.ToArray()); + } + } +} diff --git a/Infrastructure/Utilities/DynamicPropertyBag .cs b/Infrastructure/Utilities/DynamicPropertyBag .cs new file mode 100644 index 0000000..2e55f19 --- /dev/null +++ b/Infrastructure/Utilities/DynamicPropertyBag .cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Dynamic; +using System.IO; + +namespace Infrastructure.Utilities +{ + /// + /// 动态属性Bag + /// + public class DynamicPropertyBag : DynamicObject + { + private Dictionary storage = new Dictionary(); + + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + if (storage.ContainsKey(binder.Name)) + { + result = storage[binder.Name]; + return true; + } + result = null; + return false; + } + + public override bool TrySetMember(SetMemberBinder binder, object value) + { + string key = binder.Name; + if (storage.ContainsKey(key)) + storage[key] = value; + else + storage.Add(key, value); + return true; + } + + public override string ToString() + { + StringWriter message = new StringWriter(); + foreach (var item in storage) + message.WriteLine("{0}:\t{1}", item.Key, item.Value); + return message.ToString(); + } + } +} diff --git a/Infrastructure/Utilities/HttpContextUtil.cs b/Infrastructure/Utilities/HttpContextUtil.cs new file mode 100644 index 0000000..ef98865 --- /dev/null +++ b/Infrastructure/Utilities/HttpContextUtil.cs @@ -0,0 +1,40 @@ +using Infrastructure.Extensions.AutofacManager; +using Microsoft.AspNetCore.Http; + +namespace Infrastructure.Utilities +{ + public static class HttpContextUtil + { + private static IHttpContextAccessor _accessor=AutofacContainerModule.GetService(); + + public static Microsoft.AspNetCore.Http.HttpContext Current => _accessor.HttpContext; + + /// + /// 获取租户ID + /// + /// + public static string GetTenantId(this IHttpContextAccessor accessor) + { + string tenantId = "OpenAuthDBContext"; + + if (accessor != null && accessor.HttpContext != null) + { + //读取多租户ID + var httpTenantId = accessor.HttpContext.Request.Query[Define.TENANT_ID]; + if (string.IsNullOrEmpty(httpTenantId)) + { + httpTenantId = accessor.HttpContext.Request.Headers[Define.TENANT_ID]; + } + + //如果没有租户id,或租户用的是默认的OpenAuthDBContext,则不做任何调整 + if (!string.IsNullOrEmpty(httpTenantId)) + { + tenantId = httpTenantId; + } + } + + return tenantId; + } + + } +} diff --git a/Infrastructure/Utilities/HttpManager.cs b/Infrastructure/Utilities/HttpManager.cs new file mode 100644 index 0000000..5ed3331 --- /dev/null +++ b/Infrastructure/Utilities/HttpManager.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace Infrastructure.Utilities +{ + public class HttpManager + { + public static Task HttpPostAsync(string url, string postData = null, string contentType = null, int timeOut = 30, Dictionary headers = null) + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = "POST"; + if (!string.IsNullOrEmpty(contentType)) + { + request.ContentType = contentType; + } + if (headers != null) + { + foreach (var header in headers) + request.Headers[header.Key] = header.Value; + } + + try + { + byte[] bytes = Encoding.UTF8.GetBytes(postData ?? ""); + using (Stream sendStream = request.GetRequestStream()) + { + sendStream.Write(bytes, 0, bytes.Length); + } + + using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) + { + Stream responseStream = response.GetResponseStream(); + StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); + return streamReader.ReadToEndAsync(); + } + } + catch (Exception ex) + { + return Task.FromResult(ex.Message); + } + + } + public static Task HttpGetAsync(string url, Dictionary headers = null) + { + try + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + if (headers != null) + { + foreach (var header in headers) + request.Headers[header.Key] = header.Value; + } + using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) + { + Stream responseStream = response.GetResponseStream(); + StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); + return streamReader.ReadToEndAsync(); + } + } + catch (Exception ex) + { + return Task.FromResult(ex.Message); + } + } + } +} diff --git a/Infrastructure/Utilities/ProjectPath.cs b/Infrastructure/Utilities/ProjectPath.cs new file mode 100644 index 0000000..189f726 --- /dev/null +++ b/Infrastructure/Utilities/ProjectPath.cs @@ -0,0 +1,64 @@ +using System.IO; +using System.Linq; +using Infrastructure.Extensions; + +namespace Infrastructure.Utilities +{ + public class ProjectPath + { + /// + /// 获取web父目录所在位置 + /// + /// + public static DirectoryInfo GetProjectDirectoryInfo() + { + return GetProjectDirectoryInfo(new DirectoryInfo("".MapPath()), 1); + } + /// + /// 获取指定结尾的项目名称 + /// + /// + /// + public static string GetLastIndexOfDirectoryName(string lastIndexOfName) + { + string projectName = GetProjectDirectoryInfo()?.GetDirectories() + .Where(c => c.Name.LastIndexOf(lastIndexOfName) != -1).Select(x => x.Name).FirstOrDefault(); + if (string.IsNullOrEmpty(projectName)) + { + projectName = new DirectoryInfo("".MapPath()).GetFiles().Where(x => x.Name.LastIndexOf(lastIndexOfName + ".dll") != -1).FirstOrDefault().Name; + if (!string.IsNullOrEmpty(projectName)) + { + projectName = projectName.Replace(".dll", ""); + } + } + return projectName; + } + /// + /// 获取项目所在路径 + /// + /// + /// + private static DirectoryInfo GetProjectDirectoryInfo(DirectoryInfo directoryInfo, int findCount) + { + if (directoryInfo == null) + { + return null; + } + if (directoryInfo.Exists + && directoryInfo.GetDirectories().Where(x => x.Name.LastIndexOf(".App") != -1).FirstOrDefault() != null) + { + return directoryInfo; + } + if (findCount < 7) + { + findCount++; + DirectoryInfo dir = GetProjectDirectoryInfo(directoryInfo.Parent, findCount); + if (dir != null) + { + return dir; + } + } + return null; + } + } +} diff --git a/Infrastructure/Utilities/ResponseMsg.cs b/Infrastructure/Utilities/ResponseMsg.cs new file mode 100644 index 0000000..4a7ed46 --- /dev/null +++ b/Infrastructure/Utilities/ResponseMsg.cs @@ -0,0 +1,59 @@ +using Infrastructure.Const; + + namespace Infrastructure.Utilities +{ + public static class ResponseMsg + { + public static string GetMsg(this ResponseType responseType) + { + string msg; + switch (responseType) + { + case ResponseType.LoginExpiration: + msg = "登陆已过期,请重新登陆"; break; + case ResponseType.TokenExpiration: + msg = "Token已过期,请重新登陆"; break; + case ResponseType.AccountLocked: + msg = "帐号已被锁定"; break; + case ResponseType.LoginSuccess: + msg = "登陆成功"; break; + case ResponseType.ParametersLack: + msg = "参数不完整"; break; + case ResponseType.NoPermissions: + msg = "没有权限操作"; break; + case ResponseType.NoRolePermissions: + msg = "角色没有权限操作"; break; + case ResponseType.ServerError: + msg = "服务器好像出了点问题....."; break; + case ResponseType.LoginError: + msg = "用户名或密码错误"; break; + case ResponseType.SaveSuccess: + msg = "保存成功"; break; + case ResponseType.NoKey: + msg = "没有主键不能编辑"; break; + case ResponseType.NoKeyDel: + msg = "没有主键不能删除"; break; + case ResponseType.KeyError: + msg = "主键不正确或没有传入主键"; break; + case ResponseType.EidtSuccess: + msg = "编辑成功"; break; + case ResponseType.DelSuccess: + msg = "删除成功"; break; + case ResponseType.RegisterSuccess: + msg = "注册成功"; break; + case ResponseType.AuditSuccess: + msg = "审核成功"; break; + case ResponseType.ModifyPwdSuccess: + msg = "密码修改成功"; break; + case ResponseType.OperSuccess: + msg = "操作成功"; break; + case ResponseType.PINError: + msg = "验证码不正确"; break; + + default: msg = responseType.ToString(); break; + } + return msg; + } + + } +} diff --git a/Infrastructure/Utilities/UriUtil.cs b/Infrastructure/Utilities/UriUtil.cs new file mode 100644 index 0000000..b931c9d --- /dev/null +++ b/Infrastructure/Utilities/UriUtil.cs @@ -0,0 +1,62 @@ +// *********************************************************************** +// Assembly : Infrastructure +// Author : yubaolee +// Created : 06-21-2016 +// +// Last Modified By : yubaolee +// Last Modified On : 06-22-2016 +// Contact : +// File: UriUtil.cs +// *********************************************************************** + +using System; +using System.Collections.Specialized; +using System.Web; + +namespace Infrastructure.Utilities +{ + /// + /// URl帮助类 + /// + public class UriUtil + { + /// + /// 在URL后面追加参数 + /// + /// + /// + /// + /// + public static string GetAppendedQueryString(string url, string key, string value) + { + if (url.Contains("?")) + { + url = string.Format("{0}&{1}={2}", url, key, value); + } + else + { + url = string.Format("{0}?{1}={2}", url, key, value); + } + + return url; + } + + public static string RemoveParameter(string url, string key) + { + + url = url.ToLower(); + key = key.ToLower(); + if (!url.Contains(key + "=")) return url; + + Uri uri = new Uri(url); + NameValueCollection collection = HttpUtility.ParseQueryString(uri.Query); + if (collection.Count == 0) return url; + + var val = collection[key]; + string fragmentToRemove = string.Format("{0}={1}",key , val); + + String result = url.ToLower().Replace("&" + fragmentToRemove, string.Empty).Replace("?" + fragmentToRemove, string.Empty); + return result; + } + } +} \ No newline at end of file diff --git a/Infrastructure/Utilities/WebResponseContent.cs b/Infrastructure/Utilities/WebResponseContent.cs new file mode 100644 index 0000000..644704a --- /dev/null +++ b/Infrastructure/Utilities/WebResponseContent.cs @@ -0,0 +1,81 @@ +using Infrastructure.Const; + +namespace Infrastructure.Utilities +{ + public class WebResponseContent : Response + { + public WebResponseContent() + { + Code = 200; + Message = "操作成功"; + } + public WebResponseContent(bool status) + { + this.Status = status; + } + public bool Status { get; set; } + public object Result { get; set; } + + public WebResponseContent OK() + { + this.Status = true; + return this; + } + + public static WebResponseContent Instance + { + get { return new WebResponseContent(); } + } + public WebResponseContent OK(string message = null,object data=null) + { + this.Status = true; + this.Message = message; + this.Result = data; + return this; + } + public WebResponseContent OK(ResponseType responseType) + { + return Set(responseType, true); + } + public WebResponseContent Error(string message = null) + { + this.Status = false; + this.Message = message; + return this; + } + public WebResponseContent Error(ResponseType responseType) + { + return Set(responseType, false); + } + public WebResponseContent Set(ResponseType responseType) + { + bool? b = null; + return this.Set(responseType, b); + } + public WebResponseContent Set(ResponseType responseType, bool? status) + { + return this.Set(responseType, null, status); + } + public WebResponseContent Set(ResponseType responseType, string msg) + { + bool? b = null; + return this.Set(responseType, msg, b); + } + public WebResponseContent Set(ResponseType responseType, string msg, bool? status) + { + if (status != null) + { + this.Status = (bool)status; + } + this.Code = (int)responseType; + if (!string.IsNullOrEmpty(msg)) + { + Message = msg; + return this; + } + Message = responseType.GetMsg(); + return this; + } + + } +} diff --git a/Infrastructure/log4net.config b/Infrastructure/log4net.config new file mode 100644 index 0000000..dc7a861 --- /dev/null +++ b/Infrastructure/log4net.config @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenAuth.App/AuthContextFactory.cs b/OpenAuth.App/AuthContextFactory.cs new file mode 100644 index 0000000..759b791 --- /dev/null +++ b/OpenAuth.App/AuthContextFactory.cs @@ -0,0 +1,48 @@ +using Infrastructure; +using OpenAuth.Repository; +using SqlSugar; + +namespace OpenAuth.App +{ + /// + /// 加载用户所有可访问的资源/机构/模块 + /// 李玉宝新增于2016-07-19 10:53:30 + /// + public class AuthContextFactory + { + private SystemAuthStrategy _systemAuth; + private NormalAuthStrategy _normalAuthStrategy; + private readonly ISugarUnitOfWork _unitWork; + + public AuthContextFactory(SystemAuthStrategy sysStrategy + , NormalAuthStrategy normalAuthStrategy + , ISugarUnitOfWork unitWork) + { + _systemAuth = sysStrategy; + _normalAuthStrategy = normalAuthStrategy; + _unitWork = unitWork; + } + + public AuthStrategyContext GetAuthStrategyContext(string username) + { + if (string.IsNullOrEmpty(username)) return null; + + IAuthStrategy service = null; + if (username == Define.SYSTEM_USERNAME) + { + service = _systemAuth; + } + else + { + service = _normalAuthStrategy; + //unitWork 是否自己释放 + using (var uow = _unitWork.CreateContext()) + { + service.User = uow.User.GetFirst(u => u.Account == username); + } + } + + return new AuthStrategyContext(service); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/AutofacExt.cs b/OpenAuth.App/AutofacExt.cs new file mode 100644 index 0000000..838e004 --- /dev/null +++ b/OpenAuth.App/AutofacExt.cs @@ -0,0 +1,104 @@ +using System.Reflection; +using System.Runtime.Loader; +using Autofac; +using Autofac.Extras.Quartz; +using ce.autofac.extension; +using Infrastructure.Cache; +using Infrastructure.Extensions.AutofacManager; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyModel; +using OpenAuth.App.Interface; +using OpenAuth.App.SSO; +using OpenAuth.Repository; +using SqlSugar; + +namespace OpenAuth.App +{ + public static class AutofacExt + { + public static void InitAutofac(ContainerBuilder builder) + { + //注册数据库基础操作和工作单元 + builder.RegisterGeneric(typeof(SugarRepositiry<>)).As(typeof(ISimpleClient<>)).InstancePerLifetimeScope(); + //builder.RegisterGeneric(typeof(SimpleClient<>)).As(typeof(ISimpleClient<>)).InstancePerLifetimeScope(); + //builder.RegisterGeneric(typeof(SugarRepositiry<>)).As(typeof(ISugarRepositiry<>)).InstancePerLifetimeScope(); + //builder.RegisterGeneric(typeof(SugarUnitOfWork<>)).As(typeof(ISugarUnitOfWork<>)).InstancePerLifetimeScope(); + + //注入授权 + builder.RegisterType(typeof(LocalAuth)).As(typeof(IAuth)).InstancePerLifetimeScope(); + + //注册app层 + builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).InstancePerLifetimeScope(); + + builder.RegisterType(typeof(RedisCacheContext)).As(typeof(ICacheContext)).InstancePerLifetimeScope(); + //builder.RegisterType(typeof(CacheContext)).As(typeof(ICacheContext)); + builder.RegisterType(typeof(HttpContextAccessor)).As(typeof(IHttpContextAccessor)) + .InstancePerLifetimeScope(); + try + { + foreach (Assembly assembly in ce.autofac.extension.Extensions.GetAssemblies()) + { + foreach (Type type in assembly.GetTypes().Where((Func)(t => + typeof(IBLL).IsAssignableFrom(t) && + t.GetCustomAttribute() != null))) + { + BLLNameAttribute customAttribute = type.GetCustomAttribute(); + Type serviceType = + type.GetInterfaces().FirstOrDefault( + (Func)(t => typeof(IBLL).IsAssignableFrom(t))); + if (serviceType != null) + { + builder.RegisterType(type).AsImplementedInterfaces() + .Named(customAttribute.BLLName, serviceType); + builder.RegisterType(type).Named(customAttribute.BLLName, type); + } + } + } + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + + InitDependency(builder); + + builder.RegisterModule(new QuartzAutofacFactoryModule()); + } + + + /// + /// 注入所有继承了IDependency接口 + /// + /// + private static void InitDependency(ContainerBuilder builder) + { + Type baseType = typeof(IDependency); + var compilationLibrary = DependencyContext.Default + .CompileLibraries + .Where(x => !x.Serviceable + && x.Type == "project") + .ToList(); + var count1 = compilationLibrary.Count; + List assemblyList = new List(); + + foreach (var _compilation in compilationLibrary) + { + try + { + assemblyList.Add( + AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(_compilation.Name))); + } + catch (Exception ex) + { + Console.WriteLine(_compilation.Name + ex.Message); + } + } + + builder.RegisterAssemblyTypes(assemblyList.ToArray()) + .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract) + .AsSelf().AsImplementedInterfaces() + .InstancePerLifetimeScope(); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/AppManager/AppManager.cs b/OpenAuth.App/BaseApp/AppManager/AppManager.cs new file mode 100644 index 0000000..ff95b0f --- /dev/null +++ b/OpenAuth.App/BaseApp/AppManager/AppManager.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + /// + /// 分类管理 + /// + public class AppManager : SqlSugarBaseApp + { + + public AppManager(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + + } + + public void Add(SysApplication Application) + { + if (Application.Id==0) + { + Application.Id = Yitter.IdGenerator.YitIdHelper.NextId(); + } + + Repository.Insert(Application); + } + + public void Update(SysApplication Application) + { + Repository.Update(Application); + } + + + public async Task> GetList(QueryAppListReq request) + { + return await Repository.GetListAsync(); + } + + + public SysApplication GetByAppKey(string modelAppKey) + { + return Repository.GetFirst(u => u.AppSecret == modelAppKey); + } + + public void Delete(string[] ids) + { + Repository.DeleteByIds(ids); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/AppManager/Request/QueryAppListReq.cs b/OpenAuth.App/BaseApp/AppManager/Request/QueryAppListReq.cs new file mode 100644 index 0000000..20081a0 --- /dev/null +++ b/OpenAuth.App/BaseApp/AppManager/Request/QueryAppListReq.cs @@ -0,0 +1,7 @@ +namespace OpenAuth.App.Request +{ + public class QueryAppListReq : PageReq + { + + } +} diff --git a/OpenAuth.App/BaseApp/AuthStrategies/AuthStrategyContext.cs b/OpenAuth.App/BaseApp/AuthStrategies/AuthStrategyContext.cs new file mode 100644 index 0000000..e92db63 --- /dev/null +++ b/OpenAuth.App/BaseApp/AuthStrategies/AuthStrategyContext.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using Infrastructure; +using OpenAuth.App.Response; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.App +{ + /// + /// 授权策略上下文,一个典型的策略模式 + /// + public class AuthStrategyContext + { + private readonly IAuthStrategy _strategy; + public AuthStrategyContext(IAuthStrategy strategy) + { + this._strategy = strategy; + } + + public SysUser User + { + get { return _strategy.User; } + } + + public List Modules + { + get { return _strategy.Modules; } + } + + public List ModuleElements + { + get { return _strategy.ModuleElements; } + } + + public List Roles + { + get { return _strategy.Roles; } + } + + public List Resources + { + get { return _strategy.Resources; } + } + + public List Orgs + { + get { return _strategy.Orgs; } + } + + public List Positions + { + get { return _strategy.Positions; } + } + } + +} diff --git a/OpenAuth.App/BaseApp/AuthStrategies/NormalAuthStrategy.cs b/OpenAuth.App/BaseApp/AuthStrategies/NormalAuthStrategy.cs new file mode 100644 index 0000000..9ddec30 --- /dev/null +++ b/OpenAuth.App/BaseApp/AuthStrategies/NormalAuthStrategy.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Infrastructure; +using Infrastructure.Extensions; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.BasicQueryService; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using StackExchange.Redis; + +namespace OpenAuth.App +{ + /// + /// 普通用户授权策略 + /// + public class NormalAuthStrategy : SqlSugarBaseApp, IAuthStrategy + { + ISqlSugarClient client; + UserManager manager; + protected SysUser _user; + private List _userRoleIds; //用户角色ID + + public NormalAuthStrategy( + ISugarUnitOfWork unitWork, + ISimpleClient repository, + UserManager userManager + ) : base(unitWork, repository, null) + { + client = base.Repository.AsSugarClient(); + manager = userManager; + } + + + + public List Modules + { + get + { + //var moduleIds = Repository.ChangeRepository>().GetList( + // u => + // (_userRoleIds.Contains(u.RoleId))).Select(u => u.ModuleId); + //var modules = Repository.ChangeRepository>().AsQueryable().Where(u => moduleIds.Contains(u.Id)) + // .Select(module => new ModuleView + // { + // SortNo = module.SortNo, + // Name = module.Name, + // Code = module.Code, + // CascadeId = module.CascadeId, + // Id = module.Id, + // IconName = module.IconName, + // Url = module.Url, + // ParentId = module.ParentId, + // ParentName = module.ParentName, + // IsSys = module.IsSys, + // Status = module.Status + // }).ToList(); + + var modules = manager.RoleModules(_userRoleIds).Distinct().OrderBy((r, m) => m.SortNo).Select().ToList(); + + var usermoduleelements = ModuleElements; + + foreach (var module in modules) + { + module.Elements = usermoduleelements.Where(u => u.ModuleId == module.Id).DistinctBy(u=>u.Id).ToList(); + } + + return modules; + } + } + + public List ModuleElements + { + get + { + return manager.RoleModuleElements(_userRoleIds).OrderBy((r, m) => m.Sort).Select((r, m) => m).ToList(); + } + } + + public List Roles + { + get { return manager.UserRoles(_user.Id).Select((u, r) => r).ToList(); } + } + + public List Resources + { + get + { + var resourceIds = base.Repository.ChangeRepository>() + .GetList(u => _userRoleIds.Contains(u.RoleId)).Select(u => u.ResourceId); + return base.Repository.ChangeRepository>().GetList(u => resourceIds.Contains(u.Id)).ToList(); + } + } + + public List Orgs + { + get + { + return manager.UserOrgs(_user.Id).Select((u, o) => o).ToList(); + } + } + + public List Positions + { + get { return manager.UserPositons(_user.Id).Select((u, p) => p).ToList(); } + } + + public SysUser User + { + get { return _user; } + set + { + _user = value; + _userRoleIds = manager.UserRoles(_user.Id).Select((u, r) => r.Id).ToList(); + } + } + + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/AuthStrategies/SystemAuthStrategy.cs b/OpenAuth.App/BaseApp/AuthStrategies/SystemAuthStrategy.cs new file mode 100644 index 0000000..648275e --- /dev/null +++ b/OpenAuth.App/BaseApp/AuthStrategies/SystemAuthStrategy.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Infrastructure; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + /// + /// 领域服务 + /// 超级管理员权限 + /// 超级管理员使用-1,可以根据需要修改 + /// + public class SystemAuthStrategy : SqlSugarBaseApp, IAuthStrategy + { + protected SysUser _user; + + public List Modules + { + get + { + return Repository.ChangeRepository>().AsQueryable() + .Includes(a => a.Elements) + .Select(a => new ModuleView + { + Elements = a.Elements + }, true) + .ToList(); + } + } + + public List Roles + { + get { return Repository.ChangeRepository>().GetList(); } + } + + public List ModuleElements + { + get { return Repository.ChangeRepository>().GetList(); } + } + + public List Resources + { + get { return Repository.ChangeRepository>().GetList(); } + } + + public List Orgs + { + get { return Repository.ChangeRepository>().GetList(); } + } + + public List Positions + { + get { return Repository.ChangeRepository>().GetList(); } + } + + public SysUser User + { + get { return _user; } + set //禁止外部设置 + { + throw new Exception("超级管理员,禁止设置用户"); + } + } + + + + public SystemAuthStrategy(ISugarUnitOfWork unitWork, ISimpleClient repository) : base(unitWork, repository, null) + { + _user = new SysUser + { + Account = Define.SYSTEM_USERNAME, + Name = "超级管理员", + Id = -1 + }; + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Base/IdRequest.cs b/OpenAuth.App/BaseApp/Base/IdRequest.cs new file mode 100644 index 0000000..6f08a2e --- /dev/null +++ b/OpenAuth.App/BaseApp/Base/IdRequest.cs @@ -0,0 +1,14 @@ +namespace OpenAuth.App.Request +{ + /// + /// 请求参数中只有Id + /// + /// + public class IdRequest + { + /// + /// 操作Id + /// + public T Id { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/Base/PageReq.cs b/OpenAuth.App/BaseApp/Base/PageReq.cs new file mode 100644 index 0000000..8fcc1c7 --- /dev/null +++ b/OpenAuth.App/BaseApp/Base/PageReq.cs @@ -0,0 +1,24 @@ +namespace OpenAuth.App.Request +{ + public class PageReq + { + /// + /// 页码 + /// + /// 1 + public int page { get; set; } + /// + /// 每页条数 + /// + /// 10 + public int limit { get; set; } + + public string key { get; set; } + + public PageReq() + { + page = 1; + limit = 10; + } + } +} diff --git a/OpenAuth.App/BaseApp/Base/SqlSugarBaseApp.cs b/OpenAuth.App/BaseApp/Base/SqlSugarBaseApp.cs new file mode 100644 index 0000000..7817199 --- /dev/null +++ b/OpenAuth.App/BaseApp/Base/SqlSugarBaseApp.cs @@ -0,0 +1,122 @@ +using Microsoft.Extensions.Configuration; +using OpenAuth.App.FormScheme.FormHelpers; +using OpenAuth.App.Interface; +using SqlSugar; + +namespace OpenAuth.App.BaseApp.Base +{ + public abstract class SqlSugarBaseApp + where T : class, new() + where TDbContext : SugarUnitOfWork, new() + { + + /// + /// 用于普通的数据库操作 + /// + protected ISimpleClient Repository; + /// + /// 用于事务操作 + /// + protected ISugarUnitOfWork UnitWork; + + protected IAuth _auth; + + + public SqlSugarBaseApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) + { + UnitWork = unitWork; + Repository = repository; + _auth = auth; + } + + public SqlSugarClient CodeClient(string code, IConfiguration config) + { + if (string.IsNullOrEmpty(code) || code == "hcsystemdb") + { + return new SqlSugarClient(new ConnectionConfig() + { + DbType = SqlSugar.DbType.PostgreSQL, + ConnectionString = config.GetConnectionString("OpenAuthDBContext"), + IsAutoCloseConnection = true, + MoreSettings = new SqlSugar.ConnMoreSettings() + { + //PgSqlIsAutoToLower = false, + //PgSqlIsAutoToLowerCodeFirst = false, + IsAutoToUpper = false, + + DatabaseModel = DbType.PostgreSQL + } + }, + db => + { + //单例参数配置,所有上下文生效 + db.Aop.OnLogExecuting = (sql, pars) => + { + //Console.WriteLine(sql + "\r\n" + + //db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value))); + //Console.WriteLine(); + }; + }); + } + else + { + var link = UnitWork.Db.Queryable().Where(r => r.DBName == code).First(); + if (link != null) + { + return new SqlSugarClient(new ConnectionConfig() + { + DbType = DBCommonHelper.GetDbType(link.DBType), + ConnectionString = link.DBConnection, + IsAutoCloseConnection = true, + MoreSettings = new SqlSugar.ConnMoreSettings() + { + //PgSqlIsAutoToLower = false, + //PgSqlIsAutoToLowerCodeFirst = false, + IsAutoToUpper = false, + + DatabaseModel = DbType.PostgreSQL + } + }, + db => + { + //单例参数配置,所有上下文生效 + db.Aop.OnLogExecuting = (sql, pars) => + { + //Console.WriteLine(sql + "\r\n" + + //db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value))); + //Console.WriteLine(); + }; + }); + } + else + { + throw new Exception("此编码找不到对应数据库:" + code); + } + } + } + + public SqlSugarClient TestLinkClient(string conn, string dbtype) + { + var client = new SqlSugarClient(new ConnectionConfig() + { + DbType = DBCommonHelper.GetDbType(dbtype), + ConnectionString = conn, + IsAutoCloseConnection = true, + MoreSettings = new SqlSugar.ConnMoreSettings() + { + IsAutoToUpper = false, + DatabaseModel = DbType.PostgreSQL + } + }, + db => + { + //单例参数配置,所有上下文生效 + db.Aop.OnLogExecuting = (sql, pars) => + { + }; + }); + return client; + } + + } +} diff --git a/OpenAuth.App/BaseApp/Base/TableData.cs b/OpenAuth.App/BaseApp/Base/TableData.cs new file mode 100644 index 0000000..7318adf --- /dev/null +++ b/OpenAuth.App/BaseApp/Base/TableData.cs @@ -0,0 +1,33 @@ + +namespace OpenAuth.App.Response +{ + /// + /// table的返回数据 + /// + public class TableData + { + /// + /// 状态码 + /// + public int code { get; set; } + /// + /// 操作消息 + /// + public string msg { get; set; } + + /// + /// 总记录条数 + /// + public int count { get; set; } + /// + /// 数据内容 + /// + public dynamic data { get; set; } + + public TableData() + { + code = 200; + msg = "加载成功"; + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Base/TableResp.cs b/OpenAuth.App/BaseApp/Base/TableResp.cs new file mode 100644 index 0000000..08cae99 --- /dev/null +++ b/OpenAuth.App/BaseApp/Base/TableResp.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using Infrastructure; + +namespace OpenAuth.App.Response +{ + /// + /// 返回确定类型的表格数据,可以为swagger提供精准的注释 + /// + public class TableResp + { + /// + /// 状态码 + /// + public int code { get; set; } + /// + /// 操作消息 + /// + public string msg { get; set; } + + /// + /// 总记录条数 + /// + public int count { get; set; } + + /// + /// 数据内容 + /// + public List data { get; set; } + + /// + /// 返回的列表头信息 + /// + public List columnHeaders { get; set; } + + public TableResp() + { + code = 200; + msg = "加载成功"; + columnHeaders = new List(); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Base/Tree/LongTreeApp.cs b/OpenAuth.App/BaseApp/Base/Tree/LongTreeApp.cs new file mode 100644 index 0000000..23c88f9 --- /dev/null +++ b/OpenAuth.App/BaseApp/Base/Tree/LongTreeApp.cs @@ -0,0 +1,31 @@ +using System.Linq; +using Infrastructure; +using OpenAuth.App.Interface; +using OpenAuth.Repository; +using OpenAuth.Repository.Core; +using SqlSugar; + +namespace OpenAuth.App.Base +{ + public class LongTreeApp : TreeApp + where T : TreeEntity, new() + where TDbContext : SugarUnitOfWork, new() + { + public LongTreeApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) + : base(unitWork, repository, auth) + { + } + + protected override long GetDefaultId() + { + + return 0; // Define your default Id value for long type + } + + protected override string GetDefaultCascadeId() + { + return ""; + //return "0."; // Define your default CascadeId value for long type + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Base/Tree/StringTreeApp.cs b/OpenAuth.App/BaseApp/Base/Tree/StringTreeApp.cs new file mode 100644 index 0000000..787b2cf --- /dev/null +++ b/OpenAuth.App/BaseApp/Base/Tree/StringTreeApp.cs @@ -0,0 +1,35 @@ +using Infrastructure.Extensions; +using OpenAuth.App.Interface; +using OpenAuth.Repository; +using OpenAuth.Repository.Core; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Base +{ + public class StringTreeApp : TreeApp + where T : TreeEntity, new() + where TDbContext : SugarUnitOfWork, new() + { + public StringTreeApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) + : base(unitWork, repository, auth) + { + } + + protected override string GetDefaultId() + { + return "0"; + /* return ""; */// Define your default Id value for string type + } + + protected override string GetDefaultCascadeId() + { + var max = base.Repository.AsSugarClient().Queryable().Where(a => a.ParentId == "0").Max(a => SqlFunc.ToInt32(a.CascadeId)); + return (max+1).ToString(); // Define your default CascadeId value for string type + } + } +} diff --git a/OpenAuth.App/BaseApp/Base/Tree/TreeApp.cs b/OpenAuth.App/BaseApp/Base/Tree/TreeApp.cs new file mode 100644 index 0000000..2f50aed --- /dev/null +++ b/OpenAuth.App/BaseApp/Base/Tree/TreeApp.cs @@ -0,0 +1,146 @@ +using DocumentFormat.OpenXml.EMMA; +using Infrastructure.Extensions; +using OpenAuth.App.Interface; +using OpenAuth.Repository; +using OpenAuth.Repository.Core; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App.Base +{ + public abstract class TreeApp : SqlSugarBaseApp + where T : TreeEntity, new() + where TDbContext : SugarUnitOfWork, new() + { + protected TreeApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + } + + protected abstract TIdType GetDefaultId(); + protected abstract string GetDefaultCascadeId(); + + protected virtual void CalculateCascade(T entity) + { + if (EqualityComparer.Default.Equals(entity.ParentId, GetDefaultId())) + { + var entityType = entity.GetType(); + var baseType = entityType.BaseType; + + if (baseType == typeof(TreeEntity)) + { + var parentIdProperty = entityType.GetProperty("ParentId"); + parentIdProperty.SetValue(entity, "0", null); + } + else + { + entity.ParentId = default; + } + + //entity.ParentId = default; + + } + + string cascadeId; + int currentCascadeId = 1; + var sameLevels = GetSameLevelEntities(entity); + + foreach (var obj in sameLevels) + { + int objCascadeId = int.Parse(obj.CascadeId.TrimEnd('.').Split('.').Last()); + currentCascadeId = Math.Max(currentCascadeId, objCascadeId + 1); + } + + + + + + //if (!EqualityComparer.Default.Equals(entity.ParentId, GetDefaultId())) + //{ + // var parentOrg = GetParentOrganization(entity.ParentId); + // cascadeId = parentOrg.CascadeId + currentCascadeId; + // entity.ParentName = parentOrg.Name; + //} + if (!Object.Equals(entity.ParentId, GetDefaultId())) + { + var parentOrg = GetParentOrganization(entity.ParentId); + cascadeId = parentOrg.CascadeId + "." + currentCascadeId; + entity.ParentName = parentOrg.Name; + } + else + { + //cascadeId = GetDefaultCascadeId() + currentCascadeId + "."; + //cascadeId = GetDefaultCascadeId() + currentCascadeId; + cascadeId = GetDefaultCascadeId(); + entity.ParentName = "根节点"; + } + + entity.CascadeId = cascadeId; + } + + //protected virtual IEnumerable GetSameLevelEntities(T entity) + //{ + // return Repository + // .ChangeRepository>() + // .GetList(o => EqualityComparer.Default.Equals(o.ParentId, entity.ParentId) && !o.Id.Equals(entity.Id)); + //} + + protected virtual IEnumerable GetSameLevelEntities(T entity) + { + var parentId = entity.ParentId; + return Repository + .ChangeRepository>() + .GetList(o => Object.Equals(o.ParentId, parentId) && !o.Id.Equals(entity.Id)); + } + + + protected virtual T GetParentOrganization(TIdType parentId) + { + //var parentOrg = Repository + // .ChangeRepository>() + // .GetFirst(o => EqualityComparer.Default.Equals(o.Id, parentId)); + + var parentOrg = Repository + .ChangeRepository>() + .GetFirst(o => Object.Equals(o.Id, parentId)); + + + if (parentOrg == null) + { + throw new Exception("未能找到该组织的父节点信息"); + } + + return parentOrg; + } + + public void UpdateTreeObj(T obj) + { + //CalculateCascade(obj); + + //var cascadeId = Repository.GetFirst(o => object.Equals(o.Id, obj.Id)).CascadeId; + //var objs = Repository.GetList(u => u.CascadeId.Contains(cascadeId) && !object.Equals(u.Id, obj.Id)) + // .OrderBy(u => u.CascadeId).ToList(); + + Repository.Update(obj); + + //foreach (var a in objs) + //{ + // a.CascadeId = a.CascadeId.Replace(cascadeId, obj.CascadeId); + // if (EqualityComparer.Default.Equals(a.ParentId, obj.Id)) + // { + // a.ParentName = obj.Name; + // } + + // Repository.Update(a); + //} + } + + + } +} diff --git a/OpenAuth.App/BaseApp/Base/Tree/TreeExtensions.cs b/OpenAuth.App/BaseApp/Base/Tree/TreeExtensions.cs new file mode 100644 index 0000000..445a016 --- /dev/null +++ b/OpenAuth.App/BaseApp/Base/Tree/TreeExtensions.cs @@ -0,0 +1,53 @@ +using OpenAuth.Repository.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Base.Tree +{ + public static class TreeExtensions + { + public static IEnumerable BuildTree(this List nodes, long? parentId = null) + { + var rootNodes = nodes + .Where(n => n.ParentId == parentId || (parentId == null && (n.ParentId == null || !nodes.Any(child => child.Id == n.ParentId)))); + + foreach (var rootNode in rootNodes) + { + yield return new TreeItemLong + { + Id = rootNode.Id, + Name = rootNode.Name, + ParentId = rootNode.ParentId, + Level = rootNode.Level, + Children = nodes.BuildTree(rootNode.Id).ToList() + }; + } + } + + + + + public static List BuildTree1(this List nodes, long? parentId = null) + { + var result = new List(); + + foreach (var node in nodes.Where(n => n.ParentId == parentId)) + { + var newNode = new TreeItemLong + { + Id = node.Id, + Name = node.Name, + ParentId = node.ParentId, + Children = nodes.BuildTree1(node.Id) + }; + + result.Add(newNode); + } + + return result; + } + } +} diff --git a/OpenAuth.App/BaseApp/BasicQueryService/CommonDataManager.cs b/OpenAuth.App/BaseApp/BasicQueryService/CommonDataManager.cs new file mode 100644 index 0000000..9e4240f --- /dev/null +++ b/OpenAuth.App/BaseApp/BasicQueryService/CommonDataManager.cs @@ -0,0 +1,365 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.BasicQueryService +{ + public class CommonDataManager + { + ISqlSugarClient client; + + public CommonDataManager(ISqlSugarClient client) + { + this.client = client; + } + + /// + /// wkt转geom数据 + /// + /// + /// + /// + public string WktToGeometry(string wkt, int wkid) + { + StringBuilder geomsql = new StringBuilder(); + geomsql.AppendFormat(" SELECT CAST(st_geomfromtext('{0}',{1}) AS text) geom", wkt, wkid); + var model_geom = client.SqlQueryable(geomsql.ToString()).First(); + return model_geom.geom; + } + + /// + /// Pgsql获取GeoJson数据 + /// + /// + /// + /// + public JToken PgsqlGeoJsonCommon(QueryGeoJsonCommonReq req) + { + //如果有的参数为空,设置参数的默认值 + req.init(); + + //查询列的数据 + StringBuilder sqlColumn = new StringBuilder(); + sqlColumn.AppendFormat(" select {1} from {0} {3} order by \"{2}\"", req.tablename, req.column, req.order, + req.where); + + StringBuilder sqlGeo = new StringBuilder(); + sqlGeo.AppendFormat(" select st_asgeojson(\"{0}\") geom from \"{1}\" {3} order by \"{2}\"", req.geom, + req.tablename, req.order, req.where); + + return PgsqlGeoJsonCommon(sqlColumn, sqlGeo, req.pageIndex, req.limit); + } + + /// + /// 查询GeoJson公共方法 + /// + /// + /// + /// + /// + /// + /// + public JToken PgsqlGeoJsonCommon(StringBuilder sqlColumn, StringBuilder sqlGeom, int pageIndex, int pageSize) + { + //获取到数据库操作实例 + int total = 0; + int totalPage = 0; + //查询列 + var dt_properties = client.SqlQueryable(sqlColumn.ToString()) + .ToPageList(pageIndex, pageSize, ref total, ref totalPage); + //列数据转换为字符串 + string str_properties = JsonConvert.SerializeObject(dt_properties); + //列数据转换为json对象 + JToken jtoken_properties = (JToken)JsonConvert.DeserializeObject(str_properties); + + //查询geojson数据 + var dt_geom = client.SqlQueryable(sqlGeom.ToString()).ToDataTablePage(pageIndex, pageSize); + + //组装最终数据 + JObject obj = new JObject(); + JArray array = new JArray(); + obj.Add("type", "FeatureCollection"); + obj.Add("totalNumber", total); + obj.Add("totalPage", totalPage); + //遍历geojson数据 + for (var i = 0; i < dt_geom.Rows.Count; i++) + { + //行数据 + DataRow item = dt_geom.Rows[i]; + //单条geojson + string _geom = item["geom"] == DBNull.Value ? "" : item["geom"].ToString(); + //给数据赋值 + JObject featureObj = new JObject(); + featureObj.Add("type", "Feature"); + featureObj.Add("geometry", (JToken)JsonConvert.DeserializeObject(_geom)); + featureObj.Add("properties", jtoken_properties[i]); + //添加到数组 + array.Add(featureObj); + } + + obj.Add("features", array); + return obj; + } + + /// + /// 获取列名 + /// + /// + /// + public List SearchColumnsList(string tablename) + { + //查询列名和注释描述 + StringBuilder columnSql = new StringBuilder(); + columnSql.AppendFormat( + @$" SELECT a.attname column_name,col_description(a.attrelid,a.attnum) as description,format_type(a.atttypid,a.atttypmod) as column_type + FROM pg_class as c,pg_attribute as a + where c.relname = '{tablename}' + and a.attrelid = c.oid + and a.attnum>0 + and attstattarget = -1"); + //查询结果 + + var column_list = client.SqlQueryable(columnSql.ToString()).ToList(); + return column_list; + } + + /// + /// 矢量切片公共方法 + /// + /// + /// + /// + public byte[] VectorTile(VectorTileSearchModel req) + { + req.Init(); + + List lons = getLon(req.x, req.z); + List lats = getLat(req.y, req.z); + double lonmin = lons[0]; + double lonmax = lons[1]; + double latmin = lats[1]; + double latmax = lats[0]; + + StringBuilder sql = new StringBuilder(); + sql.AppendFormat( + $" SELECT ST_AsMVT(tile, '{req.source_layer}', 4096, 'geom') tile FROM (SELECT {req.field}ST_AsMVTGeom(geom, ST_Transform(ST_MakeEnvelope({lonmin},{latmin},{lonmax},{latmax}, 4326),4326),4096, 256, true) AS geom FROM public.{req.table} where {req.filter} ) AS tile"); + + + var dataTable = client.Ado.GetDataTable(sql.ToString()); + byte[] result = (Byte[])dataTable.Rows[0]["tile"]; + + return result; + } + + /// + /// 查询最新的主键 + /// + /// + /// + /// + /// + public string GetMaxKeyVal(string _column, string tablename, int _gid_const) + { + string _val = ""; + //查询最大的gid + var column_list = SearchColumnsList(tablename); + string _type = column_list[0].column_type; + if (_type != "integer") + { + _val = Guid.NewGuid().ToString(); + return _val; + } + + var _maxgid = client + .SqlQueryable( + $"SELECT max(\"{_column}\") \"maxGid\" FROM \"{tablename}\" where \"{_column}\" < 6000000").First() + .maxGid; + //gid为空时,说明一条数据都没有 + if (_maxgid == null) + _val = _gid_const.ToString(); + else + { + //如果大于设定值,在此基础上加一,否则设置为默认值 + if (_maxgid >= _gid_const) + _val = (_maxgid + 1).ToString(); + else + _val = _gid_const.ToString(); + } + + return _val; + } + + /// + /// 格式化wkt数据,兼容多个地块 + /// + /// + /// + /// + /// + public string WktDataConvert(string _wkt, string _newType, int _len) + { + //使用逗号分割 + var list = _wkt.Split(","); + + //返回值 + StringBuilder res = new StringBuilder(); + + //扩展的维度,用 0补齐 + string extStr = ""; + for (int i = 0; i < list.Length; i++) + { + //当前项 + var item = list[i]; + extStr = GetWktDemension(item, _len); + if (i == 0) + { + //第一项数据先去除前缀 + item = item.Substring(item.IndexOf("(")).TrimStart('('); + if (_newType == "MULTIPOLYGON ZM") + item = "(((" + item; + else if (_newType == "MULTILINESTRING") + item = "((" + item; + + //扩展后的值 + item = _newType + item + extStr; + } + else if (i == list.Length - 1) + { + //最后一项 + item = item.TrimEnd(')'); + if (_newType == "MULTIPOLYGON ZM") + item = item + extStr + ")))"; + else if (_newType == "MULTILINESTRING") + item = item + extStr + "))"; + } + else + { + //判断是否存在右括号 + if (item.IndexOf(")") > -1) + { + //在第一个右括号前插入维度数据 + item = item.Insert(item.IndexOf(")"), extStr); + } + else + { + //在后面追加维度数据 + item = item + extStr; + } + } + + //追加数据 + res.Append($"{item},"); + } + + string strRes = res.ToString(); + + //把最后一个逗号截取掉 + return strRes.Substring(0, strRes.Length - 1); + } + + private string GetWktDemension(string item, int _len) + { + if (item.IndexOf("(") > -1) + { + item = item.Substring(item.IndexOf("(")); + item = item.TrimStart('('); + } + + string extStr = ""; + //数据的维度 + var _count = _len - item.Split(" ", StringSplitOptions.RemoveEmptyEntries).Length; + + //扩展维度 + if (_count == 1) + extStr = " 0"; + else if (_count == 2) + extStr = " 0 0"; + return extStr; + } + + #region Util + + /// + /// 瓦片转经度 + /// + /// 列号 + /// 缩放级别 + /// + public static double tile2lon(int x, int z) + { + return x / Math.Pow(2.0, z) * 360.0 - 180; + } + + /// + /// 瓦片转纬度 + /// + /// 行号 + /// 缩放级别 + /// + public static double tile2lat(int y, int z) + { + double n = Math.PI - (2.0 * Math.PI * y) / Math.Pow(2.0, z); + return Math.Atan(Math.Sinh(n)) * 180 / Math.PI; + } + + /// + /// 获取经度最大值和经度最小值 + /// + /// 列号 + /// 缩放级别 + /// + public static List getLon(int x, int z) + { + List lonExtent = new List(); + lonExtent.Add(tile2lon(x, z)); + lonExtent.Add(tile2lon(x + 1, z)); + return lonExtent; + } + + /// + /// 获取纬度最大值和经度最小值 + /// + /// 列号 + /// 缩放级别 + /// + public static List getLat(int y, int z) + { + List latExtent = new List(); + latExtent.Add(tile2lat(y, z)); + latExtent.Add(tile2lat(y + 1, z)); + return latExtent; + } + + #endregion + + public byte[] VectorTile1(VectorTileSearchModel req) + { + req.Init(); + + List lons = getLon(req.x, req.z); + List lats = getLat(req.y, req.z); + double lonmin = lons[0]; + double lonmax = lons[1]; + double latmin = lats[1]; + double latmax = lats[0]; + + StringBuilder sql = new StringBuilder(); + sql.AppendFormat( + $" SELECT ST_AsMVT(tile, '{req.source_layer}', 4096, 'geom') tile FROM (SELECT {req.field}ST_AsMVTGeom(geometry, ST_Transform(ST_MakeEnvelope({lonmin},{latmin},{lonmax},{latmax}, 4326),4326),4096, 256, true) AS geom FROM public.{req.table} where {req.filter} ) AS tile"); + + + var dataTable = client.Ado.GetDataTable(sql.ToString()); + byte[] result = (Byte[])dataTable.Rows[0]["tile"]; + + return result; + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/BasicQueryService/PositionManager.cs b/OpenAuth.App/BaseApp/BasicQueryService/PositionManager.cs new file mode 100644 index 0000000..85111ad --- /dev/null +++ b/OpenAuth.App/BaseApp/BasicQueryService/PositionManager.cs @@ -0,0 +1,187 @@ +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.BasicQueryService +{ + public class PositionManager + { + ISqlSugarClient client; + public PositionManager(ISqlSugarClient client) + { + this.client = client; + } + + private async Task HasRelation(string beginId, Dictionary map) + { + bool res = false; + var entity = await client.Queryable().Where(a => a.Id.ToString() == beginId).FirstAsync(); + if (entity == null || entity.ParentId.ToString() == "0") + { + res = false; + } + else if (map.ContainsKey(entity.ParentId.ToString())) + { + res = true; + } + else + { + res = await HasRelation(entity.ParentId.ToString(), map); + } + return res; + } + + /// + /// 判断是否是上级 + /// + /// 自己的岗位 + /// 对方的岗位 + /// + public async Task IsUp(List myIds, List otherIds) + { + bool res = false; + if (myIds.Count > 0 && otherIds.Count > 0) + { + Dictionary map = new Dictionary(); + foreach (var otherItem in myIds) + { + if (!map.ContainsKey(otherItem)) + { + map.Add(otherItem, 1); + } + } + foreach (var myItem in otherIds) + { + if (await HasRelation(myItem, map)) + { + res = true; + break; + } + } + } + return res; + } + /// + /// 判断是否是下级 + /// + /// 自己的岗位 + /// 对方的岗位 + /// + public async Task IsDown(List myIds, List otherIds) + { + bool res = false; + if (myIds.Count > 0 && otherIds.Count > 0) + { + Dictionary map = new Dictionary(); + foreach (var myItem in myIds) + { + if (!map.ContainsKey(myItem)) + { + map.Add(myItem, 1); + } + } + foreach (var otherItem in otherIds) + { + if (await HasRelation(otherItem, map)) + { + res = true; + break; + } + } + } + return res; + } + + /// + /// 获取上级岗位人员ID + /// + /// 岗位 + /// 级数 + /// + public async Task> GetUpIdList(List postIds, int level) + { + List res = new List(); + if (postIds.Count > 0 && level > 0 && level < 6) + {// 现在支持1-5级查找 + bool isHave = false; // 判断是否指定级数的职位 + foreach (var postId in postIds) + { + isHave = false; + var entity = await client.Queryable().Where(a => a.Id.ToString() == postId).FirstAsync(); + if (entity != null) + { + string parentId = entity.ParentId.ToString(); + SysPosition parentEntity = null; + for (int i = 0; i < level; i++) + { + parentEntity = await client.Queryable().Where(a => a.Id.ToString() == parentId).FirstAsync(); + if (parentEntity != null) + { + parentId = parentEntity.ParentId.ToString(); + if (i == (level - 1)) + { + isHave = true; + } + } + else + { + break; + } + } + if (isHave) + { + if (parentEntity != null) + { + res.Add(parentEntity.Id.ToString()); + } + } + } + } + } + return res; + } + /// + /// 获取下级岗位人员ID + /// + /// 岗位 + /// 级数 + /// + public async Task> GetDownIdList(List postIds, int level) + { + List res = new List(); + if (postIds.Count > 0 && level > 0 && level < 6) + {// 现在支持1-5级查找 + bool isHave = false; // 判断是否指定级数的职位 + List parentList = new List(); + parentList.AddRange(postIds); + for (int i = 0; i < level; i++) + { + parentList = (List)await client.Queryable().Where(a => parentList.Contains(a.ParentId.ToString())).Select(a => a.Id.ToString()).ToListAsync(); + if (parentList.Count > 0) + { + if (i == (level - 1)) + { + isHave = true; + } + } + else + { + break; + } + } + if (isHave) + { + res.AddRange(parentList); + } + } + return res; + } + + + + } +} diff --git a/OpenAuth.App/BaseApp/BasicQueryService/Request/QueryGeoJsonCommonReq.cs b/OpenAuth.App/BaseApp/BasicQueryService/Request/QueryGeoJsonCommonReq.cs new file mode 100644 index 0000000..512c839 --- /dev/null +++ b/OpenAuth.App/BaseApp/BasicQueryService/Request/QueryGeoJsonCommonReq.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class QueryGeoJsonCommonReq + { + public string tablename { get; set; } + public string geom { get; set; } + public string column { get; set; } + public string where { get; set; } + public string order { get; set; } + public int pageIndex { get; set; } + public int limit { get; set; } + + public void init() + { + //如果有的参数为空,设置参数的默认值 + if (string.IsNullOrEmpty(geom)) geom = "geom"; + if (string.IsNullOrEmpty(column)) column = "*"; + if (limit == 0 || limit == null) limit = 2000; + if (string.IsNullOrEmpty(order)) order = "gid"; + } + } +} diff --git a/OpenAuth.App/BaseApp/BasicQueryService/Request/QueryVectorTileByTableReq.cs b/OpenAuth.App/BaseApp/BasicQueryService/Request/QueryVectorTileByTableReq.cs new file mode 100644 index 0000000..f82596b --- /dev/null +++ b/OpenAuth.App/BaseApp/BasicQueryService/Request/QueryVectorTileByTableReq.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class QueryVectorTileByTableReq + { + public int x { get; set; } + public int y { get; set; } + public int z { get; set; } + + public string table { get; set; } + + public string field { get; set; } + + public string filter { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/BasicQueryService/Request/VectorTileSearchModel.cs b/OpenAuth.App/BaseApp/BasicQueryService/Request/VectorTileSearchModel.cs new file mode 100644 index 0000000..f43312c --- /dev/null +++ b/OpenAuth.App/BaseApp/BasicQueryService/Request/VectorTileSearchModel.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class VectorTileSearchModel + { + public void Init() + { + if (string.IsNullOrEmpty(filter)) filter = " 1=1"; + if (string.IsNullOrEmpty(source_layer)) source_layer = table; + } + + public int x { get; set; } + public int y { get; set; } + public int z { get; set; } + + public string table { get; set; } + + public string source_layer { get; set; } + + public string field { get; set; } + + public string filter { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/BasicQueryService/UserManager.cs b/OpenAuth.App/BaseApp/BasicQueryService/UserManager.cs new file mode 100644 index 0000000..4e7ac07 --- /dev/null +++ b/OpenAuth.App/BaseApp/BasicQueryService/UserManager.cs @@ -0,0 +1,162 @@ +using Infrastructure.Extensions; +using OpenAuth.App.Interface; +using OpenAuth.Repository.Domain; +using SqlSugar; +using StackExchange.Redis; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.BasicQueryService +{ + public class UserManager + { + ISqlSugarClient client; + + public UserManager(ISqlSugarClient sqlSugarClient) + { + client = sqlSugarClient; + } + + /// + /// x用户的部门集合 + /// + /// + /// + public ISugarQueryable UserOrgs(long userId) + { + var query = client.Queryable() + .LeftJoin((u, o) => u.OrgId == o.Id) + .Where((u, o) => u.UserId == userId && o.Id != null); + + return query; + } + + /// + /// x用户的角色集合 + /// + /// + /// + public ISugarQueryable UserRoles(long userId) + { + var query = client.Queryable() + .LeftJoin((u, r) => u.RoleId == r.Id) + .Where((u, r) => u.UserId == userId && r.Id != null); + + return query; + } + + + /// + /// x角色集合的菜单集合 + /// + /// + /// + /// + /// + /// + public ISugarQueryable RoleModules(List roleIds) + { + var query = client.Queryable() + .LeftJoin((r, m) => r.ModuleId == m.Id) + .Where((r, m) => roleIds.Contains(r.RoleId) && m.Id != null); + + return query; + } + + /// + /// x角色集合的按钮集合 + /// + /// + /// + /// + /// + /// + public ISugarQueryable RoleModuleElements(List roleIds) + { + var query = client.Queryable() + .LeftJoin((r, m) => r.ElementId == m.Id) + .Where((r, m) => roleIds.Contains(r.RoleId) && m.Id != null); + + return query; + } + + public ISugarQueryable UserPositons(long userId) + { + var query = client.Queryable() + .LeftJoin((u, p) => u.PositionId == p.Id) + .Where((u, p) => u.PositionId != null && u.UserId == userId && p.Id != null); + + return query; + } + + public async Task> UserIdsByPosition(string orgId, string positionId) + { + var list = await client.Queryable() + .Where(a => a.PositionId.ToString() == positionId) + .WhereIF(!string.IsNullOrEmpty(orgId), a => a.OrgId.ToString() == orgId) + .Select(a => a.UserId.ToString()).ToListAsync(); + return list; + } + + public async Task> UserIdsByPositions(List positionIds) + { + var list = await client.Queryable() + .Where(a => positionIds.Contains(a.PositionId.ToString())) + .Select(a => a.UserId.ToString()).ToListAsync(); + return list; + } + + public async Task> UserIdsByRole(string roleId) + { + var list = await client.Queryable() + .Where(a => a.RoleId.ToString() == roleId) + .Select(a => a.UserId.ToString()) + .ToListAsync(); + return list; + } + + public async Task> UserOrgsByUserIds(List userIds) + { + var list1 = await client.Queryable() + .Where(a => userIds.Contains(a.UserId.ToString())) + .GroupBy(a => a.UserId) + .Select(it => new + { + UserId = it.UserId.ToString(), + OrgIds = SqlFunc.Subqueryable().Where(s => s.UserId == it.UserId).ToList(s => s.OrgId.ToString()) + }).ToListAsync(); + //.ToDictionaryAsync(x => x.UserId, x => x.OrgIds); + + //var result = list.GroupBy(a => a.UserId.ToString()) + // .Select(g => new + // { + // UserId = g.Key, + // OrgIds = g.Select(a => a.OrgId.ToString()).ToList() + // }).ToDictionary(x => x.UserId, x => x.OrgIds); + Dictionary list = new Dictionary(); + foreach(var item in list1) + { + list.Add(item.UserId, item.OrgIds); + } + return list; + } + + public async Task> PositonsByUser(string userId) + { + var list = await client.Queryable() + .Where(a => a.UserId.ToString() == userId) + .Select(a => a.PositionId.ToString()) + .ToListAsync(); + return list; + } + + + } +} diff --git a/OpenAuth.App/BaseApp/BasicQueryService/WorkFlowMangaer.cs b/OpenAuth.App/BaseApp/BasicQueryService/WorkFlowMangaer.cs new file mode 100644 index 0000000..0c204c1 --- /dev/null +++ b/OpenAuth.App/BaseApp/BasicQueryService/WorkFlowMangaer.cs @@ -0,0 +1,83 @@ +using Infrastructure.Helpers; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.BasicQueryService +{ + public class WorkFlowMangaer + { + ISqlSugarClient client; + ISugarUnitOfWork unitWork; + public WorkFlowMangaer( + ISqlSugarClient sqlSugarClient, + ISugarUnitOfWork unitWork) + { + client = sqlSugarClient; + this.unitWork = unitWork; + } + + #region 模版 + + #endregion + + #region 流程 + + #endregion + + #region 任务 + + #endregion + + #region 签名 + + + public string ToWfImg(string keyValue, string password) + { + return ""; + + //if (string.IsNullOrEmpty(keyValue)) + //{ + // return ""; + //} + + //WFStamp entity = await GetEntity(keyValue); + //if (entity != null && (entity.F_IsNotPassword == 0 || entity.F_Password.Equals(password))) + //{ + // var imgId = entity.F_ImgFile; + // var data = await _annexesFileIBLL.GetEntity(imgId); + // if (data == null) + // { + // // 说明上传的是附件夹主键 + // var list = (List)await _annexesFileIBLL.GetList(imgId); + // if (list.Count == 0) + // { + // return ""; + // } + // data = list[0]; + // } + // var basePath = ConfigHelper.GetConfig().FilePath; + // string path = $"{basePath}/Learun_WF_IMG/{imgId}{data.F_FileExtensions}"; + // if (!File.Exists(path)) + // { + // byte[] arr = FileHelper.Read($"{basePath}/Learun_ANNEXESFILE/{data.F_FilePath}"); + // FileHelper.Write(path, arr); + // } + + // return $"{imgId}{data.F_FileExtensions}"; + //} + //else + //{ + // return ""; + //} + } + + + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/Category/CategoryApp.cs b/OpenAuth.App/BaseApp/Category/CategoryApp.cs new file mode 100644 index 0000000..9c607cd --- /dev/null +++ b/OpenAuth.App/BaseApp/Category/CategoryApp.cs @@ -0,0 +1,117 @@ +using Infrastructure; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + public class CategoryApp : SqlSugarBaseApp + { + private DbExtension extension; + public CategoryApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth, DbExtension dbExtension) : base(unitWork, repository, auth) + { + extension = dbExtension; + } + /// + /// 加载列表 + /// + + public void Add(AddOrUpdateCategoryReq req) + { + var obj = req.MapTo(); + obj.CreateTime = DateTime.Now; + var user = _auth.GetCurrentUser().User; + obj.CreateUserId = user.Id; + obj.CreateUserName = user.Name; + Repository.Insert(obj); + } + + public void Update(AddOrUpdateCategoryReq obj) + { + var user = _auth.GetCurrentUser().User; + Repository.Update(u => new SysCategory + { + Name = obj.Name, + Enable = obj.Enable, + DtValue = obj.DtValue, + DtCode = obj.DtCode, + TypeId = obj.TypeId, + UpdateTime = DateTime.Now, + UpdateUserId = user.Id, + UpdateUserName = user.Name + //todo:要修改的字段赋值 + }, u => u.Id == obj.Id); + + } + + /// + /// 加载一个分类类型里面的所有值,即字典的所有值 + /// + /// + /// + public dynamic LoadByTypeId(string typeId, int page, int limit) + { + var loginContext = _auth.GetCurrentUser(); + + var properties = extension.GetProperties(typeof(SysCategory)); + + var p = new PageModel() { PageIndex = page, PageSize = limit }; + + var exp = Expressionable.Create() + .AndIF(!string.IsNullOrEmpty(typeId), u => u.TypeId == typeId) + .ToExpression(); + + var list = Repository.GetPageList(exp, p); + + //return new TableData + //{ + // code = 200, + // count = p.TotalCount, + // data = list, + // msg = "success" + //}; + return new + { + code = 200, + columnHeaders = properties, + count = p.TotalCount, + data = list, + msg = "success" + }; + } + + public TableData QueryCategory(string type) + { + var table = base.Repository.AsQueryable() + .Where(a => a.TypeId == type) + .OrderBy(a => a.SortNo) + .Select(a => new + { + a.Name, + a.DtCode, + a.DtValue + }).ToList(); + + return new TableData() + { + count = table.Count, + data = table + }; + } + + public void Delete(string[] ids) + { + Repository.DeleteByIds(ids); + } + + public SysCategory Get(string id) + { + return Repository.GetById(id); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Category/CategoryTypeApp.cs b/OpenAuth.App/BaseApp/Category/CategoryTypeApp.cs new file mode 100644 index 0000000..55b810a --- /dev/null +++ b/OpenAuth.App/BaseApp/Category/CategoryTypeApp.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Infrastructure; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + public class CategoryTypeApp : SqlSugarBaseApp + { + public CategoryTypeApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + + } + /// + /// 加载列表 + /// + public async Task Load(QueryCategoryTypeListReq request) + { + int totalCount = 0; + var result = new TableData(); + var objs = base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(request.key), u => u.Id.Contains(request.key) || u.Name.Contains(request.key)); + + result.data = await objs.OrderBy(u => u.Name).ToPageListAsync(request.page, request.limit, totalCount); + result.count = totalCount; + + return result; + } + + public void Add(AddOrUpdateCategoryTypeReq req) + { + var obj = req.MapTo(); + //todo:补充或调整自己需要的字段 + obj.CreateTime = DateTime.Now; + Repository.Insert(obj); + } + + public void Update(AddOrUpdateCategoryTypeReq obj) + { + var user = _auth.GetCurrentUser().User; + Repository.Update(u => new SysCategoryType + { + Name = obj.Name, + CreateTime = DateTime.Now + //todo:补充或调整自己需要的字段 + }, u => u.Id == obj.Id); + } + + public void Delete(string[] ids) + { + using (var uwo = UnitWork.CreateContext()) + { + uwo.CategoryType.Delete(u => ids.Contains(u.Id)); + uwo.Category.Delete(u => ids.Contains(u.TypeId)); + uwo.Commit(); + } + } + + public List AllTypes() + { + return Repository.GetList(); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Category/Request/AddOrUpdateCategoryReq.cs b/OpenAuth.App/BaseApp/Category/Request/AddOrUpdateCategoryReq.cs new file mode 100644 index 0000000..b13186a --- /dev/null +++ b/OpenAuth.App/BaseApp/Category/Request/AddOrUpdateCategoryReq.cs @@ -0,0 +1,51 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a CodeSmith Template. +// +// DO NOT MODIFY contents of this file. Changes to this +// file will be lost if the code is regenerated. +// Author:Yubao Li +// +//------------------------------------------------------------------------------ + +namespace OpenAuth.App.Request +{ + /// + /// 分类表,也可用作数据字典。表示一个全集,比如:男、女、未知。关联的分类类型表示按什么进行的分类,如:按照性别对人类对象集 + /// + public class AddOrUpdateCategoryReq + { + + public long Id { get; set; } + + /// + /// 分类名称或描述 + /// + public string Name { get; set; } + /// + /// 分类标识 + /// + public string DtCode { get; set; } + /// + /// 通常与分类标识一致,但万一有不一样的情况呢? + /// + public string DtValue { get; set; } + /// + /// + /// + public bool Enable { get; set; } + /// + /// 排序号 + /// + public int SortNo { get; set; } + /// + /// 详细说明,基本没啥用 + /// + public string Description { get; set; } + /// + /// 分类的ID + /// + public string TypeId { get; set; } + + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Category/Request/AddOrUpdateCategoryTypeReq.cs b/OpenAuth.App/BaseApp/Category/Request/AddOrUpdateCategoryTypeReq.cs new file mode 100644 index 0000000..a2748dd --- /dev/null +++ b/OpenAuth.App/BaseApp/Category/Request/AddOrUpdateCategoryTypeReq.cs @@ -0,0 +1,31 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a CodeSmith Template. +// +// DO NOT MODIFY contents of this file. Changes to this +// file will be lost if the code is regenerated. +// Author:Yubao Li +// +//------------------------------------------------------------------------------ + +using System.ComponentModel.DataAnnotations.Schema; + +namespace OpenAuth.App.Request +{ + /// + /// 分类类型 + /// + [Table("CategoryType")] + public partial class AddOrUpdateCategoryTypeReq + { + + /// + /// 分类表ID + /// + public string Id { get; set; } + /// + /// 名称 + /// + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Category/Request/QueryCategoryListReq.cs b/OpenAuth.App/BaseApp/Category/Request/QueryCategoryListReq.cs new file mode 100644 index 0000000..538e63e --- /dev/null +++ b/OpenAuth.App/BaseApp/Category/Request/QueryCategoryListReq.cs @@ -0,0 +1,11 @@ +namespace OpenAuth.App.Request +{ + public class QueryCategoryListReq : PageReq + { + + /// + /// TypeID + /// + public string TypeId { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Category/Request/QueryCategoryTypeListReq.cs b/OpenAuth.App/BaseApp/Category/Request/QueryCategoryTypeListReq.cs new file mode 100644 index 0000000..1f27d06 --- /dev/null +++ b/OpenAuth.App/BaseApp/Category/Request/QueryCategoryTypeListReq.cs @@ -0,0 +1,7 @@ +namespace OpenAuth.App.Request +{ + public class QueryCategoryTypeListReq : PageReq + { + //todo:添加自己的请求字段 + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Category/Response/CategoryTypeResp.cs b/OpenAuth.App/BaseApp/Category/Response/CategoryTypeResp.cs new file mode 100644 index 0000000..c49734f --- /dev/null +++ b/OpenAuth.App/BaseApp/Category/Response/CategoryTypeResp.cs @@ -0,0 +1,10 @@ +using OpenAuth.Repository.Domain; + +namespace OpenAuth.App.Response +{ + public class CategoryTypeResp : SysCategoryType + { + public string ParentId { get; set; } + + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/CodeTable/CodeColumnsApp.cs b/OpenAuth.App/BaseApp/CodeTable/CodeColumnsApp.cs new file mode 100644 index 0000000..99758d4 --- /dev/null +++ b/OpenAuth.App/BaseApp/CodeTable/CodeColumnsApp.cs @@ -0,0 +1,74 @@ +using OpenAuth.App.Base; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App.CodeTable +{ + /// + /// 日 期: 2024-03-02 + /// 描 述: 数据库表字段信息 + /// + public class CodeColumnsApp : SqlSugarBaseApp + { + public CodeColumnsApp(ISugarUnitOfWork unitWork, ISimpleClient repository) : base(unitWork, repository, null) + { + + } + public Task> GetList(DbCodeColumns queryParams) + { + return base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(queryParams.CodeTableId), t => t.CodeTableId == queryParams.CodeTableId) + .WhereIF(!string.IsNullOrEmpty(queryParams.DbType), t => t.DbType == queryParams.DbType) + .WhereIF(!string.IsNullOrEmpty(queryParams.DbColumnName), t => t.DbColumnName == queryParams.DbColumnName) + .WhereIF(queryParams.IsIdentity != null, t => t.IsIdentity == queryParams.IsIdentity) + .WhereIF(queryParams.IsPrimaryKey != null, t => t.IsPrimaryKey == queryParams.IsPrimaryKey) + .OrderBy(t => t.Sort) + .ToListAsync(); + } + #region 提交数据 + /// + /// 删除 + /// + /// 表格主键 + public async Task Delete(string tableId) + { + await base.Repository.DeleteAsync(t => t.CodeTableId == tableId); + } + /// + /// 新增数据 + /// + /// 字段数据集 + /// + public async Task Add(List list) + { + await base.Repository.InsertRangeAsync(list); + } + /// + /// 更新数据 + /// + /// 字段数据集 + /// + public async Task Update(List list) + { + await base.Repository.UpdateRangeAsync(list); + } + + /// + /// 更新数据 + /// + /// 字段数据集 + /// + public async Task Deletes(List list) + { + await base.Repository.DeleteAsync(list); + } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/CodeTable/CodeTableApp.cs b/OpenAuth.App/BaseApp/CodeTable/CodeTableApp.cs new file mode 100644 index 0000000..3874698 --- /dev/null +++ b/OpenAuth.App/BaseApp/CodeTable/CodeTableApp.cs @@ -0,0 +1,277 @@ +using Infrastructure; +using Infrastructure.Extensions; +using Infrastructure.Utilities; +using Microsoft.Extensions.Configuration; +using NUnit.Framework; +using OpenAuth.App.Base; +using OpenAuth.App.FormScheme.FormHelpers; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; +using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource; + +namespace OpenAuth.App.CodeTable +{ + public class CodeTableApp : SqlSugarBaseApp + { + CodeColumnsApp _codeColumnsApp; + private IConfiguration _configuration; + public CodeTableApp(ISugarUnitOfWork unitWork, ISimpleClient repository, CodeColumnsApp codeColumnsApp, IConfiguration configuration) : base(unitWork, repository, null) + { + _codeColumnsApp = codeColumnsApp; + _configuration = configuration; + } + + /// + /// 获取CodeTable的分页数据 + /// + /// 查询关键字 + /// 数据库编码 + /// + /// + /// + public async Task>>> LoadCodeTablePage(string keyWord, string dbCode, int page, int limit) + { + RefAsync totalCount = 0; + var info = await base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(keyWord), t => t.ClassName.Contains(keyWord) || t.TableName.Contains(keyWord) || t.Description.Contains(keyWord)) + .WhereIF(!string.IsNullOrEmpty(dbCode), t => t.DbId == dbCode) + .ToPageListAsync(page, limit, totalCount); + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + /// + /// 获取实体集合 + /// + /// 数据库编码 + /// 数据库表名 + /// + public async Task> GetEntitys(string dbCode, List tableNames) + { + var list = await base.Repository.AsQueryable() + .Where(t => t.DbId == dbCode && tableNames.Contains(t.TableName)) + .ToListAsync(); + return list; + } + /// + /// 获取列表数据 + /// + /// 数据库编码 + /// + public Task> GetList(string dbCode) + { + + return base.Repository.AsQueryable().Where(t => t.DbId == dbCode).ToListAsync(); + } + /// + /// 跨服务器获取表单字段 + /// + /// + /// + /// + public List GetTableColumnList(string code, string tableName) + { + using (var db = this.CodeClient(code, _configuration)) + { + //var list= this.Repository.AsSugarClient().DbMaintenance.GetTableInfoList(isCache); + var list = db.DbMaintenance.GetColumnInfosByTableName(tableName,false); + return list; + } + + } + /// + /// 导入表信息 + /// + /// 数据库编码 + /// 数据表信息 + /// + public async Task ImportTable(string dbcode, List tableList) + { + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + var oldTables = await GetList(dbcode); + List updateList = new List(); + List addList = new List(); + List deleteList = new List(); + foreach (var tableItem in tableList) + { + //排除中间表 + if (tableItem.Name.ToLower() == "db_codecolumns" || tableItem.Name.ToLower() == "db_codetable" || tableItem.Name.ToLower() == "db_history") + { + continue; + } + DbCodeTable entity = oldTables.FirstOrDefault(t => t.TableName == tableItem.Name); + //var dbColumns = db.Db.DbMaintenance.GetColumnInfosByTableName(tableItem.Name, false); + var dbColumns = GetTableColumnList(dbcode, tableItem.Name); + foreach (var item in dbColumns) + { + item.PropertyName = FormHelper.GetCsType(SqlSugar.DbType.Kdbndp, item.DataType); + } + int columnSort = 1; + if (entity == null) + { + // 新增 + entity = new DbCodeTable(); + entity.DbId = dbcode; + entity.ClassName = StringExtension.CsharpName(tableItem.Name); + entity.TableName = tableItem.Name; + entity.Description = tableItem.Description; + entity.IsLock = 0; + entity.DeleteMark = 0; + entity.State = 1; + await SaveEntity(null, entity); + + // 新增列 + foreach (var dbColumnItem in dbColumns) + { + var codeColumnsEntity = CreateColumn(dbColumnItem); + codeColumnsEntity.CodeTableId = entity.Id; + codeColumnsEntity.Id = Guid.NewGuid().ToString(); + codeColumnsEntity.Sort = columnSort; + columnSort++; + addList.Add(codeColumnsEntity); + } + } + else + { + // 编辑 + if (entity.Description != tableItem.Description + || entity.State != 1 + || entity.IsLock != 0 + || entity.DeleteMark != 0 + ) + { + entity.State = 1; + entity.Description = tableItem.Description; + entity.IsLock = 0; + entity.DeleteMark = 0; + await SaveEntity(entity.Id, entity); + } + var oldColumns = await _codeColumnsApp.GetList(new DbCodeColumns { CodeTableId = entity.Id }); + foreach (var dbColumnItem in dbColumns) + { + var codeColumnsEntity = CreateColumn(dbColumnItem); + codeColumnsEntity.CodeTableId = entity.Id; + codeColumnsEntity.Sort = columnSort; + columnSort++; + + var oldColumn = oldColumns.Find(t => t.DbColumnName == dbColumnItem.DbColumnName); + if (oldColumn == null) + { + codeColumnsEntity.Id = Guid.NewGuid().ToString(); + addList.Add(codeColumnsEntity); + } + else + { + codeColumnsEntity.Id = oldColumn.Id; + updateList.Add(codeColumnsEntity); + } + } + // 获取需要删除的列 + var deleteColumns = oldColumns.FindAll(t => updateList.FindIndex(t2 => t2.Id == t.Id) == -1); + deleteList.AddRange(deleteColumns); + } + } + //await _codeColumnsApp.Add(addList); + //await _codeColumnsApp.Update(updateList); + //await _codeColumnsApp.Deletes(deleteList); + await db.DbCodeColumns.InsertRangeAsync(addList); + await db.DbCodeColumns.UpdateRangeAsync(updateList); + await db.DbCodeColumns.DeleteAsync(deleteList); + db.Commit(); + } + } + #region 操作方法 + /// + /// 保存(新增,更新) + /// + /// 唯一标识码(GUID) + /// 数据库表信息db_codetable实体数据 + public async Task SaveEntity(string Id, DbCodeTable dbCodeTable) + { + if (!string.IsNullOrEmpty(Id)) // 更新 + { + dbCodeTable.Id = Id; + await base.Repository.UpdateAsync(dbCodeTable); + } + else // 新增 + { + if (string.IsNullOrEmpty(dbCodeTable.Id)) + { + dbCodeTable.Id = Guid.NewGuid().ToString(); + } + await base.Repository.InsertAsync(dbCodeTable); + } + } + /// + /// 获取类字段信息 + /// + /// 数据库字段信息 + /// + private DbCodeColumns CreateColumn(DbColumnInfo dbColumnInfo) + { + var codeColumns = new DbCodeColumns(); + codeColumns.DbColumnName = dbColumnInfo.DbColumnName; + codeColumns.IsNullable = dbColumnInfo.IsNullable == true ? 1 : 0; + codeColumns.IsIdentity = dbColumnInfo.IsIdentity == true ? 1 : 0; + codeColumns.IsPrimaryKey = dbColumnInfo.IsPrimarykey == true ? 1 : 0; + codeColumns.Description = dbColumnInfo.ColumnDescription; + codeColumns.CsType = dbColumnInfo.PropertyName; + codeColumns.DbType = dbColumnInfo.DataType; + codeColumns.Length = dbColumnInfo.Length; + codeColumns.DecimalDigits = dbColumnInfo.DecimalDigits; + return codeColumns; + } + #endregion + #region 获取表及视图字段 + /// + /// 获取表及视图字段 + /// + /// + /// + public List GetTableAndViewColumnList(string dbCode, string tableName) + { + using (var db = this.CodeClient(dbCode, _configuration)) + { + string query = $@" + SELECT + c.column_name, + d.description + FROM + information_schema.columns c + LEFT JOIN + pg_catalog.pg_class t ON t.relname = c.table_name + LEFT JOIN + pg_catalog.pg_attribute a ON a.attnum > 0 + AND a.attrelid = t.oid + AND a.attname = c.column_name + LEFT JOIN + pg_catalog.pg_namespace n ON n.oid = t.relnamespace + LEFT JOIN + pg_catalog.pg_description d ON d.objoid = a.attrelid + AND d.objsubid = a.attnum + WHERE + c.table_name = @tableName + AND c.table_schema = 'public';"; + // 执行查询并获取结果 + var viewColumns = db.Ado.SqlQuery(query, new { tableName = tableName }); + return viewColumns; + } + + } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/CodeTable/Request/CodeTableReq.cs b/OpenAuth.App/BaseApp/CodeTable/Request/CodeTableReq.cs new file mode 100644 index 0000000..ccab511 --- /dev/null +++ b/OpenAuth.App/BaseApp/CodeTable/Request/CodeTableReq.cs @@ -0,0 +1,27 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.CodeTable.Request +{ + /// + /// 数据库操作中间类 + /// + public class CodeTableReq + { + /// + /// 导入的数据表字符串 + /// + public string CodeTableStr { get; set; } + + /// + /// 需要导入表数据 + /// + [Required(ErrorMessage = "请选择导入的数据表")] + public List TableList { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/CodeTable/Response/CodeTableColumnsResp.cs b/OpenAuth.App/BaseApp/CodeTable/Response/CodeTableColumnsResp.cs new file mode 100644 index 0000000..120a5e5 --- /dev/null +++ b/OpenAuth.App/BaseApp/CodeTable/Response/CodeTableColumnsResp.cs @@ -0,0 +1,19 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.CodeTable.Response +{ + public class CodeTableColumnsResp + { + /// db_codetable(数据库表信息)表的实体 + /// + public DbCodeTable db_codetable { get; set; } + /// db_codecolumns(数据库表字段信息)表的实体 + /// + public List db_codecolumnsList { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/CreateTable/BasicTableService.cs b/OpenAuth.App/BaseApp/CreateTable/BasicTableService.cs new file mode 100644 index 0000000..77a77fd --- /dev/null +++ b/OpenAuth.App/BaseApp/CreateTable/BasicTableService.cs @@ -0,0 +1,211 @@ +using Castle.Core.Internal; +using ClosedXML.Excel; +using DocumentFormat.OpenXml.Drawing; +using DocumentFormat.OpenXml.Spreadsheet; +using DocumentFormat.OpenXml.Wordprocessing; +using Infrastructure; +using Infrastructure.Extensions; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using NUnit.Framework.Internal.Execution; +using OpenAuth.App.Interface; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Nodes; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class BasicTableService + { + + ISqlSugarClient client; + + IAuth auth; + + public BasicTableService(ISqlSugarClient client,IAuth auth) + { + this.client = client; + this.auth = auth; + } + + /// + /// 创建表 + /// + /// + /// + [HttpPost] + public string CreateTable([FromBody] CreateTableReq req) + { + string tableName = req.TableName; + List tableInfo = req.TableInfos; + if(tableName == null||tableInfo.Count==0) { + return "数据不能为空"; + } + string sql = @"CREATE TABLE ""public""." + tableName+"("+ "id varchar(255) COLLATE \"pg_catalog\".\"default\" NOT NULL,"; + string explanation = ""; + int type = 0; + for (int i = 0; i < tableInfo.Count; i++) { + TableInfo table = tableInfo[i]; + if ("id".Equals(table.Name.ToLower())){ + continue; + } + sql = sql +table.Name+" "+ table.Type; + if (!table.Name.IsNullOrEmpty()) { + explanation = explanation + "COMMENT ON COLUMN \"public\"." + tableName + "." + table.Name + " Is "+"'"+ table.Explanation+"'"+";" ; + } + if ("varchar".Equals(table.Name.ToLower())) { + sql = sql +"("+255+")"; + } + if (table.Type.Contains("geom")) { + type = 1; + } + /*if (table.IsNull) { + sql = sql+" "+"NOT NUll"; + }*/ + sql = sql + ","; + if (tableInfo.Count-1==i) { + sql = sql + "CONSTRAINT "+ tableName +"_pkey PRIMARY KEY (\"id\"));"; + } + } + Console.WriteLine(sql); + int count = client.Ado.ExecuteCommand(sql); + Console.WriteLine(count); + string sql1 = "ALTER TABLE \"public\"." + tableName+ " OWNER TO \"postgres\""; + client.Ado.ExecuteCommand(sql1); + addExplain(explanation); + SysUser user = auth.GetCurrentUser().User; + string sql22 = "insert into table_record (\"TableName\",\"Type\",\"ColumnJson\",\"CreateUser\") values('" + tableName+"'," + type+",'"+ String.Join(":",tableInfo.Select( + p=> $"{p.Name},{p.Type},{p.Explanation}"))+ "','"+user.Account+"')"; + client.Ado.ExecuteCommand(sql22); + return "创建成功"; + } + + [HttpPost] + public string CreateView([FromBody] CreateViewReq req) { + int count = client.Ado.ExecuteCommand(req.sql); + return "创建成功"; + } + + [HttpPost] + public List UploadExcel(UploadExcelReq req) + { + using (var workbook = new XLWorkbook(req.file.OpenReadStream())){ + string tableName = req.tableName; + var wooksheet = workbook.Worksheet(1); + IXLRows row = wooksheet.RowsUsed(); + List rowCells = row.ToList(); + + IXLRow row1 = rowCells[0]; + IXLCells cells = row1.CellsUsed(); + + string sqltable = @"CREATE TABLE if not exists ""public""." + "table_relation_record " + "(" + "id varchar(255) COLLATE \"pg_catalog\".\"default\" NOT NULL," + + "name varchar(32) COLLATE \"pg_catalog\".\"default\"," + + "relation text COLLATE \"pg_catalog\".\"default\","+ + " CONSTRAINT \"table_relation_record_pkey\" PRIMARY KEY (\"id\"))\r\n;" + + "ALTER TABLE \"public\".\"table_relation_record\" OWNER TO \"postgres\";"; + + + addExplain(sqltable); + string sql = @"CREATE TABLE ""public""." + tableName + "(" + "id varchar(255) COLLATE \"pg_catalog\".\"default\" NOT NULL,"; + string explanation = ""; + List listTableInfo = new List(); + + int k = 0; + JsonObject json = new JsonObject(); + foreach (IXLCell cell in row1.CellsUsed()) + { + if (cell.GetString().IsNullOrEmpty()) { + break;} + json.Add(cell.GetString(), "cloum" + k); + TableInfo tableInfo = new TableInfo(); + tableInfo.Name = "cloum" + k; + tableInfo.Type = "varchar"; + // tableInfo.Length = 255; + tableInfo.Explanation = cell.GetString(); + listTableInfo.Add(tableInfo); + sql = sql + "cloum" + k + " " + "varchar(255),"; + explanation = explanation + "COMMENT ON COLUMN \"public\"." + tableName + "." + "cloum" + k + " Is " + "'" + cell.GetString() + "'" + ";"; + k++; + } + Dictionary dict = new Dictionary(); + dict.Add("id", Guid.NewGuid()); + dict.Add("name", tableName); + dict.Add("relation", json.ToJsonString()); + client.Insertable(dict).AS("table_relation_record").ExecuteCommand(); + sql = sql + "CONSTRAINT " + tableName + "_pkey PRIMARY KEY (\"id\"));"; + + string sql1 = "ALTER TABLE \"public\"." + tableName + " OWNER TO \"postgres\""; + addExplain(sql); + addExplain(sql1); + addExplain(explanation); + var count = wooksheet.RowCount(); + + List> listmap = new List>(); + + foreach (IXLRow rowValue in wooksheet.RowsUsed()) { + if (rowValue.RowNumber() == 1) { + + continue; + } + + Dictionary map = new Dictionary(); + map.Add("id", Guid.NewGuid()); + int g = 0; + foreach (IXLCell cell in rowValue.CellsUsed()) { + map.Add("cloum" + g, cell.GetString()); + g++; + } + listmap.Add(map); + + } + + client.Insertable(listmap).AS(tableName).ExecuteCommand(); + return listTableInfo; + } + + + } + [HttpPost] + public string UpdateTable([FromBody] CreateTableReq req) + { + List infos = req.TableInfos; + string sql = ""; + foreach (TableInfo info in infos) { + if (!info.YuanName.IsNullOrEmpty()) + { + sql = sql + @"ALTER TABLE ""public""."+req.TableName+"RENAME COLUMN"+info.YuanName + " TO " + info.Name+ ";"; + } + } + if (!sql.IsNullOrEmpty()) { addExplain(sql); } + + return "创建成功"; + } + public void addExplain(String sql) { + client.Ado.ExecuteCommand(sql); + } + + + public bool CheckTableExist(string tableName) + { + + string sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_name = '" + tableName + "';"; + + int count = client.Ado.GetInt(sql); + if (count > 0) + { + return true; + } + else { return false; } + + + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/CreateTable/CreateTableReq.cs b/OpenAuth.App/BaseApp/CreateTable/CreateTableReq.cs new file mode 100644 index 0000000..ff2ff41 --- /dev/null +++ b/OpenAuth.App/BaseApp/CreateTable/CreateTableReq.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class CreateTableReq + { + /// + /// 表名称 + /// + public string TableName { get; set;} + + public List TableInfos { get; set; } + } + + +} diff --git a/OpenAuth.App/BaseApp/CreateTable/CreateViewReq.cs b/OpenAuth.App/BaseApp/CreateTable/CreateViewReq.cs new file mode 100644 index 0000000..3f7fba6 --- /dev/null +++ b/OpenAuth.App/BaseApp/CreateTable/CreateViewReq.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class CreateViewReq + { + /// + /// 表名称 + /// + public string sql { get; set;} + + } + + +} diff --git a/OpenAuth.App/BaseApp/CreateTable/TableInfo.cs b/OpenAuth.App/BaseApp/CreateTable/TableInfo.cs new file mode 100644 index 0000000..5908ff3 --- /dev/null +++ b/OpenAuth.App/BaseApp/CreateTable/TableInfo.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class TableInfo + { + + public TableInfo() { } + /// + /// 字段名称 + /// + public string Name { get; set; } + /// + /// 字段名称 + /// + + public string YuanName { get; set; } + /// + /// 字段类型 + /// + public string Type { get; set; } + /// + /// 字段长度 + /// + /* public int Length { get; set; } + /// + /// 是否为空 + /// + public bool IsNull { get; set; }*/ + /// + /// 注释 + /// + public string Explanation { get; set; } + + public override string ToString() + { + return $"{Name},{Type},{Explanation}"; + } + } +} diff --git a/OpenAuth.App/BaseApp/CreateTable/TableRecordApp.cs b/OpenAuth.App/BaseApp/CreateTable/TableRecordApp.cs new file mode 100644 index 0000000..960fade --- /dev/null +++ b/OpenAuth.App/BaseApp/CreateTable/TableRecordApp.cs @@ -0,0 +1,41 @@ +using Infrastructure; +using OpenAuth.App.Base; +using OpenAuth.Repository; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App +{ + public class TableRecordApp : SqlSugarBaseApp + { + public TableRecordApp(ISugarUnitOfWork unitWork, + ISimpleClient repository) + : base(unitWork, repository, null) + { + + } + public Response>> LoadTableRecordList(string keyword, int pageindex, int pagesize) + { + //定义且实例化分页数据 + int totalCount = 0; + //数据查询并返回 + var info = this.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(keyword), t => t.TableName.Contains(keyword)) + .ToPageList(pageindex, pagesize, ref totalCount); + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + + } +} diff --git a/OpenAuth.App/BaseApp/CreateTable/UploadExcelReq.cs b/OpenAuth.App/BaseApp/CreateTable/UploadExcelReq.cs new file mode 100644 index 0000000..5ff845d --- /dev/null +++ b/OpenAuth.App/BaseApp/CreateTable/UploadExcelReq.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class UploadExcelReq + { + + public string tableName { get; set; } + + public IFormFile file { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/DataCodeRule/CodeRuleApp.cs b/OpenAuth.App/BaseApp/DataCodeRule/CodeRuleApp.cs new file mode 100644 index 0000000..0191a68 --- /dev/null +++ b/OpenAuth.App/BaseApp/DataCodeRule/CodeRuleApp.cs @@ -0,0 +1,245 @@ +using OpenAuth.App.Base; +using OpenAuth.App.DataCodeRule.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Infrastructure.Extensions; +using Infrastructure.Cache; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App.DataCodeRule +{ + /// + /// 日期:2024-03-06 + /// 描述:编号规则 + /// + public class CodeRuleApp : SqlSugarBaseApp + { + private ICacheContext _iCache; + public CodeRuleApp(ISugarUnitOfWork unitWork, ICacheContext cacheContext, + ISimpleClient repository) + : base(unitWork, repository, null) + { + _iCache = cacheContext; + } + #region 单据编码处理 + /// + /// 获得指定模块或者编号的单据号 + /// + /// 编码 + /// 单据号 + public async Task GetBillCode(string enCode) + { + string billCode = ""; //单据号 + string nextBillCode = "";//单据号 + + SysCodeRule coderuleentity = await GetEntityByCode(enCode); + if (coderuleentity != null) + { + List codeRuleFormatList = coderuleentity.RuleFormatJson.ToList(); + string dateFormatStr = ""; + foreach (CodeRuleFormatModel codeRuleFormatEntity in codeRuleFormatList) + { + switch (codeRuleFormatEntity.itemType.ToString()) + { + //自定义项 + case "0": + billCode += codeRuleFormatEntity.formatStr; + nextBillCode += codeRuleFormatEntity.formatStr; + break; + //日期 + case "1": + //日期字符串类型 + dateFormatStr += codeRuleFormatEntity.formatStr.Replace("m", "M"); + billCode += DateTime.Now.ToString(dateFormatStr); + nextBillCode += DateTime.Now.ToString(dateFormatStr); + break; + //流水号 + case "2": + int seedStep = codeRuleFormatEntity.stepValue == null ? 1 : int.Parse(codeRuleFormatEntity.stepValue.ToString());//如果步长为空默认1 + int initValue = codeRuleFormatEntity.initValue == null ? 1 : int.Parse(codeRuleFormatEntity.initValue.ToString());//如果初始值为空默认1 + + int nowSerious = await _iCache.Lock(coderuleentity.RuleId, id => { return GetSeedValue(coderuleentity.RuleId, initValue, seedStep, dateFormatStr); }); + //int nowSerious =await codeRuleService.GetSeedValue(coderuleentity.F_RuleId, initValue, seedStep, dateFormatStr); + + + int nextSerious = nowSerious + seedStep; + // 最大种子已经过期 + string seriousStr = new string('0', (int)(codeRuleFormatEntity.formatStr.Length - nowSerious.ToString().Length)) + nowSerious.ToString(); + string NextSeriousStr = new string('0', (int)(codeRuleFormatEntity.formatStr.Length - nextSerious.ToString().Length)) + nextSerious.ToString(); + billCode += seriousStr; + nextBillCode += NextSeriousStr; + break; + //部门 + case "3": + //var userInfo = await CurrentUser(); + //DepartmentEntity departmentEntity = await _departmentIBLL.GetEntity(userInfo.F_DepartmentId); + //if (departmentEntity != null) + //{ + // if (codeRuleFormatEntity.formatStr == "code") + // { + // billCode += departmentEntity.F_EnCode; + // nextBillCode = nextBillCode + departmentEntity.F_EnCode; + // } + // else + // { + // billCode = billCode + departmentEntity.F_FullName; + // nextBillCode = nextBillCode + departmentEntity.F_FullName; + + // } + //} + break; + //公司 + case "4": + //var userInfo2 = await CurrentUser(); + //CompanyEntity companyEntity = await _companyIBLL.GetEntity(userInfo2.F_CompanyId); + //if (companyEntity != null) + //{ + // if (codeRuleFormatEntity.formatStr == "code") + // { + // billCode += companyEntity.F_EnCode; + // nextBillCode += companyEntity.F_EnCode; + // } + // else + // { + // billCode += companyEntity.F_FullName; + // nextBillCode += companyEntity.F_FullName; + // } + //} + break; + //用户 + case "5": + //var userInfo3 = await CurrentUser(); + //if (codeRuleFormatEntity.formatStr == "code") + //{ + // billCode += userInfo3.F_Account; + // nextBillCode += userInfo3.F_Account; + //} + //else + //{ + // billCode += userInfo3.F_RealName; + // nextBillCode += userInfo3.F_RealName; + //} + break; + default: + break; + } + } + coderuleentity.CurrentNumber = nextBillCode; + await SaveEntity(coderuleentity.RuleId, coderuleentity); + } + return billCode; + + } + + /// + /// 保存规则表单(新增、修改) + /// + /// 主键值 + /// 规则实体 + /// + public async Task SaveEntity(string keyValue, SysCodeRule codeRuleEntity) + { + if (!string.IsNullOrEmpty(keyValue)) + { + codeRuleEntity.RuleId = keyValue; + codeRuleEntity.ModifyDate = DateTime.Now; + codeRuleEntity.ModifyUserId = _auth.GetUserId(); + codeRuleEntity.ModifyUserName = _auth.GetUserName(); + await base.Repository.UpdateAsync(codeRuleEntity); + } + else + { + codeRuleEntity.RuleId = Guid.NewGuid().ToString(); + codeRuleEntity.CreateDate = DateTime.Now; + codeRuleEntity.DeleteMark = 0; + codeRuleEntity.EnabledMark = 1; + codeRuleEntity.CreateUserId = _auth.GetUserId(); + codeRuleEntity.CreateUserName = _auth.GetUserName(); + await base.Repository.InsertAsync(codeRuleEntity); + } + } + + /// + /// 规则实体 + /// + /// 规则编码 + /// + public Task GetEntityByCode(string enCode) + { + return base.Repository.GetFirstAsync(t => t.EnabledMark == 1 && t.DeleteMark == 0 && t.EnCode == enCode); + } + #endregion + #region 单据编码处理 + /// + /// 获取当前编码规则流程号值 + /// + /// + /// + /// + /// + /// + public async Task GetSeedValue(string ruleId, int initValue, int stepNum, string dateFormatStr) + { + int value = 0; + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + var codeRuleSeed = await base.Repository.ChangeRepository>().GetFirstAsync(t => t.RuleId == ruleId); + if (codeRuleSeed == null) + { + //说明没有种子,插入一条种子 + codeRuleSeed = new SysCodeRuleSeed(); + codeRuleSeed.RuleSeedId = Guid.NewGuid().ToString(); + codeRuleSeed.CreateDate = DateTime.Now; + codeRuleSeed.ModifyDate = DateTime.Now; + codeRuleSeed.SeedValue = initValue; + codeRuleSeed.RuleId = ruleId; + + value = (int)codeRuleSeed.SeedValue; + codeRuleSeed.SeedValue += stepNum; + + await db.SysCodeRuleSeed.InsertAsync(codeRuleSeed); + } + else + { + if (dateFormatStr.Contains("dd")) + { + if ((codeRuleSeed.ModifyDate).ToDateString() != DateTime.Now.ToString("yyyy-MM-dd")) + { + codeRuleSeed.SeedValue = initValue; + } + } + else if (dateFormatStr.Contains("mm")) + { + if (((DateTime)codeRuleSeed.ModifyDate).ToString("yyyy-MM") != DateTime.Now.ToString("yyyy-MM")) + { + codeRuleSeed.SeedValue = initValue; + } + } + else if (dateFormatStr.Contains("yy")) + { + if (((DateTime)codeRuleSeed.ModifyDate).ToString("yyyy") != DateTime.Now.ToString("yyyy")) + { + codeRuleSeed.SeedValue = initValue; + } + } + codeRuleSeed.ModifyDate = DateTime.Now; + value = (int)codeRuleSeed.SeedValue; + + codeRuleSeed.SeedValue += stepNum; + + await db.SysCodeRuleSeed.UpdateAsync(codeRuleSeed); + } + db.Commit(); + return value; + } + + } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/DataCodeRule/Response/CodeRuleFormatModel.cs b/OpenAuth.App/BaseApp/DataCodeRule/Response/CodeRuleFormatModel.cs new file mode 100644 index 0000000..d7ef74c --- /dev/null +++ b/OpenAuth.App/BaseApp/DataCodeRule/Response/CodeRuleFormatModel.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.DataCodeRule.Response +{ + /// + /// 日 期:2023.03.06 + /// 描 述:编号规则 + /// + public class CodeRuleFormatModel + { + #region 实体成员 + /// + /// 项目类型 + /// + public int? itemType { get; set; } + /// + /// 项目类型名称 + /// + public string itemTypeName { get; set; } + /// + /// 格式化字符串 + /// + public string formatStr { get; set; } + /// + /// 步长 + /// + public int? stepValue { get; set; } + /// + /// 初始值 + /// + public int? initValue { get; set; } + /// + /// 备注 + /// + public string description { get; set; } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/DataSource/DataSourceApp.cs b/OpenAuth.App/BaseApp/DataSource/DataSourceApp.cs new file mode 100644 index 0000000..6b709d9 --- /dev/null +++ b/OpenAuth.App/BaseApp/DataSource/DataSourceApp.cs @@ -0,0 +1,173 @@ +using Infrastructure; +using Infrastructure.Extensions; +using OpenAuth.App.Base; +using OpenAuth.App.FormScheme.FormHelpers; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App.DataSource +{ + public class DataSourceApp : SqlSugarBaseApp + { + public DataSourceApp(ISugarUnitOfWork unitWork, + ISimpleClient repository) + : base(unitWork, repository, null) + { + + } + /// + /// 分页获取列表数据 + /// + /// + /// + /// + /// + public async Task>>> LoadDataSourceList(string keyword, int pageindex, int pagesize) + { + //定义且实例化分页数据 + RefAsync totalCount = 0; + //数据查询并返回 + var info = await this.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(keyword), t => t.Name.Contains(keyword)) + .OrderBy(t => t.Name) + .ToPageListAsync(pageindex, pagesize, totalCount); + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + /// + /// 获取实体 + /// + /// 编码 + /// + public Task GetEntityByCode(string code) + { + return this.Repository.AsQueryable().FirstAsync(t => t.Code == code); + } + /// + /// 获取sql的列 + /// + /// 编码 + /// + public async Task>> GetDataColName(string code) + { + Repository.Domain.DataSource entity = await GetEntityByCode(code); + if (entity == null || string.IsNullOrEmpty(entity.Sql) || !entity.Sql.Contains("select")) + { + return new Response>(); + } + else + { + string sql = entity.Sql; + sql = sql.Replace("={userId}", " is not null "); + sql = sql.Replace("={userAccount}", " is not null"); + sql = sql.Replace("={companyId}", " is not null"); + sql = sql.Replace("={departmentId}", " is not null"); + + sql = sql.Replace("= {userId}", " is not null "); + sql = sql.Replace("= {userAccount}", " is not null"); + sql = sql.Replace("= {companyId}", " is not null"); + sql = sql.Replace("= {departmentId}", " is not null"); + + sql = sql.Replace("=@param", " is not null"); + sql = sql.Replace("= @param", " is not null"); + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + DataTable dt = await db.Db.SqlQueryable(sql).ToDataTablePageAsync(1, 1); + List res = new List(); + foreach (DataColumn item in dt.Columns) + { + res.Add(item.ColumnName.ToLower()); + } + return new Response> + { + Result = res + }; + } + + } + + } + /// + /// 保存(新增、修改) + /// + /// 主键值 + /// 数据源实体 + /// + public async Task> SaveEntity(string keyValue, Repository.Domain.DataSource dataSourceEntity) + { + var flag = false; + dataSourceEntity.Sql = FormHelper.SqlFilters(dataSourceEntity.Sql); + if (!string.IsNullOrEmpty(keyValue)) + { + Repository.Domain.DataSource entity = await this.Repository.GetFirstAsync(t => t.Code == dataSourceEntity.Code && t.Id != keyValue); + if (entity != null) + { + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + dataSourceEntity.Id = keyValue; + dataSourceEntity.ModifyDate = DateTime.Now; + dataSourceEntity.ModifyUserId = dataSourceEntity.ModifyUserId; + dataSourceEntity.ModifyUserName = dataSourceEntity.ModifyUserName; + flag = await this.Repository.UpdateAsync(dataSourceEntity); + } + else + { + Repository.Domain.DataSource entity = await GetEntityByCode(dataSourceEntity.Code); + if (entity != null) + { + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + dataSourceEntity.Id = Guid.NewGuid().ToString(); + dataSourceEntity.CreateDate = DateTime.Now; + dataSourceEntity.CreateUserId = dataSourceEntity.CreateUserId; + dataSourceEntity.CreateUserName = dataSourceEntity.CreateUserName; + flag = await this.Repository.InsertAsync(dataSourceEntity); + } + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 删除数据源 + /// + /// 主键 + public async Task> DeleteEntity(string keyValue) + { + Repository.Domain.DataSource entity = new Repository.Domain.DataSource() + { + Id = keyValue, + }; + var flag = await this.Repository.DeleteAsync(entity); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } +} diff --git a/OpenAuth.App/BaseApp/DbTable/DbTableApp.cs b/OpenAuth.App/BaseApp/DbTable/DbTableApp.cs new file mode 100644 index 0000000..79f7b49 --- /dev/null +++ b/OpenAuth.App/BaseApp/DbTable/DbTableApp.cs @@ -0,0 +1,99 @@ +using Infrastructure; +using Infrastructure.Extensions; +using Microsoft.Extensions.Configuration; +using OpenAuth.App.Base; +using OpenAuth.App.CodeTable; +using OpenAuth.App.Request; +using OpenAuth.App.FormScheme.FormHelpers; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; +using static Dm.net.buffer.ByteArrayBuffer; + +namespace OpenAuth.App.DbTable +{ + public class DbTableApp : SqlSugarBaseApp + { + private IConfiguration _configuration; + public DbTableApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IConfiguration configuration) : base(unitWork, repository, null) + { + _configuration = configuration; + } + + /// + /// 创建表信息 + /// + /// 数据库编码 + /// 数据表信息 + /// + public Response AddTable(string dbcode, DbTableReq dbTableReq) + { + if (dbTableReq.DbColumnInfoList == null || !dbTableReq.DbColumnInfoList.Any()) + throw new Exception("请添加数据列"); + using (var db = this.CodeClient(dbcode, _configuration)) + { + var typeBuilder = db.DynamicBuilder().CreateClass(dbTableReq.TableName, new SugarTable() { TableName = dbTableReq.TableName, TableDescription = dbTableReq.Description }); + dbTableReq.DbColumnInfoList.ForEach(u => + { + typeBuilder.CreateProperty(u.DbColumnName, typeof(string), new SugarColumn() + { + IsPrimaryKey = u.IsPrimarykey == 1, + IsIdentity = u.IsIdentity == 1, + ColumnDataType = u.DataType, + Length = u.Length, + IsNullable = u.IsNullable == 1, + DecimalDigits = u.DecimalDigits, + ColumnDescription = u.ColumnDescription, + }); + }); + db.CodeFirst.InitTables(typeBuilder.BuilderType()); + return new Response() + { + Code = 200, + Result = true, + Message = "创建成功" + }; + } + } + /// + /// 创建字段 + /// + /// 数据库编码 + /// 表字段 + /// + public Response AddColumn(string dbcode, DbColumnInput dbColumnInput) + { + using (var db = this.CodeClient(dbcode, _configuration)) + { + var column = new DbColumnInfo + { + ColumnDescription = dbColumnInput.ColumnDescription, + DbColumnName = dbColumnInput.DbColumnName, + IsIdentity = dbColumnInput.IsIdentity == 1, + IsNullable = dbColumnInput.IsNullable == 1, + IsPrimarykey = dbColumnInput.IsPrimarykey == 1, + Length = dbColumnInput.Length, + DecimalDigits = dbColumnInput.DecimalDigits, + DataType = dbColumnInput.DataType + }; + + db.DbMaintenance.AddColumn(dbColumnInput.TableName, column); + db.DbMaintenance.AddColumnRemark(dbColumnInput.DbColumnName, dbColumnInput.TableName, dbColumnInput.ColumnDescription); + if (column.IsPrimarykey) + db.DbMaintenance.AddPrimaryKey(dbColumnInput.TableName, dbColumnInput.DbColumnName); + return new Response() + { + Code = 200, + Result = true, + Message = "创建成功" + }; + } + } + } +} diff --git a/OpenAuth.App/BaseApp/DbTable/Request/DbColumnInput.cs b/OpenAuth.App/BaseApp/DbTable/Request/DbColumnInput.cs new file mode 100644 index 0000000..5e3be9d --- /dev/null +++ b/OpenAuth.App/BaseApp/DbTable/Request/DbColumnInput.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class DbColumnInput + { + public string TableName { get; set; } + + public string DbColumnName { get; set; } + + public string DataType { get; set; } + + public int Length { get; set; } + + public string ColumnDescription { get; set; } + + public int IsNullable { get; set; } + + public int IsIdentity { get; set; } + + public int IsPrimarykey { get; set; } + + public int DecimalDigits { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/DbTable/Request/DbTableReq.cs b/OpenAuth.App/BaseApp/DbTable/Request/DbTableReq.cs new file mode 100644 index 0000000..c542042 --- /dev/null +++ b/OpenAuth.App/BaseApp/DbTable/Request/DbTableReq.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class DbTableReq + { + public string TableName { get; set; } + + public string Description { get; set; } + + public List DbColumnInfoList { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/Extensions/OpenJobExt.cs b/OpenAuth.App/BaseApp/Extensions/OpenJobExt.cs new file mode 100644 index 0000000..03b509f --- /dev/null +++ b/OpenAuth.App/BaseApp/Extensions/OpenJobExt.cs @@ -0,0 +1,55 @@ +using System; +using System.Linq; +using Infrastructure; +using OpenAuth.Repository.Domain; +using Quartz; + +namespace OpenAuth.App.Extensions +{ + /// + /// 定时任务扩展 + /// + public static class OpenJobExt + { + /// + /// 启动定时任务 + /// + /// + /// 一个Quartz Scheduler + public static void Start(this SysOpenJob job, IScheduler scheduler) + { + var jobBuilderType = typeof(JobBuilder); + var method = jobBuilderType.GetMethods().FirstOrDefault( + x => x.Name.Equals("Create", StringComparison.OrdinalIgnoreCase) && + x.IsGenericMethod && x.GetParameters().Length == 0) + ?.MakeGenericMethod(Type.GetType(job.JobCall)); + + var jobBuilder = (JobBuilder) method.Invoke(null, null); + + IJobDetail jobDetail = jobBuilder.WithIdentity(job.Id.ToString()).Build(); + jobDetail.JobDataMap[Define.JOBMAPKEY] = job.Id; //传递job信息 + ITrigger trigger = TriggerBuilder.Create() + .WithCronSchedule(job.Cron) + .WithIdentity(job.Id.ToString()) + .StartNow() + .Build(); + scheduler.ScheduleJob(jobDetail, trigger); + } + + /// + /// 停止一个定时任务 + /// + /// + /// + public static void Stop(this SysOpenJob job, IScheduler scheduler) + { + TriggerKey triggerKey = new TriggerKey(job.Id.ToString()); + // 停止触发器 + scheduler.PauseTrigger(triggerKey); + // 移除触发器 + scheduler.UnscheduleJob(triggerKey); + // 删除任务 + scheduler.DeleteJob(new JobKey(job.Id.ToString())); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Files/FileApp.cs b/OpenAuth.App/BaseApp/Files/FileApp.cs new file mode 100644 index 0000000..93db12b --- /dev/null +++ b/OpenAuth.App/BaseApp/Files/FileApp.cs @@ -0,0 +1,215 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Infrastructure; +using Infrastructure.Extensions; +using Infrastructure.Helpers; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + /// + /// 文件管理 + /// + public class FileApp : SqlSugarBaseApp + { + private ILogger _logger; + private string _filePath; + private string _dbFilePath; //数据库中的文件路径 + private string _dbThumbnail; //数据库中的缩略图路径 + + public FileApp( + IOptions setOptions, + ISugarUnitOfWork unitWork, + ISimpleClient repository, + ILogger logger, + IAuth auth) : base(unitWork, repository, auth) + { + _logger = logger; + _filePath = setOptions.Value.UploadPath; + if (string.IsNullOrEmpty(_filePath)) + { + _filePath = AppContext.BaseDirectory; + } + } + + /// + /// 加载附件列表 + /// + public async Task LoadOld(QueryFileListReq request) + { + int totalCount = 0; + var result = new TableData(); + var objs = Repository.AsQueryable(); + objs.WhereIF(!string.IsNullOrEmpty(request.key), u => u.FileName.Contains(request.key) || u.FilePath.Contains(request.key)); + + result.data = await objs.OrderByDescending(u => u.CreateTime).ToPageListAsync(request.page, request.limit, totalCount); + result.count = totalCount; + + return result; + } + /// + /// 加载附件列表 + /// + public async Task>>> Load(QueryFileListReq request) + { + int totalCount = 0; + var objs = Repository.AsQueryable(); + objs.WhereIF(!string.IsNullOrEmpty(request.key), u => u.FileName.Contains(request.key) || u.FilePath.Contains(request.key)); + var data = await objs.OrderByDescending(u => u.CreateTime).ToPageListAsync(request.page, request.limit, totalCount); + return new Response>> + { + Result = new PageInfo> + { + Items = data, + Total = totalCount + } + }; + } + + /// + /// 批量添加附件 + /// + /// + /// + public List Add(IFormFileCollection files) + { + if (!_auth.CheckLogin()) + { + throw new Exception("必需登录才能上传附件"); + } + + var result = new List(); + foreach (var file in files) + { + result.Add(Add(file)); + } + + return result; + } + + public SysUploadFile Add(IFormFile file) + { + if (file != null) + { + _logger.LogInformation("收到新文件: " + file.FileName); + _logger.LogInformation("收到新文件: " + file.Length); + } + else + { + _logger.LogWarning("收到新文件为空"); + } + + if (file != null && file.Length > 0 ) + { + using (var binaryReader = new BinaryReader(file.OpenReadStream())) + { + var fileName = Path.GetFileName(file.FileName); + var data = binaryReader.ReadBytes((int)file.Length); + SaveFile(fileName, data); + + var filedb = new SysUploadFile + { + Id = SqlSugar.SnowFlakeSingle.instance.getID(), + FilePath = _dbFilePath, + Thumbnail = _dbThumbnail, + FileName = fileName, + FileSize = file.Length.ToInt(), + CreateUserName = _auth.GetUserName(), + FileType = Path.GetExtension(fileName), + Extension = Path.GetExtension(fileName), + CreateTime = DateTime.Now, + }; + Repository.Insert(filedb); + return filedb; + } + } + else + { + throw new Exception("文件过大"); + } + } + + /// + /// 删除附件 + /// + /// + public void Delete(long[] ids) + { + var files = base.Repository.GetList(u => ids.Contains(u.Id)).ToList(); + for (int i = 0; i < files.Count(); i++) + { + var uploadPath = Path.Combine(_filePath, files[i].FilePath); + FileHelper.FileDel(uploadPath); + if (!string.IsNullOrEmpty(files[i].Thumbnail)) + { + FileHelper.FileDel(Path.Combine(_filePath, files[i].Thumbnail)); + } + Repository.Delete(u => u.Id == files[i].Id); + } + } + + /// + /// 存储文件,如果是图片文件则生成缩略图 + /// + /// + /// + /// + private void SaveFile(string fileName, byte[] fileBuffers) + { + string folder = DateTime.Now.ToString("yyyyMMdd"); + + //判断文件是否为空 + if (string.IsNullOrEmpty(fileName)) + { + throw new Exception("文件名不能为空"); + } + + //判断文件是否为空 + if (fileBuffers.Length < 1) + { + throw new Exception("文件不能为空"); + } + + var uploadPath = Path.Combine(_filePath, folder); + _logger.LogInformation("文件写入:" + uploadPath); + if (!Directory.Exists(uploadPath)) + { + Directory.CreateDirectory(uploadPath); + } + + var ext = Path.GetExtension(fileName).ToLower(); + string newName = GenerateId.GenerateOrderNumber() + ext; + + using (var fs = new FileStream(Path.Combine(uploadPath, newName), FileMode.Create)) + { + fs.Write(fileBuffers, 0, fileBuffers.Length); + fs.Close(); + + //生成缩略图 + if (ext.Contains(".jpg") || ext.Contains(".jpeg") || ext.Contains(".png") || ext.Contains(".bmp") || + ext.Contains(".gif")) + { + string thumbnailName = GenerateId.GenerateOrderNumber() + ext; + ImgHelper.MakeThumbnail(Path.Combine(uploadPath, newName), Path.Combine(uploadPath, thumbnailName)); + _dbThumbnail = Path.Combine(folder, thumbnailName); + } + + + _dbFilePath = Path.Combine(folder, newName); + } + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Files/Request/QueryFileListReq.cs b/OpenAuth.App/BaseApp/Files/Request/QueryFileListReq.cs new file mode 100644 index 0000000..13d2a2b --- /dev/null +++ b/OpenAuth.App/BaseApp/Files/Request/QueryFileListReq.cs @@ -0,0 +1,7 @@ +namespace OpenAuth.App.Request +{ + public class QueryFileListReq : PageReq + { + //todo:添加自己的请求字段 + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/FormModule/FormModuleApp.cs b/OpenAuth.App/BaseApp/FormModule/FormModuleApp.cs new file mode 100644 index 0000000..cc15f16 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormModule/FormModuleApp.cs @@ -0,0 +1,703 @@ +using DocumentFormat.OpenXml.Spreadsheet; +using Infrastructure; +using Microsoft.Extensions.Configuration; +using NPOI.HSSF.UserModel; +using NPOI.SS.UserModel; +using OpenAuth.App.Base; +using OpenAuth.App.FormModule.Request; +using OpenAuth.App.Interface; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System.Linq.Expressions; +using System.Text; +using Castle.Core.Internal; +using DocumentFormat.OpenXml.Drawing.Charts; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App.FormModule +{ + public class FormModuleApp : SqlSugarBaseApp + { + private IConfiguration _configuration; + + public FormModuleApp(ISugarUnitOfWork unitWork, + ISimpleClient repository, IAuth auth, + IConfiguration configuration) : base(unitWork, repository, auth) + { + _configuration = configuration; + } + + #region 查询数据 + + /// + /// 模块获取分页列表 + /// + /// 筛选关键词 + /// 父级菜单 + /// 当前页 + /// 每页条数 + /// + public async Task>>> GetModulePageList(string keyword, + string pmoduleid, int pageindex, int pagesize) + { + //定义且实例化分页数据 + RefAsync totalCount = 0; + //PageModel page = new PageModel { PageIndex = pageindex, PageSize = pagesize, TotalCount = totalCount }; + + ////筛选条件处理 + //Expression> expression = PredicateBuilder.True(); ; + //if (!string.IsNullOrEmpty(keyword)) + //{ + // expression = expression.And(t => t.Code.Contains(keyword) || t.Name.Contains(keyword)); + //} + //if (!string.IsNullOrEmpty(pmoduleid)) + //{ + // expression = expression.And(t => t.PmoduleId == pmoduleid); + //} + + //多租户 + //if (ConfigHelper.GetConfig().IsSass) + //{ + // expression = expression.And(t => t.IsMain != 1); + //} + + //数据查询并返回 + var info = await this.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(keyword), t => t.Code.Contains(keyword) || t.Name.Contains(keyword)) + .WhereIF(!string.IsNullOrEmpty(pmoduleid), t => t.PmoduleId == pmoduleid) + .OrderByDescending(t => t.CreateDate) + .ToPageListAsync(pageindex, pagesize, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + + /// + /// 获取列表 + /// + /// + /// + public async Task>> GetList() + { + var info = await this.Repository.GetListAsync(r => r.EnabledMark == 1); + return new Response> + { + Result = info + }; + } + + /// + /// 获取实体数据 + /// + /// 发布表单模板的id(formmodule的id) + /// + public async Task> GetForm(string id) + { + var info = await this.Repository.GetByIdAsync(id); + return new Response + { + Result = info + }; + } + + /// + /// 根据菜单主键id获取实体数据 + /// + /// 菜单id(SYSModule的id) + /// + public async Task> GetFormByModuleId(string id) + { + var info = await this.Repository.GetFirstAsync(r => r.ModuleId == id); + return new Response + { + Result = info + }; + } + + /// + /// 根据编号获取实体数据 + /// + /// 编号 + /// + public async Task> GetFormByCode(string code) + { + var info = await this.Repository.GetFirstAsync(r => r.Code == code); + return new Response + { + Result = info + }; + } + + /// + /// 获取设计数据 + /// + /// 编码 + /// + public async Task> GetEntityByCode(string code) + { + var info = new FormModuleSchemeReq(); + info.Entity = await this.Repository.GetFirstAsync(r => r.Code == code); + if (info.Entity != null) + { + info.FormScheme = await base.Repository + .ChangeRepository>() + .GetFirstAsync(r => r.Id == info.Entity.FormVerison); + } + + return new Response + { + Result = info + }; + } + + #endregion + + #region 增删改 + + #region 添加 + + /// + /// 保存模块功能实体(新增、修改)(系统功能菜单,按钮,视图,表单四个表) + /// + /// 主键值 + /// 实体 + /// 按钮列表 + /// 视图列集合 + /// 表单字段 + public async Task> SaveEntity(string keyValue, FormModuleEntity entity, SysModule module, + List moduleElement, List moduleColumn, List moduleForm) + { + var mid = entity.ModuleId; + var oldModuleEntity = await this.Repository.AsSugarClient().Queryable().Where(r => r.Id == mid) + .FirstAsync(); + if (oldModuleEntity == null) + { + module.Id = mid; + mid = string.Empty; + } + + using (var uwo = base.UnitWork.CreateContext()) + { + #region 添加系统菜单及下属菜单信息 + + #region 添加 + + if (string.IsNullOrEmpty(module.ParentId) || module.ParentId == "-1") + { + module.ParentId = "0"; + } + + if (string.IsNullOrEmpty(mid)) + { + // 新增 + if (string.IsNullOrEmpty(module.Id)) + { + module.Id = Guid.NewGuid().ToString(); + } + + //module.F_CreateDate = DateTime.Now; + //module.F_CreateUserId = this.GetUserId(); + //module.F_CreateUserName = this.GetUserName(); + //module.F_DeleteMark = 0; + await uwo.SysModule.InsertAsync(module); + } + else + { + // 编辑 + await uwo.SysModule.UpdateAsync(u => new SysModule + { + ParentId = module.ParentId, + IconName = module.IconName, + ParentName = module.ParentName, + SortNo = module.SortNo, + Encode = module.Encode, + IsSys = module.IsSys, + Code = module.Code, + Status = module.Status, + CascadeId = module.CascadeId, + Url = module.Url + }, u => u.Id == mid); + await uwo.SysModuleElement.DeleteAsync(t => t.ModuleId == mid); + await uwo.SysModuleColumn.DeleteAsync(t => t.ModuleId == mid); + await uwo.SysModuleForm.DeleteAsync(t => t.ModuleId == mid); + } + + int num = 0; + if (moduleElement != null) + { + foreach (var item in moduleElement) + { + item.Sort = num; + item.ModuleId = module.Id; + //item.F_ModuleButtonId = Guid.NewGuid().ToString(); + if (string.IsNullOrEmpty(item.Id)) + { + item.Id = Guid.NewGuid().ToString(); + } + + await uwo.SysModuleElement.InsertAsync(item); + num++; + } + } + + if (moduleColumn != null) + { + num = 0; + foreach (var item in moduleColumn) + { + item.SortCode = num; + item.ModuleId = module.Id; + //item.F_ModuleColumnId = Guid.NewGuid().ToString(); + if (string.IsNullOrEmpty(item.ModuleColumnId)) + { + item.ModuleColumnId = Guid.NewGuid().ToString(); + } + + await uwo.SysModuleColumn.InsertAsync(item); + num++; + } + } + + if (moduleForm != null) + { + num = 0; + foreach (var item in moduleForm) + { + item.SortCode = num; + item.ModuleId = module.Id; + //item.F_ModuleFormId = Guid.NewGuid().ToString(); + if (string.IsNullOrEmpty(item.ModuleFormId)) + { + item.ModuleFormId = Guid.NewGuid().ToString(); + } + + await uwo.SysModuleForm.InsertAsync(item); + num++; + } + } + + #endregion + + #region 权限 + + if (!string.IsNullOrEmpty(entity.ModuleId)) + { + var objectList = await this.Repository.AsSugarClient().Queryable() + .Where(r => r.ModuleId == entity.ModuleId).ToListAsync(); + + List buttonList = new List(); + List columnList = new List(); + List formList = new List(); + + if (moduleElement != null) + { + foreach (var item in moduleElement) + { + buttonList.Add(item.Id); + } + } + + if (moduleColumn != null) + { + foreach (var item in moduleColumn) + { + columnList.Add(item.ModuleColumnId); + } + } + + if (moduleForm != null) + { + foreach (var item in moduleForm) + { + formList.Add(item.ModuleFormId); + } + } + + + if (buttonList.Count == 0) + { + await uwo.SysRoleElement.DeleteAsync(r => objectList.Select(r => r.Id).Contains(r.ElementId)); + } + else + { + await uwo.SysRoleElement.DeleteAsync(r => !buttonList.Contains(r.ElementId)); + } + + if (columnList.Count == 0) + { + //await moduleService.BaseRepository().Delete(t => t.F_ItemType == 3 && t.F_ParentId == moduleEntity.F_ModuleId); + } + else + { + await uwo.SysRoleElement.DeleteAsync(r => !buttonList.Contains(r.ElementId)); + } + + if (formList.Count == 0) + { + //await moduleService.BaseRepository().Delete(t => t.F_ItemType == 4 && t.F_ParentId == moduleEntity.F_ModuleId); + } + else + { + await uwo.SysRoleElement.DeleteAsync(r => !buttonList.Contains(r.ElementId)); + } + } + + #endregion + + #endregion + + #region 表单发布模板信息添加 + + entity.ModuleId = module.Id; + if (string.IsNullOrEmpty(keyValue)) + { + var user = _auth.GetCurrentUser().User; + entity.Id = Guid.NewGuid().ToString(); + entity.CreateDate = DateTime.Now; + entity.CreateUserId = user.Id.ToString(); + entity.CreateUserName = user.Name; + + await uwo.FormModuleEntity.InsertAsync(entity); + } + else + { + //编辑 + var user = _auth.GetCurrentUser().User; + entity.Id = keyValue; + entity.ModifyDate = DateTime.Now; + entity.ModifyUserId = user.Id.ToString(); + entity.ModifyUserName = user.Name; + await uwo.FormModuleEntity.UpdateAsync(entity); + } + + #endregion + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "操作成功" : "操作失败" + }; + } + } + + + /// + /// 更新状态 + /// + /// 主键 + /// 状态 + /// + public async Task> UpdateState(string keyValue, int state) + { + var entity = await this.Repository.GetByIdAsync(keyValue); + if (entity != null) + { + using (var uwo = UnitWork.CreateContext()) + { + await uwo.FormModuleEntity.UpdateAsync(r => new FormModuleEntity + { + EnabledMark = state + }, r => r.Id == keyValue); + + await uwo.SysModule.UpdateAsync(r => new SysModule + { + Status = state + }, r => r.Id == keyValue); + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "操作成功" : "操作失败" + }; + } + } + else + { + return new Response + { + Result = false, + Message = "数据丢失" + }; + } + } + + public async Task> DeleteForm(string keyValue) + { + var entity = await this.Repository.GetByIdAsync(keyValue); + if (entity != null) + { + using (var uwo = UnitWork.CreateContext()) + { + await uwo.FormModuleEntity.DeleteByIdAsync(keyValue); + await uwo.SysModule.DeleteByIdAsync(entity.ModuleId); + await uwo.SysModuleColumn.DeleteAsync(r => r.ModuleId == entity.ModuleId); + await uwo.SysModuleElement.DeleteAsync(r => r.ModuleId == entity.ModuleId); + await uwo.SysModuleForm.DeleteAsync(r => r.ModuleId == entity.ModuleId); + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "操作成功" : "操作失败" + }; + } + } + else + { + return new Response + { + Result = false, + Message = "数据不存在" + }; + } + } + + /// + /// 根据菜单主键id删除表单发布模板信息 + /// + /// 菜单id(Sysmodule的主键) + public async Task> DeleteEntityByModuleId(string keyValue) + { + using (var uwo = UnitWork.CreateContext()) + { + await uwo.FormModuleEntity.DeleteAsync(r => r.ModuleId == keyValue); + await uwo.SysModule.DeleteByIdAsync(keyValue); + await uwo.SysModuleColumn.DeleteAsync(r => r.ModuleId == keyValue); + await uwo.SysModuleElement.DeleteAsync(r => r.ModuleId == keyValue); + await uwo.SysModuleForm.DeleteAsync(r => r.ModuleId == keyValue); + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "操作成功" : "操作失败" + }; + } + } + + #endregion + + #endregion + + + #region 扩展方法 + + /// + /// 判断数据表字段重复 + /// + /// 主键值 + /// 表名 + /// 主键名 + /// 数据字段 + /// + public async Task> ExistFiled(string keyValue, string tableName, string keyName, + string filedsJson) + { + StringBuilder strSql = new StringBuilder(); + var tableNameList = tableName.Split("."); + var dbCode = string.Empty; + if (tableNameList.Length == 2) + { + dbCode = tableNameList[0]; + tableName = tableNameList[1]; + } + + strSql.Append("select * from " + tableName + " t where 1=1 "); + if (!string.IsNullOrEmpty(keyValue)) + { + strSql.Append(" AND \"" + keyName + "\" !=\'" + keyValue + "\'"); + } + + var args = filedsJson.ToJObject(); + foreach (var item in args.Properties()) + { + if (!string.IsNullOrEmpty(item.Value.ToString())) + { + strSql.Append(" AND \"" + item.Name + "\" = '" + item.Value + "'"); + } + } + + var dt = await this.Repository.AsSugarClient().SqlQueryable(strSql.ToString()).ToListAsync(); + + if (dt.Count == 0) + { + return new Response + { + Result = true + }; + } + else + { + return new Response + { + Result = false, + Message = "字段重复" + }; + } + } + + #endregion + + #region 获取数据库数据列表 + + /// + /// 数据表列表 + /// + /// 数据库编码 + /// 是否读取存储区 + /// + public Response> GetTableList(string code, string key, bool isCache = false) + { + using (var db = this.CodeClient(code, _configuration)) + { + var list = db.DbMaintenance.GetTableInfoList(isCache); + //var list = db.DbMaintenance.GetTableInfoList((dbtype, sql) => + //{ + // if (dbtype == SqlSugar.DbType.Kdbndp) + // { + // return sql.Replace(@"where relkind = 'r' and c.oid > 16384 and c.relnamespace != 99 and c.relname not like '%pl_profiler_saved%' order by relname", @" INNER JOIN PG_NAMESPACE AS n ON c.relnamespace = n.oid where relkind = 'r' and c.oid > 16384 and c.relnamespace != 99 and c.relname not like '%pl_profiler_saved%' and n.nspname = 'public' order by relname"); + // } + // return sql; + //}); + var info = list.FindAll(t => + t.DbObjectType == DbObjectType.Table && t.Name.ToLower() != "lr_db_codecolumns" && + t.Name.ToLower() != "lr_db_codetable" && t.Name.ToLower() != "lr_db_history") + .WhereIF(!key.IsNullOrEmpty(), t => t.Name.ToLower().Contains(key.ToLower())).ToList(); + return new Response> + { + Result = info + }; + } + } + + #endregion + + #region 导出 + public Response ListToExcel(System.Data.DataTable list, List headers) + { + Response response = new Response(); + try + { + HSSFWorkbook workbook = new HSSFWorkbook(); + #region 内容样式 + + IFont font1 = workbook.CreateFont(); //创建一个字体样式对象 + font1.FontName = "Microsoft YaHei"; //和excel里面的字体对应 + //font1.Boldweight = short.MaxValue;//字体加粗 + font1.FontHeightInPoints = 12; //字体大小 + ICellStyle style = workbook.CreateCellStyle(); //创建样式对象 + style.BorderBottom = BorderStyle.Thin; + style.BorderLeft = BorderStyle.Thin; + style.BorderRight = BorderStyle.Thin; + style.BorderTop = BorderStyle.Thin; + style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; + style.VerticalAlignment = VerticalAlignment.Center; + style.SetFont(font1); //将字体样式赋给样式对象 + style.WrapText = true; + + #endregion + + #region 标题样式 + + IFont font = workbook.CreateFont(); //创建一个字体样式对象 + font.FontName = "Microsoft YaHei"; //和excel里面的字体对应 + font.Boldweight = (short)FontBoldWeight.Bold; //字体加粗 + font.FontHeightInPoints = 12; //字体大小 + ICellStyle style1 = workbook.CreateCellStyle(); //创建样式对象 + style1.BorderBottom = BorderStyle.Thin; + style1.BorderLeft = BorderStyle.Thin; + style1.BorderRight = BorderStyle.Thin; + style1.BorderTop = BorderStyle.Thin; + style1.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; + style1.VerticalAlignment = VerticalAlignment.Center; + style1.SetFont(font); //将字体样式赋给样式对象 + + #endregion + + #region 创建表头 + int m = list.Rows.Count / 60000+1; + for (int k = 0; k < m; k++) + { + ISheet sheet = workbook.CreateSheet("Sheet"+k.ToString()); + IRow rowHeader = sheet.CreateRow(0); + rowHeader.Height = 20 * 30; + for (int i = 0; i < headers.Count; i++) + { + ModuleColumn header = headers[i]; + rowHeader.CreateCell(i); + rowHeader.Cells[i].CellStyle = style1; + rowHeader.Cells[i].SetCellValue(header.value); + sheet.SetColumnWidth(i, 20 * 350); + } + #endregion + + #region 填充数据 + var val = (k + 1) * 60000; + var num = 60000; + if (val > list.Rows.Count) + { + num=list.Rows.Count-k*60000; + } + for (int i = 0; i < num; i++) //循环数据 + { + var item = list.Rows[k*60000+i]; //获取数据 + IRow dataRow = sheet.CreateRow(i + 1); //创建行 + for (int j = 0; j < headers.Count; j++) //循环表头 + { + //数据处理 + var objValue = ""; + if (list.Columns.Contains(headers[j].key)) + { + objValue = item[headers[j].key].ToString(); + } + else + { + objValue = ""; + } + //创建单元格 + dataRow.CreateCell(j); + dataRow.Cells[j].CellStyle = style; //添加单元格样式 + if (objValue != null && !string.IsNullOrEmpty(objValue.ToString())) + { + dataRow.Cells[j].SetCellValue(objValue.ToString()); //填充Excel单元格 + } + else + { + dataRow.Cells[j].SetCellValue(""); //填充Excel单元格 + } + } + } + } + + #endregion + + response.Result = new MemoryStream(); + workbook.Write(response.Result); + workbook = null; + response.Result.Close(); + response.Result.Dispose(); + response.Code = 200; + response.Message = "获取成功"; + } + catch (Exception ex) + { + response.Code = 500; + response.Message = ex.Message; + } + return response; + } + #endregion + } + public class ModuleColumn + { + public string key { get; set; } + public string value { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/FormModule/Request/FormModuleReq.cs b/OpenAuth.App/BaseApp/FormModule/Request/FormModuleReq.cs new file mode 100644 index 0000000..e3dd48f --- /dev/null +++ b/OpenAuth.App/BaseApp/FormModule/Request/FormModuleReq.cs @@ -0,0 +1,38 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + /// + /// 提交参数 + /// 2024.03.04 + /// xiaojiejie + /// + public class FormModuleReq + { + /// + /// 设计数据 + /// + public FormModuleEntity FormModuleEntity { get; set; } + /// + /// 功能模块实体 + /// + public SysModule SysModule { get; set; } + /// + /// 按钮列表 + /// + public List SysModuleElement { get; set; } + /// + /// 视图列集合 + /// + public List SysModuleColumn { get; set; } + /// + /// 表单字段集合 + /// + public List SysModuleForm { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormModule/Request/FormModuleSchemeReq.cs b/OpenAuth.App/BaseApp/FormModule/Request/FormModuleSchemeReq.cs new file mode 100644 index 0000000..cd8a40e --- /dev/null +++ b/OpenAuth.App/BaseApp/FormModule/Request/FormModuleSchemeReq.cs @@ -0,0 +1,21 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormModule.Request +{ + public class FormModuleSchemeReq + { + /// + /// 设计数据 + /// + public FormModuleEntity Entity { get; set; } + /// + /// 表单模板 + /// + public Repository.Domain.FormScheme FormScheme { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/FormHelpers/DBCommonHelper.cs b/OpenAuth.App/BaseApp/FormScheme/FormHelpers/DBCommonHelper.cs new file mode 100644 index 0000000..87e1214 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/FormHelpers/DBCommonHelper.cs @@ -0,0 +1,312 @@ +using Newtonsoft.Json.Converters; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using DbType = SqlSugar.DbType; +namespace OpenAuth.App.FormScheme.FormHelpers +{ + public class DBCommonHelper + { + /// + /// 获取fsql的数据库类型 + /// + /// SqlServer,Oracle,MySql,PostgreSQL,Dameng,Kdbndp + /// + public static DbType GetDbType(string dbtype) + { + switch (dbtype) + { + case "SqlServer": + return DbType.SqlServer; + case "Oracle": + return DbType.Oracle; + case "MySql": + return DbType.MySql; + case "PostgreSQL": + return DbType.PostgreSQL; + case "Dameng": + return DbType.Dm;//达梦 + case "Kdbndp": + return DbType.Kdbndp;//人大金仓 + case "Sqlite": + return DbType.Sqlite;//Sqlite + default: + return DbType.MySql; + } + } + + /// + /// 将IDataReader转换为DataTable + /// + /// datatable + /// IDataReader + public static DataTable IDataReaderToDataTable(IDataReader reader) + { + using (reader) + { + DataTable objDataTable = new DataTable("Table"); + int intFieldCount = reader.FieldCount; + for (int intCounter = 0; intCounter < intFieldCount; ++intCounter) + { + objDataTable.Columns.Add(reader.GetName(intCounter).ToLower(), reader.GetFieldType(intCounter)); + } + objDataTable.BeginLoadData(); + object[] objValues = new object[intFieldCount]; + while (reader.Read()) + { + reader.GetValues(objValues); + objDataTable.LoadDataRow(objValues, true); + } + reader.Close(); + reader.Dispose(); + objDataTable.EndLoadData(); + return objDataTable; + } + } + + /// + /// 将datatable的字段格式化为小写 + /// + /// + /// + public static DataTable DtColToLow(DataTable dt) + { + foreach (DataColumn item in dt.Columns) + { + //item.ColumnName = item.ColumnName.ToLower(); + item.ColumnName = item.ColumnName;//不转小写 + } + return dt; + } + + /// + /// 判断是否为匿名对象 + /// + /// + /// + public static bool CheckIfAnonymousType(Type type) + { + if (type == null) + throw new ArgumentNullException("type"); + + return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false) + && type.IsGenericType && type.Name.Contains("AnonymousType") + && (type.Name.StartsWith("<>")) + && (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic; + } + + ///// + ///// 将不是匿名对象转化为字典数据 + ///// + ///// + ///// + //public static object ConvertToDic(object param) + //{ + // //判断是否匿名,不是匿名就转一下,是就直接加进去 + // if (param != null && !CheckIfAnonymousType(param.GetType())) + // { + // return param.ToObject>(); + // } + // return param; + //} + /// + /// 获取c#字段类型 + /// + /// 数据库类型 + /// 数据库字段类型 + /// + public static string GetCsType(DbType dbtype, string dbType) + { + string csType = "string"; + switch (dbType.ToLower()) + { + case "varchar": + csType = "string"; + break; + case "varchar2": + csType = "string"; + break; + case "char": + case "nchar": + case "nvarchar": + case "nvarchar2": + csType = "string"; + break; + case "text": + csType = "string"; + break; + case "ntext": + case "longtext": + case "clob": + case "nclog": + csType = "text"; + break; + case "int2": + csType = "int"; + break; + case "integer": + csType = "int"; + break; + case "int4": + csType = "int"; + break; + case "mediumint":// mysql + case "year": + csType = "int"; + break; + case "bigint": + csType = "long"; + break; + case "smallint": + csType = "short"; + break; + case "bit": + csType = "bool"; + break; + case "tinyint": + csType = "byte"; + break; + case "decimal": + csType = "decimal"; + break; + case "numeric": + csType = "decimal"; + break; + case "number": + csType = "int"; + break; + case "number(8,2)": + csType = "double"; + break; + case "money": + case "bool": + csType = "bool"; + break; + case "smallmoney": + csType = "decimal"; + break; + case "real": + case "double": + if (dbtype == DbType.MySql) + { + csType = "double"; + } + else + { + csType = "float"; + } + break; + case "float": + if (dbtype == DbType.MySql) + { + csType = "float"; + } + else + { + csType = "double"; + } + break; + case "float4": + csType = "double"; + break; + case "float8": + csType = "double"; + break; + case "date": + csType = "DateTime"; + break; + case "datetime": + csType = "DateTime"; + break; + case "datetime2": + csType = "DateTime"; + break; + case "smalldatetime": + csType = "DateTime"; + break; + case "datetimeoffset": + csType = "DateTimeOffset"; + break; + case "time": + csType = "DateTime"; + break; + case "timestamp": + if (dbtype == DbType.MySql) + { + csType = "DateTime"; + + } + else + { + csType = "DateTime"; + } + break; + case "binary": + case "varbinary": + case "image": + + case "tinyblob": + case "blob": + case "mediumblob": + case "longblob": + csType = "byte[]"; + break; + case "uniqueidentifier": + csType = "Guid"; + break; + case "variant": + csType = "Object"; + break; + case "timestamp without time zone": + csType = "TimeSpan"; + break; + // mysql + case "set": + case "enum": + csType = "Enum"; + break; + case "point": + case "linestring": + case "polygon": + case "geometry": + case "multipoint": + case "multilinestring": + case "multipolygon": + //case "geometrycollection": + // csType = "MygisGeometry"; + case "geometrycollection": + csType = "string"; + break; + } + + return csType; + } + + public static string GetDbType(DbType dbtype, string dbType, string csType) + { + if (!string.IsNullOrEmpty(dbType)) + { + return dbType; + } + if (csType == "text") + { + if (DbType.Oracle == dbtype) + { + return "clob"; + } + else + { + return "text"; + } + } + + return string.Empty; + } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/FormHelpers/FormHelper.cs b/OpenAuth.App/BaseApp/FormScheme/FormHelpers/FormHelper.cs new file mode 100644 index 0000000..475564f --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/FormHelpers/FormHelper.cs @@ -0,0 +1,1444 @@ +using Infrastructure; +using Infrastructure.Extensions; +using Microsoft.AspNetCore.Components; +using Newtonsoft.Json.Linq; +using OpenAuth.App.FormScheme.Response; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.FormHelpers +{ + public static class FormHelper + { + /// + /// 获取保存sql语句 + /// + /// + /// + /// + /// + /// + /// + public static List GetSaveSql(FormSchemeModel formSchemeModel, JObject dataJson, string pkey, string pkeyValue, bool isUpdate) + { + List list = new List(); + + // 获取主子表 + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + List childrenTables = formSchemeModel.Db.FindAll(t => t.Type == "chlid"); + + // 对表组件按表进行分类 + Dictionary> tableMap = new Dictionary>(); + Dictionary girdTableMap = new Dictionary(); + + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Components) + { + if (string.IsNullOrEmpty(component.Table)) + { + continue; + } + if (!tableMap.ContainsKey(component.Table)) + { + tableMap[component.Table] = new List(); + } + + if (component.Type == "gridtable") + { + tableMap[component.Table].AddRange(component.children); + girdTableMap.Add(component.Table, component); + } + else + { + if (component.Prop == pkey) + { + pkey = component.Field; + } + tableMap[component.Table].Add(component); + } + } + } + + if (isUpdate) + { + list.Add(GetUpDateSql(mainTable, tableMap, dataJson, pkey, pkeyValue)); + foreach (var childTable in childrenTables) + { + if (tableMap.ContainsKey(childTable.Name)) + { + var rComponent = tableMap[childTable.RelationName].Find(t => t.Field == childTable.RelationField); + if (girdTableMap.ContainsKey(childTable.Name)) + { + list.Add(GetDeleteSql(childTable, dataJson, rComponent)); + // 新增 + FormComponentModel newComponent = new FormComponentModel(); + newComponent.Prop = rComponent.Prop; + newComponent.Field = childTable.Field; + tableMap[childTable.Name].Add(newComponent); + List girdDataJson = dataJson[girdTableMap[childTable.Name].Prop].ToString().ToObject>(); + foreach (var girdData in girdDataJson) + { + girdData.Add(newComponent.Prop, dataJson[newComponent.Prop]); + list.Add(GetInsertSql(childTable, tableMap, girdData)); + } + } + else + { + list.Add(GetUpDateSql(childTable, tableMap, dataJson, childTable.Field, dataJson[rComponent.Prop].ToString())); + } + } + + } + } + else + { + list.Add(GetInsertSql(mainTable, tableMap, dataJson)); + foreach (var childTable in childrenTables) + { + var rComponent = tableMap[childTable.RelationName].Find(t => t.Field.ToLower() == childTable.RelationField.ToLower()); + FormComponentModel newComponent = new FormComponentModel(); + newComponent.Prop = rComponent.Prop; + newComponent.Field = childTable.Field; + tableMap[childTable.Name].Add(newComponent); + + if (girdTableMap.ContainsKey(childTable.Name)) + { + // 编辑表格 + List girdDataJson = dataJson[girdTableMap[childTable.Name].Prop].ToString().ToObject>(); + foreach (var girdData in girdDataJson) + { + girdData.Add(newComponent.Prop, dataJson[newComponent.Prop]); + list.Add(GetInsertSql(childTable, tableMap, girdData)); + } + } + else + { + list.Add(GetInsertSql(childTable, tableMap, dataJson)); + } + + } + } + + return list; + } + /// + /// 获取保存sql语句 + /// + /// + /// + /// + /// + /// + /// + public static List GetSaveSqlNew(FormSchemeNewModel formSchemeModel, JObject dataJson, string pkey, string pkeyValue, bool isUpdate) + { + List list = new List(); + + // 获取主子表 + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + List childrenTables = formSchemeModel.Db.FindAll(t => t.Type == "chlid"); + + // 对表组件按表进行分类 + Dictionary> tableMap = new Dictionary>(); + //Dictionary girdTableMap = new Dictionary(); + Dictionary girdTableMap = new Dictionary(); + + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Schemas) + { + if (component == null || component.ComponentProps == null || string.IsNullOrEmpty(component.ComponentProps.DataTable)) + { + //if(component.Component == "Grid1") + //{ + // foreach (var column in component.Columns) + // { + // tableMap[component.ComponentProps.DataTable].AddRange(column.children); + // } + //} + //else + //{ + // continue; + //} + continue; + } + if (!tableMap.ContainsKey(component.ComponentProps.DataTable)) + { + tableMap[component.ComponentProps.DataTable] = new List(); + } + + if (component.Component == "Grid") + { + //tableMap[component.ComponentProps.DataTable].AddRange(component.children); + //girdTableMap.Add(component.ComponentProps.DataTable, component); + + foreach (var column in component.Columns) + { + tableMap[component.ComponentProps.DataTable].AddRange(column.children); + //girdTableMap.Add(component.ComponentProps.DataTable, column); + if (girdTableMap.ContainsKey(component.ComponentProps.DataTable)) + { + //girdTableMap[component.ComponentProps.DataTable].children.AddRange(column.children); + } + else + { + girdTableMap.Add(component.ComponentProps.DataTable, component); + } + } + + } + else + { + if (component.Field == pkey) + { + pkey = component.Field; + } + tableMap[component.ComponentProps.DataTable].Add(component); + } + } + } + + + + if (isUpdate) + { + list.Add(GetUpDateSqlNew(mainTable, tableMap, dataJson, pkey, pkeyValue)); + foreach (var childTable in childrenTables) + { + if (tableMap.ContainsKey(childTable.Name)) + { + var rComponent = tableMap[childTable.RelationName].Find(t => t.ComponentProps.FieldName == childTable.RelationField); + if (girdTableMap.ContainsKey(childTable.Name)) + { + list.Add(GetDeleteSqlNew(childTable, dataJson, rComponent)); + // 新增 + FormComponentNewModel newComponent = new FormComponentNewModel(); + //newComponent.ComponentProps.FieldName = rComponent.ComponentProps.FieldName; + newComponent.ComponentProps = new ComponentPropsModel(); + newComponent.ComponentProps.DataTable = childTable.Name; + newComponent.ComponentProps.FieldName = childTable.Field; + //newComponent.Field = childTable.Field; + newComponent.Field = rComponent.Field; + tableMap[childTable.Name].Add(newComponent); + //for (int i = 0; i < girdTableMap[childTable.Name].Count; i++) + //{ + // // 编辑表格 + // List girdDataJson = dataJson[girdTableMap[childTable.Name][i].Field].ToString().ToObject>(); + // foreach (var girdData in girdDataJson) + // { + // //girdData.Add(newComponent.ComponentProps.FieldName, dataJson[newComponent.ComponentProps.FieldName]); + // list.Add(GetInsertSqlNew(childTable, tableMap, girdData)); + // } + //} + // List girdDataJson = dataJson[girdTableMap[childTable.Name].ComponentProps.FieldName].ToString().ToObject>(); + List girdDataJson = dataJson[girdTableMap[childTable.Name].Field].ToString().ToObject>(); + foreach (var girdData in girdDataJson) + { + girdData.Add(newComponent.Field, dataJson[newComponent.Field]); + list.Add(GetInsertSqlNew(childTable, tableMap, girdData)); + } + } + else + { + list.Add(GetUpDateSqlNew(childTable, tableMap, dataJson, childTable.Field, dataJson[rComponent.Field].ToString())); + } + } + + } + } + else + { + list.Add(GetInsertSqlNew(mainTable, tableMap, dataJson)); + foreach (var childTable in childrenTables) + { + var rComponent = tableMap[childTable.RelationName].Find(t => t.ComponentProps.FieldName == childTable.RelationField); + FormComponentNewModel newComponent = new FormComponentNewModel() { }; + newComponent.Field = rComponent.Field; + newComponent.ComponentProps = new ComponentPropsModel(); + //newComponent.ComponentProps.DataTable = rComponent.ComponentProps.DataTable; + //newComponent.ComponentProps.FieldName = rComponent.ComponentProps.FieldName; + newComponent.ComponentProps.DataTable = childTable.Name; + newComponent.ComponentProps.FieldName = childTable.Field; + + //newComponent.Field = childTable.Field; + tableMap[childTable.Name].Add(newComponent); + + if (girdTableMap.ContainsKey(childTable.Name)) + { + //for(int i=0;i< girdTableMap[childTable.Name].Count; i++) + //{ + // // 编辑表格 + // List girdDataJson = dataJson[girdTableMap[childTable.Name][i].Field].ToString().ToObject>(); + // foreach (var girdData in girdDataJson) + // { + // //girdData.Add(newComponent.ComponentProps.FieldName, dataJson[newComponent.ComponentProps.FieldName]); + // list.Add(GetInsertSqlNew(childTable, tableMap, girdData)); + // } + //} + List girdDataJson = dataJson[girdTableMap[childTable.Name].Field].ToString().ToObject>(); + foreach (var girdData in girdDataJson) + { + girdData.Add(newComponent.Field, dataJson[newComponent.Field]); + list.Add(GetInsertSqlNew(childTable, tableMap, girdData)); + } + } + else + { + list.Add(GetInsertSqlNew(childTable, tableMap, dataJson)); + } + + } + } + + return list; + } + + /// + /// 获取表单查询方法 + /// + /// + /// + /// + public static FormDbTable GetQuerySql(FormSchemeModel formSchemeModel, string queryJson) + { + FormDbTable res = new FormDbTable(); + res.DbParameter = new List(); + + StringBuilder str = new StringBuilder(); + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + int mainTableIndex = formSchemeModel.Db.FindIndex(t => t.Type == "main"); + + if (formSchemeModel.FormType == 1) + { + str.Append($"select * from ({mainTable.Sql})t "); + } + else + { + Dictionary> tableMap = new Dictionary>(); + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Components) + { + if (component.Type != "gridtable") + { + if (string.IsNullOrEmpty(component.Table)) + { + continue; + } + if (!tableMap.ContainsKey(component.Table)) + { + tableMap[component.Table] = new List(); + } + tableMap[component.Table].Add(component); + } + } + } + + + str.Append("SELECT "); + var mainComponents = tableMap[mainTable.Name]; + foreach (var component in mainComponents) + { + str.Append(string.Format("t.{1} as {1}{0},", mainTableIndex, component.Field)); + } + + str.Append(GetQueryColumns(formSchemeModel.Db, tableMap, mainTable.Name)); + str.Append("FROM "); + str.Append(string.Format("{0} t ", mainTable.Name)); + str.Append(GetQueryLeftTable(formSchemeModel.Db, tableMap, mainTable.Name, mainTableIndex)); + + + } + + str.Append(" WHERE 1=1 {LEARUN_SASSID} "); + + + + + + // 添加参数 + // 对表组件按表进行分类 + Dictionary componentMap = new Dictionary(); + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Components) + { + if (string.IsNullOrEmpty(component.Table)) + { + continue; + } + if (!componentMap.ContainsKey(component.Prop)) + { + componentMap.Add(component.Prop, component); + } + } + } + + var queryParam = queryJson.ToJObject(); + int index = 0; + foreach (var item in queryParam.Properties()) + { + componentMap.TryGetValue(item.Name, out var component); + if (component != null && !string.IsNullOrEmpty(component.Table) && !queryParam[component.Prop].IsEmpty()) + { + int tableIndex = formSchemeModel.Db.FindIndex(t => t.Name == component.Table); + FormDbTableInfo table = formSchemeModel.Db[tableIndex]; + + string tIndex = tableIndex + ""; + if (table.Name == mainTable.Name) + { + tIndex = ""; + } + + + switch (component.Type) + { + case "userSelect": + case "departmentSelect": + case "companySelect": + case "company": + case "department": + case "createuser": + case "modifyuser": + case "select": + str.Append($" AND t{tIndex}.{component.Field} in ('{queryParam[component.Prop].ToString().Replace(",", "','")}') "); + break; + case "input": + case "textarea": + case "texteditor": + res.DbParameter.Add(new SugarParameter($"p_{index}", $"%{queryParam[component.Prop].ToString()}%")); + str.Append($" AND t{tIndex}.{component.Field} like @p_{index} "); + break; + + case "time": + case "datetime": + case "createtime": + case "modifytime": + var value = queryParam[component.Prop].ToString().Split(" - "); + res.DbParameter.Add(GetMyDbParameter($"p_{index}", value[0], component.CsType)); + res.DbParameter.Add(GetMyDbParameter($"p_{index + 1}", value[1], component.CsType)); + str.Append($" AND(t{tIndex}.{component.Field} >= @p_{index} AND t{tIndex}.{component.Field} <= @p_{index + 1} ) "); + index++; + break; + default: + res.DbParameter.Add(GetMyDbParameter($"p_{index}", queryParam[component.Prop].ToString(), component.CsType)); + str.Append($" AND t{tIndex}.{component.Field} = @p_{index} "); + break; + } + + index++; + } + } + + res.Sql = str.ToString().Replace(",FROM", " FROM"); + + return res; + } + public static FormDbTable GetQuerySqlNew(FormSchemeNewModel formSchemeModel, string queryJson) + { + FormDbTable res = new FormDbTable(); + res.DbParameter = new List(); + + StringBuilder str = new StringBuilder(); + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + int mainTableIndex = formSchemeModel.Db.FindIndex(t => t.Type == "main"); + + if (formSchemeModel.FormType == 1) + { + str.Append($"select * from ({mainTable.Sql})t "); + } + else + { + Dictionary> tableMap = new Dictionary>(); + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Schemas) + { + if (component.Component != "Grid") + { + if (component == null || component.ComponentProps == null || string.IsNullOrEmpty(component.ComponentProps.DataTable)) + { + continue; + } + if (!tableMap.ContainsKey(component.ComponentProps.DataTable)) + { + tableMap[component.ComponentProps.DataTable] = new List(); + } + tableMap[component.ComponentProps.DataTable].Add(component); + } + } + } + + str.Append("SELECT "); + var mainComponents = tableMap[mainTable.Name]; + foreach (var component in mainComponents) + { + if (component.ComponentProps.FieldName == "geom") + { + str.Append(string.Format("st_astext( t{0}.\"{1}\") as \"{2}\",", mainTableIndex, component.ComponentProps.FieldName, component.Field)); + } + else + { + str.Append(string.Format("t{0}.\"{1}\" as \"{2}\",", mainTableIndex, component.ComponentProps.FieldName, component.Field)); + } + + ////str.Append(string.Format("t{0}.\"{1}\" as \"{1}{0}\",", mainTableIndex, component.ComponentProps.FieldName)); + //str.Append(string.Format("t{0}.\"{1}\" as \"{2}\",", mainTableIndex, component.ComponentProps.FieldName, component.Field)); + } + + str.Append(GetQueryColumnsNew(formSchemeModel.Db, tableMap, mainTable.Name)); + //str = new StringBuilder(str.ToString().Substring(0, str.Length - 1)); + str.Append("FROM "); + str.Append(string.Format("\"{0}\" t{1} ", mainTable.Name, mainTableIndex)); + //不查询子表信息 + //str.Append(GetQueryLeftTableNew(formSchemeModel.Db, tableMap, mainTable.Name, mainTableIndex)); + + + } + + str.Append(" WHERE 1=1 {LEARUN_SASSID} "); + + + + + + // 添加参数 + // 对表组件按表进行分类 + Dictionary componentMap = new Dictionary(); + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Schemas) + { + if (component == null || component.ComponentProps == null || string.IsNullOrEmpty(component.ComponentProps.DataTable)) + { + continue; + } + if (!componentMap.ContainsKey(component.Field)) + { + componentMap.Add(component.Field, component); + } + } + } + + + + var queryParam = queryJson.ToJObject(); + int index = 0; + foreach (var item in queryParam.Properties()) + { + componentMap.TryGetValue(item.Name, out var component); + if (component != null && !string.IsNullOrEmpty(component.ComponentProps.DataTable) && !queryParam[component.Field].IsEmpty()) + { + //int tableIndex = formSchemeModel.Db.FindIndex(t => t.Name == component.Field); + int tableIndex = formSchemeModel.Db.FindIndex(t => t.Name == component.ComponentProps.DataTable); + FormDbTableInfo table = formSchemeModel.Db[tableIndex]; + + string tIndex = tableIndex + ""; + //if (table.Name == mainTable.Name) + //{ + // tIndex = ""; + //} + + + switch (component.Component) + { + case "userSelect": + case "departmentSelect": + case "companySelect": + case "company": + case "department": + case "createuser": + case "modifyuser": + case "select": + str.Append($" AND t{tIndex}.{component.Field} in ('{queryParam[component.Component].ToString().Replace(",", "','")}') "); + break; + case "Input": + case "InputTextArea": + case "texteditor": + res.DbParameter.Add(new SugarParameter($"p_{index}", $"%{queryParam[component.Field].ToString()}%")); + //str.Append($" AND t{tIndex}.{component.Field} like @p_{index} "); + str.Append($" AND t{tIndex}.{component.ComponentProps.FieldName} like @p_{index} "); + break; + + case "time": + case "datetime": + case "createtime": + case "modifytime": + var value = queryParam[component.Field].ToString().Split(" - "); + res.DbParameter.Add(GetMyDbParameter($"p_{index}", value[0], component.CsType)); + res.DbParameter.Add(GetMyDbParameter($"p_{index + 1}", value[1], component.CsType)); + str.Append($" AND(t{tIndex}.{component.ComponentProps.FieldName} >= @p_{index} AND t{tIndex}.{component.ComponentProps.FieldName} <= @p_{index + 1} ) "); + index++; + break; + case "RangePicker": + var valuep = queryParam[component.Field].ToString().Split(" - "); + res.DbParameter.Add(GetMyDbParameter($"p_{index}", valuep[0], component.CsType)); + res.DbParameter.Add(GetMyDbParameter($"p_{index + 1}", valuep[1], component.CsType)); + str.Append($" AND(t{tIndex}.{component.ComponentProps.FieldName} >= @p_{index} AND t{tIndex}.{component.ComponentProps.FieldName} <= @p_{index + 1} ) "); + index++; + break; + default: + res.DbParameter.Add(GetMyDbParameter($"p_{index}", queryParam[component.Field].ToString(), component.CsType)); + str.Append($" AND t{tIndex}.{component.ComponentProps.FieldName} = @p_{index} "); + break; + } + + index++; + } + } + + res.Sql = str.ToString().Replace(",FROM", " FROM").Replace("{LEARUN_SASSID}", " "); + + return res; + } + + /// + /// 获取更新sql语句 + /// + /// 表 + /// 组件集合 + /// 表单数据 + /// 主键 + /// 主键值 + /// + private static FormDbTable GetUpDateSql(FormDbTableInfo table, Dictionary> tableMap, JObject dataJson, string pkey, string pkeyValue) + { + FormDbTable res = new FormDbTable(); + res.DbParameter = new List(); + res.TableName = table.Name; + res.ExecuteType = ExecuteType.Update; + res.Pkey = pkey.ToUpper(); + bool isPkey = false; + var formComponents = tableMap[table.Name]; + + foreach (var component in formComponents) + { + if (!string.IsNullOrEmpty(component.Field)) + { + if (res.DbParameter.Find(t => t.ParameterName == component.Field.ToUpper()) != null) + { + // 参数添加过则不再添加 + continue; + } + + if (!dataJson[component.Prop].IsEmpty()) + { + res.DbParameter.Add(GetMyDbParameter(component.Field.ToUpper(), dataJson[component.Prop].ToString(), component.CsType)); + } + else + { + res.DbParameter.Add(new SugarParameter(component.Field.ToUpper(), null)); + } + + if (component.Field.ToUpper() == pkey.ToUpper()) + { + isPkey = true; + if (res.DbParameter[res.DbParameter.Count - 1].Value == null) + { + res.DbParameter[res.DbParameter.Count - 1].Value = pkeyValue; + } + } + } + } + + if (!isPkey) + { + res.DbParameter.Add(new SugarParameter(pkey.ToUpper(), pkeyValue)); + } + + return res; + } + private static FormDbTable GetUpDateSqlNew(FormDbTableInfo table, Dictionary> tableMap, JObject dataJson, string pkey, string pkeyValue) + { + FormDbTable res = new FormDbTable(); + res.DbParameter = new List(); + res.TableName = table.Name; + res.ExecuteType = ExecuteType.Update; + res.Pkey = pkey; + bool isPkey = false; + var formComponents = tableMap[table.Name]; + + foreach (var component in formComponents) + { + if (!string.IsNullOrEmpty(component.ComponentProps.FieldName)) + { + if (res.DbParameter.Find(t => t.ParameterName == component.Field) != null) + { + // 参数添加过则不再添加 + continue; + } + + //if (dataJson[component.Field] != null && !dataJson[component.Field].IsEmpty()) + if (!dataJson[component.Field].IsEmpty()) + { + res.DbParameter.Add(GetMyDbParameter(component.ComponentProps.FieldName, dataJson[component.Field].ToString(), component.CsType)); + } + else + { + //如果传过来的值为"",需要判断下字符类型 + if (dataJson[component.Field] != null && dataJson[component.Field].ToString() == "" && component.CsType == "string") + { + res.DbParameter.Add(GetMyDbParameter(component.ComponentProps.FieldName, dataJson[component.Field].ToString(), component.CsType)); + } + //只更新上传的数据,表单其他的不更新 + //res.DbParameter.Add(new SugarParameter(component.ComponentProps.FieldName, null)); + } + + if (component.ComponentProps.FieldName == pkey) + { + isPkey = true; + if (res.DbParameter[res.DbParameter.Count - 1].Value == null) + { + res.DbParameter[res.DbParameter.Count - 1].Value = pkeyValue; + } + } + } + } + + if (!isPkey) + { + res.DbParameter.Add(new SugarParameter(pkey, pkeyValue)); + } + + return res; + } + + private static FormDbTable GetDeleteSql(FormDbTableInfo table, JObject dataJson, FormComponentModel component) + { + FormDbTable res = new FormDbTable(); + res.DbParameter = new List(); + res.TableName = table.Name; + res.ExecuteType = ExecuteType.Delete; + + res.DbParameter.Add(GetMyDbParameter(table.Field.ToUpper(), dataJson[component.Prop].ToString(), component.CsType)); + return res; + } + private static FormDbTable GetDeleteSqlNew(FormDbTableInfo table, JObject dataJson, FormComponentNewModel component) + { + FormDbTable res = new FormDbTable(); + res.DbParameter = new List(); + res.TableName = table.Name; + res.ExecuteType = ExecuteType.Delete; + + res.DbParameter.Add(GetMyDbParameter(table.Field, dataJson[component.Field].ToString(), component.CsType)); + return res; + } + private static void GetDeleteSqlNew(List list, List db, string pTableName) + { + var tables = db.FindAll(t => t.RelationName == pTableName); + foreach (var table in tables) + { + var sql = new StringBuilder(); + sql.Append($" DELETE FROM {table.Name} WHERE {table.Field}= @keyValue "); + list.Add(new FormDbTable + { + Sql = sql.ToString(), + RelationField = table.RelationField, + RelationName = table.RelationName, + TableName = table.Name + }); + GetDeleteSqlNew(list, db, table.Name); + } + } + /// + /// 获取删除语句 + /// + /// + /// + /// + public static List GetDeleteSqlNew(FormSchemeNewModel formSchemeModel, string pkey) + { + List list = new List(); + // 获取主子表 + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + + var sql = new StringBuilder(); + //sql.Append($" DELETE FROM {mainTable.Name} WHERE {pkey}= @keyValue " + "{LEARUN_SASSID_NOTT}"); + sql.Append($" DELETE FROM {mainTable.Name} WHERE \"{pkey}\"= @keyValue "); + list.Add(new FormDbTable + { + Sql = sql.ToString(), + TableName = mainTable.Name + }); + GetDeleteSqlNew(list, formSchemeModel.Db, mainTable.Name); + return list; + } + /// + /// 获取新增sql语句 + /// + /// 表 + /// 组件集合 + /// 表单数据 + /// + private static FormDbTable GetInsertSql(FormDbTableInfo table, Dictionary> tableMap, JObject dataJson) + { + FormDbTable res = new FormDbTable(); + res.DbParameter = new List(); + res.TableName = table.Name; + res.ExecuteType = ExecuteType.Insert; + foreach (var component in tableMap[table.Name]) + { + if (!string.IsNullOrEmpty(component.Field) && !dataJson[component.Prop].IsEmpty()) + { + if (res.DbParameter.Find(t => t.ParameterName == component.Field) != null) + { + continue; + } + res.DbParameter.Add(GetMyDbParameter(component.Field, dataJson[component.Prop].ToString(), component.CsType)); + } + } + return res; + } + /// + /// 获取新增sql语句 + /// + /// 表 + /// 组件集合 + /// 表单数据 + /// + private static FormDbTable GetInsertSqlNew(FormDbTableInfo table, Dictionary> tableMap, JObject dataJson) + { + FormDbTable res = new FormDbTable(); + res.DbParameter = new List(); + res.TableName = table.Name; + res.ExecuteType = ExecuteType.Insert; + foreach (var component in tableMap[table.Name]) + { + if (!string.IsNullOrEmpty(component.Field) && !dataJson[component.Field].IsEmpty()) + { + if (res.DbParameter.Find(t => t.ParameterName == component.Field) != null) + { + continue; + } + res.DbParameter.Add(GetMyDbParameter(component.ComponentProps.FieldName, dataJson[component.Field].ToString(), component.CsType)); + } + } + return res; + } + + private static string GetQueryColumns(List db, Dictionary> tableMap, string pTableName) + { + StringBuilder str = new StringBuilder(); + var tables = db.FindAll(t => t.RelationName == pTableName && tableMap.ContainsKey(t.Name)); + foreach (var table in tables) + { + int tableIndex = db.FindIndex(t => t.Name == table.Name); + + var components = tableMap[table.Name]; + + foreach (var component in components) + { + if (!string.IsNullOrEmpty(component.Field)) + { + str.Append(string.Format("t{0}.{1} as {1}{0},", tableIndex, component.Field)); + } + } + + str.Append(GetQueryColumns(db, tableMap, table.Name)); + } + + return str.ToString(); + } + private static string GetQueryColumnsNew(List db, Dictionary> tableMap, string pTableName) + { + StringBuilder str = new StringBuilder(); + var tables = db.FindAll(t => t.RelationName == pTableName && tableMap.ContainsKey(t.Name)); + foreach (var table in tables) + { + //只查主表信息 + if (table.Type == "main") + { + int tableIndex = db.FindIndex(t => t.Name == table.Name); + + var components = tableMap[table.Name]; + + foreach (var component in components) + { + if (!string.IsNullOrEmpty(component.ComponentProps.DataTable)) + { + //str.Append(string.Format("t{0}.\"{1}\" as \"{1}{0}\",", tableIndex, component.ComponentProps.FieldName)); + str.Append(string.Format("t{0}.\"{1}\" as \"{2}\",", tableIndex, component.ComponentProps.FieldName, component.Field)); + } + } + + str.Append(GetQueryColumnsNew(db, tableMap, table.Name)); + } + //int tableIndex = db.FindIndex(t => t.Name == table.Name); + + //var components = tableMap[table.Name]; + + //foreach (var component in components) + //{ + // if (!string.IsNullOrEmpty(component.ComponentProps.DataTable)) + // { + // //str.Append(string.Format("t{0}.\"{1}\" as \"{1}{0}\",", tableIndex, component.ComponentProps.FieldName)); + // str.Append(string.Format("t{0}.\"{1}\" as \"{2}\",", tableIndex, component.ComponentProps.FieldName, component.Field)); + // } + //} + + //str.Append(GetQueryColumnsNew(db, tableMap, table.Name)); + } + + return str.ToString(); + } + + private static string GetQueryLeftTable(List db, Dictionary> tableMap, string pTableName, int pTableIndex) + { + StringBuilder str = new StringBuilder(); + var tables = db.FindAll(t => t.RelationName == pTableName && tableMap.ContainsKey(t.Name)); + foreach (var table in tables) + { + + int tableIndex = db.FindIndex(t => t.Name == table.Name); + str.Append(string.Format(" LEFT JOIN {0} t{1} ON t{1}.{2} = t{3}.{4} ", table.Name, tableIndex, table.Field, pTableIndex, table.RelationField)); + str.Append(GetQueryLeftTable(db, tableMap, table.Name, tableIndex)); + } + + return str.ToString(); + } + private static string GetQueryLeftTableNew(List db, Dictionary> tableMap, string pTableName, int pTableIndex) + { + StringBuilder str = new StringBuilder(); + var tables = db.FindAll(t => t.RelationName == pTableName && tableMap.ContainsKey(t.Name)); + foreach (var table in tables) + { + + int tableIndex = db.FindIndex(t => t.Name == table.Name); + str.Append(string.Format(" LEFT JOIN \"{0}\" t{1} ON t{1}.\"{2}\" = t{3}.\"{4}\" ", table.Name, tableIndex, table.Field, pTableIndex, table.RelationField)); + str.Append(GetQueryLeftTableNew(db, tableMap, table.Name, tableIndex)); + } + + return str.ToString(); + } + public static bool IsEmpty(this object value) + { + if (value != null && !string.IsNullOrEmpty(value.ToString())) + { + return false; + } + + return true; + } + public static SugarParameter GetMyDbParameter(string parameterName, string value, string csType) + { + string _csType = csType; + switch (csType) + { + case "int": + _csType = "System.Int32"; + break; + case "long": + _csType = "System.Int64"; + break; + case "short": + _csType = "System.Int16"; + break; + case "bool": + _csType = "System.Boolean"; + break; + case "float": + _csType = "System.Single"; + break; + case "text": + _csType = ""; + break; + default: + if (!string.IsNullOrEmpty(csType)) + { + _csType = $"System.{StringExtension.FirstUpper(csType)}"; + } + break; + } + if (_csType == "System.TimeSpan") + { + return new SugarParameter(parameterName, TimeSpan.Parse(value)); + } + else if (_csType == "System.Guid") + { + return new SugarParameter(parameterName, Guid.Parse(value)); + } + else + { + return new SugarParameter(parameterName, string.IsNullOrEmpty(_csType) ? value : Convert.ChangeType(value, System.Type.GetType(_csType))); + } + } + /// + /// 获取表单查询方法 + /// + /// + /// + /// + public static List GetQuery(FormSchemeModel formSchemeModel, string pkey) + { + List list = new List(); + + StringBuilder str = new StringBuilder(); + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + // 对表组件按表进行分类 + Dictionary> tableMap = new Dictionary>(); + Dictionary girdTableMap = new Dictionary(); + + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Components) + { + if (string.IsNullOrEmpty(component.Table)) + { + continue; + } + if (!tableMap.ContainsKey(component.Table)) + { + tableMap[component.Table] = new List(); + } + + if (component.Type == "gridtable") + { + tableMap[component.Table].AddRange(component.children); + girdTableMap.Add(component.Table, component); + } + else + { + if (component.Prop == pkey) + { + pkey = component.Field; + } + tableMap[component.Table].Add(component); + } + } + } + + + str.Append("SELECT "); + var mainComponents = tableMap[mainTable.Name]; + foreach (var component in mainComponents) + { + str.Append($" {component.Field},"); + } + str.Append($"FROM {mainTable.Name} t where {pkey} = @keyValue " + "{LEARUN_SASSID}"); + + list.Add(new FormDbTable + { + Sql = str.ToString().Replace(",FROM", " FROM"), + TableName = mainTable.Name + }); + + + GetQuery(list, formSchemeModel.Db, mainTable.Name, tableMap, girdTableMap); + + return list; + } + /// + /// 获取表单查询方法 + /// + /// + /// + /// + public static List GetQueryNew(FormSchemeNewModel formSchemeModel, string pkey) + { + List list = new List(); + + StringBuilder str = new StringBuilder(); + // 主数据库 + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + // 对表组件按表进行分类 + Dictionary> tableMap = new Dictionary>(); + Dictionary girdTableMap = new Dictionary(); + + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Schemas) + { + if (component == null || component.ComponentProps == null || string.IsNullOrEmpty(component.ComponentProps.DataTable)) + { + //if(component.Component == "Grid1") + //{ + // foreach (var column in component.Columns) + // { + // tableMap[component.ComponentProps.DataTable].AddRange(column.children); + // } + //} + //else + //{ + // continue; + //} + continue; + } + if (!tableMap.ContainsKey(component.ComponentProps.DataTable)) + { + tableMap[component.ComponentProps.DataTable] = new List(); + } + + if (component.Component == "Grid") + { + //tableMap[component.ComponentProps.DataTable].AddRange(component.children); + //girdTableMap.Add(component.ComponentProps.DataTable, component); + foreach (var column in component.Columns) + { + tableMap[component.ComponentProps.DataTable].AddRange(column.children); + if (girdTableMap.ContainsKey(component.ComponentProps.DataTable)) + { + //girdTableMap[component.ComponentProps.DataTable].AddRange(column); + } + else + { + girdTableMap.Add(component.ComponentProps.DataTable, column); + } + + } + } + else + { + if (component.ComponentProps.FieldName == pkey) + { + pkey = component.ComponentProps.FieldName; + } + //添加关联键 + tableMap[component.ComponentProps.DataTable].Add(component); + } + } + } + + + + + str.Append("SELECT "); + var mainComponents = tableMap[mainTable.Name]; + foreach (var component in mainComponents) + { + if (component.ComponentProps.FieldName == "geom") + { + str.Append($" st_astext(\"{component.ComponentProps.FieldName}\") as " + component.Field + ","); + } + else + { + str.Append($" \"{component.ComponentProps.FieldName}\" as " + component.Field + ","); + } + //str.Append($" \"{component.ComponentProps.FieldName}\" as " + component.Field + ","); + + } + //pkey = mainComponents.Where(t => t.ComponentProps.FieldName == pkey).First()?.Field; + pkey = mainComponents.Where(t => t.ComponentProps.FieldName == pkey).First()?.ComponentProps.FieldName; + //str.Append($"FROM \"{mainTable.Name}\" t where \"{pkey}\" = @keyValue " + "{LEARUN_SASSID}"); + str.Append($"FROM \"{mainTable.Name}\" t where \"{pkey}\" = @keyValue "); + + list.Add(new FormDbTable + { + Sql = str.ToString().Replace(",FROM", " FROM"), + TableName = mainTable.Name + }); + + + GetQueryNew(list, formSchemeModel.Db, mainTable.Name, tableMap, girdTableMap); + + return list; + } + + private static void GetQuery(List list, List db, string pTableName, Dictionary> tableMap, Dictionary girdTableMap) + { + var tables = db.FindAll(t => t.RelationName == pTableName); + foreach (var table in tables) + { + StringBuilder str = new StringBuilder(); + str.Append("SELECT "); + var components = tableMap[table.Name]; + foreach (var column in components) + { + str.Append($" {column.Field},"); + } + str.Append($"FROM {table.Name} where {table.Field} = @keyValue "); + + if (girdTableMap.ContainsKey(table.Name)) + { + var componentModel = girdTableMap[table.Name]; + if (!string.IsNullOrEmpty(componentModel.OrderId)) + { + if (componentModel.isDESC) + { + str.Append($" order by {componentModel.OrderId} DESC "); + } + else + { + str.Append($" order by {componentModel.OrderId} "); + } + } + } + + list.Add(new FormDbTable + { + Sql = str.ToString().Replace(",FROM", " FROM"), + RelationField = table.RelationField, + RelationName = table.RelationName, + TableName = table.Name + }); + + GetQuery(list, db, table.Name, tableMap, girdTableMap); + } + + + } + private static void GetQueryNew(List list, List db, string pTableName, Dictionary> tableMap, Dictionary girdTableMap) + { + var tables = db.FindAll(t => t.RelationName == pTableName); + foreach (var table in tables) + { + StringBuilder str = new StringBuilder(); + str.Append("SELECT "); + var components = tableMap[table.Name]; + foreach (var column in components) + { + //新加 + var field = components.Where(t => t.ComponentProps.FieldName == column.ComponentProps.FieldName).First(); + if (field.ComponentProps.FieldName == "geom") + { + str.Append($" st_astext(\"{column.ComponentProps.FieldName}\") as " + field.Field + ","); + } + else + { + str.Append($" \"{column.ComponentProps.FieldName}\" as " + field.Field + ","); + } + //str.Append($" \"{column.ComponentProps.FieldName}\" as " + field.Field + ","); + } + // var ffield = components.Where(t => t.ComponentProps.FieldName == table.Field).First()?.Field; + //str.Append($"FROM \"{table.Name}\" where \"{table.Field}\" = @keyValue "); + str.Append($"FROM \"{table.Name}\" where \"{table.Field}\" = @keyValue "); + + if (girdTableMap.ContainsKey(table.Name)) + { + var componentModel = girdTableMap[table.Name]; + if (!string.IsNullOrEmpty(componentModel.OrderId)) + { + if (componentModel.isDESC) + { + str.Append($" order by \"{componentModel.OrderId}\" DESC "); + } + else + { + str.Append($" order by \"{componentModel.OrderId}\" "); + } + } + } + + list.Add(new FormDbTable + { + Sql = str.ToString().Replace(",FROM", " FROM"), + //RelationField = table.RelationField, + RelationField = table.Field, + RelationName = table.RelationName, + TableName = table.Name + }); + + GetQueryNew(list, db, table.Name, tableMap, girdTableMap); + } + + + } + public static string GetCsType(DbType dbtype, string dbType) + { + string csType = "string"; + switch (dbType.ToLower()) + { + case "varchar": + csType = "string"; + break; + case "varchar2": + csType = "string"; + break; + case "char": + case "nchar": + case "nvarchar": + case "nvarchar2": + csType = "string"; + break; + case "text": + csType = "string"; + break; + case "ntext": + case "longtext": + case "clob": + case "nclog": + csType = "text"; + break; + case "int2": + csType = "int"; + break; + case "integer": + csType = "int"; + break; + case "int4": + csType = "int"; + break; + case "mediumint":// mysql + case "year": + csType = "int"; + break; + case "bigint": + csType = "long"; + break; + case "smallint": + csType = "short"; + break; + case "bit": + csType = "bool"; + break; + case "tinyint": + csType = "byte"; + break; + case "decimal": + csType = "decimal"; + break; + case "numeric": + csType = "decimal"; + break; + case "number": + csType = "int"; + break; + case "number(8,2)": + csType = "double"; + break; + case "money": + case "bool": + csType = "bool"; + break; + case "smallmoney": + csType = "decimal"; + break; + case "real": + case "double": + if (dbtype == DbType.MySql) + { + csType = "double"; + } + else + { + csType = "float"; + } + break; + case "float": + if (dbtype == DbType.MySql) + { + csType = "float"; + } + else + { + csType = "double"; + } + break; + case "float4": + csType = "double"; + break; + case "float8": + csType = "double"; + break; + case "date": + csType = "DateTime"; + break; + case "datetime": + csType = "DateTime"; + break; + case "datetime2": + csType = "DateTime"; + break; + case "smalldatetime": + csType = "DateTime"; + break; + case "datetimeoffset": + csType = "DateTimeOffset"; + break; + case "time": + //csType = "TimeSpan"; + //break; + csType = "DateTime"; + break; + case "timestamp": + if (dbtype == DbType.MySql) + { + csType = "DateTime"; + + } + else + { + csType = "DateTime"; + } + break; + case "binary": + case "varbinary": + case "image": + + case "tinyblob": + case "blob": + case "mediumblob": + case "longblob": + csType = "byte[]"; + break; + case "uniqueidentifier": + csType = "Guid"; + break; + case "variant": + csType = "Object"; + break; + case "timestamp without time zone": + csType = "TimeSpan"; + break; + // mysql + case "set": + case "enum": + csType = "Enum"; + break; + case "point": + case "linestring": + case "polygon": + case "geometry": + case "multipoint": + case "multilinestring": + case "multipolygon": + //case "geometrycollection": + // csType = "MygisGeometry"; + case "geometrycollection": + csType = "string"; + break; + } + + return csType; + } + /// + /// + /// + /// + /// + public static string SqlFilters(string source) + { + if (string.IsNullOrEmpty(source)) + { + return source; + } + + //去除执行SQL语句的命令关键字 + // source = Regex.Replace(source, "select", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "insert", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "update", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "delete", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "drop", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "truncate", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "declare", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "xp_cmdshell", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "/add", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "net user", "", RegexOptions.IgnoreCase); + //去除执行存储过程的命令关键字 + source = Regex.Replace(source, "exec", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "execute", "", RegexOptions.IgnoreCase); + //去除系统存储过程或扩展存储过程关键字 + source = Regex.Replace(source, "xp_", "x p_", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "sp_", "s p_", RegexOptions.IgnoreCase); + //防止16进制注入 + source = Regex.Replace(source, "0x", "0 x", RegexOptions.IgnoreCase); + return source; + } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/FormSchemeApp.cs b/OpenAuth.App/BaseApp/FormScheme/FormSchemeApp.cs new file mode 100644 index 0000000..9531ec3 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/FormSchemeApp.cs @@ -0,0 +1,1776 @@ +using OpenAuth.App.Base; +using OpenAuth.Repository.Domain; +using OpenAuth.Repository; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using Infrastructure; +using OpenAuth.Repository.Core; +using System.Data; +using System.Text.RegularExpressions; +using OpenAuth.App.FormScheme.Response; +using OpenAuth.App.FormScheme.FormHelpers; +using Autofac.Core; +using Infrastructure.Helpers; +using System.Collections; +using Newtonsoft.Json.Linq; +using OpenAuth.App.FormScheme.Request; +using System.Collections.Concurrent; +using ce.autofac.extension; +using OpenAuth.App.DataCodeRule; +using Infrastructure.Extensions; +using OpenAuth.App.BasicQueryService; +using OpenAuth.App.Permission; +using NPOI.SS.Formula.Functions; +using OpenAuth.App.DataSource; +using System.Data.SqlTypes; +using DocumentFormat.OpenXml.Spreadsheet; +using NPOI.HSSF.UserModel; +using NPOI.SS.UserModel; +using OpenAuth.App.FormModule; +using Microsoft.Extensions.Logging; +using OpenAuth.App.BaseApp.Base; +using Castle.Core.Internal; + +namespace OpenAuth.App.FormScheme +{ + public class FormSchemeApp : SqlSugarBaseApp + { + private ConcurrentDictionary codeDic; + private readonly BaseDataAuthorizeApp _dataAuthorizeApp; + private ILogger _logger; + + public FormSchemeApp(ISugarUnitOfWork unitWork, + ILogger logger, + ISimpleClient repository, BaseDataAuthorizeApp dataAuthorizeApp) + : base(unitWork, repository, null) + { + _logger = logger; + _dataAuthorizeApp = dataAuthorizeApp; + } + + /// + /// 查询表单分页信息 custmerform/scheme/page + /// + /// 关键字 + /// 分类 + /// 状态1启用0未启用2草稿3全部 + /// + /// + /// + /// + public async Task>>> LoadFormPage(string keyword, string category, + int pageIndex, int pageSize, int isEnabled = 3) + { + RefAsync totalCount = 0; + var info = await base.Repository.AsQueryable() + .LeftJoin((a, b) => a.SchemeId == b.Id) + .WhereIF(!string.IsNullOrEmpty(keyword), (a, b) => a.Name.Contains(keyword)) + .WhereIF(!string.IsNullOrEmpty(category), (a, b) => a.Category == category) + //.WhereIF(isEnabled, (a, b) => a.EnabledMark == 1 && b.Type == 1) + .WhereIF(isEnabled != 3, (a, b) => a.EnabledMark == isEnabled) + .OrderByDescending((a, b) => b.CreateDate) + //.WhereIF(type != 0, (a, b) => b.Type == type) + .Select((a, b) => new FormSchemeInfo() + { + Id = a.Id, + Name = a.Name, + Category = a.Category, + SchemeId = a.SchemeId, + EnabledMark = a.EnabledMark, + FormType = a.FormType, + Description = a.Description, + Type = b.Type, + CreateDate = b.CreateDate, + CreateUserId = b.CreateUserId, + CreateUserName = b.CreateUserName + }) + .ToPageListAsync(pageIndex, pageSize, totalCount); + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + + #region 添加表单信息 + + /// + /// 保存模板信息 + /// + /// 主键 + /// 模板基础信息 + /// 模板信息 + public async Task> AddForm(string keyValue, FormSchemeInfo schemeInfo, + Repository.Domain.FormScheme formScheme) + { + try + { + if (!string.IsNullOrEmpty(schemeInfo.SchemeId)) + { + var schemeOldEntity = await GetScheme(schemeInfo.SchemeId); + if (schemeOldEntity == null || schemeOldEntity.Type != formScheme.Type || + schemeOldEntity.Scheme != formScheme.Scheme) + { + await SaveEntity(keyValue, schemeInfo, formScheme); + } + else + { + await SaveEntity(keyValue, schemeInfo, null); + } + } + else + { + await SaveEntity(keyValue, schemeInfo, formScheme); + } + + return new Response { Result = true }; + } + catch (Exception ex) + { + return new Response { Result = false }; + } + } + + /// + /// 获取模板的实体 + /// + /// 主键 + /// + public Task GetScheme(string keyValue) + { + return base.Repository.ChangeRepository>() + .GetFirstAsync(r => r.Id == keyValue); + } + + /// + /// 获取模板基础信息的实体 + /// + /// 主键 + /// + public Task GetSchemeInfo(string keyValue) + { + return base.Repository.GetFirstAsync(r => r.Id == keyValue); + } + + /// + /// 保存模板信息 + /// + /// 主键 + /// 模板基础信息 + /// 模板信息 + public async Task SaveSchEntity(string keyValue, FormSchemeInfo schemeInfoEntity, + Repository.Domain.FormScheme schemeEntity) + { + if (!string.IsNullOrEmpty(schemeInfoEntity.SchemeId)) + { + var schemeOldEntity = await GetScheme(schemeInfoEntity.SchemeId); + if (schemeOldEntity == null || schemeOldEntity.Type != schemeEntity.Type || + schemeOldEntity.Scheme != schemeEntity.Scheme) + { + await SaveEntity(keyValue, schemeInfoEntity, schemeEntity); + } + else + { + await SaveEntity(keyValue, schemeInfoEntity, null); + } + } + else + { + await SaveEntity(keyValue, schemeInfoEntity, schemeEntity); + } + } + + /// + /// 保存模板信息 + /// + /// 主键 + /// 模板基础信息 + /// 模板信息 + public async Task> SaveEntity(string keyValue, FormSchemeInfo schemeInfo, + Repository.Domain.FormScheme formScheme) + { + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + if (string.IsNullOrEmpty(keyValue)) + { + schemeInfo.Id = Guid.NewGuid().ToString(); + } + else + { + schemeInfo.Id = keyValue; + } + + #region 模板信息 + + //FormSchemeNewModel formSchemeModel = formScheme.Scheme.ToObject(); + //formSchemeModel.FormType = schemeInfo.FormType; + if (formScheme != null) + { + //formScheme.Scheme = Json.ToJson(formSchemeModel); + formScheme.SchemeInfoId = schemeInfo.Id; + formScheme.Id = Guid.NewGuid().ToString(); + formScheme.CreateDate = DateTime.Now; + formScheme.CreateUserId = schemeInfo.CreateUserId; + formScheme.CreateUserName = schemeInfo.CreateUserName; + await db.Scheme.InsertAsync(formScheme); + schemeInfo.SchemeId = formScheme.Id; + } + + #endregion + + #region 模板基础信息 + + if (!string.IsNullOrEmpty(keyValue)) + { + await db.SchemeInfo.UpdateAsync(schemeInfo); + } + else + { + await db.SchemeInfo.InsertAsync(schemeInfo); + } + + #endregion + + var flag = db.Commit(); + return new Response + { + Result = schemeInfo.Id, + Message = flag == true ? "添加成功" : "添加失败" + }; + } + } + + /// + /// 更新表单模板版本 + /// + /// 模板信息主键 + /// 模板主键 + public async Task> UpdateScheme(string schemeInfoId, string schemeId) + { + Repository.Domain.FormScheme formSchemeEntity = await GetScheme(schemeId); + FormSchemeInfo entity = await base.Repository.GetFirstAsync(r => r.Id == schemeInfoId); + if (formSchemeEntity.Type != 1) + { + entity.EnabledMark = 0; + } + + //忽略为空的数据 + var flag = true; + if (entity != null) + { + entity.SchemeId = schemeId; + flag = await base.Repository.UpdateAsync(entity); + } + + return new Response + { + Result = flag, + Message = flag == true ? "更新成功" : "更新失败" + }; + } + + #endregion + + /// + /// 更新自定义表单模板状态 + /// + /// 模板信息主键 + /// 状态1启用0禁用 + public async Task> UpdateState(string schemeInfoId, int state) + { + FormSchemeInfo entity = await base.Repository.GetFirstAsync(r => r.Id == schemeInfoId); + entity.EnabledMark = state; + var flag = await base.Repository.UpdateAsync(entity); + return new Response + { + Result = flag, + Message = flag == true ? "更新成功" : "更新失败" + }; + } + + /// + /// 删除模板信息 + /// + /// 主键 + public async Task> Delete(string keyValue) + { + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + await db.SchemeInfo.DeleteAsync(t => t.Id == keyValue); + await db.Scheme.DeleteAsync(t => t.SchemeInfoId == keyValue); + var flag = db.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "删除成功" : "删除失败" + }; + } + } + + /// + /// 获取模板列表 + /// + /// 分页参数 + /// 模板信息主键 + /// + public async Task>>> GetSchemePageList(PageReq pagination, + string schemeInfoId) + { + RefAsync totalCount = 0; + var info = await base.Repository.ChangeRepository>() + .AsQueryable() + .Where(t => t.SchemeInfoId == schemeInfoId) + .OrderByDescending(t => t.CreateDate) + .ToPageListAsync(pagination.page, pagination.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + + #region 扩展方法 + + /// + /// 获取sql列 + /// + /// + /// + /// + public async Task> GetDataColName(string dbCode, string sql, string whereStr = null) + { + sql = this.SqlFilters(sql); + sql = sql.Replace("=@param", " is not null"); + sql = sql.Replace("= @param", " is not null"); + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + DataTable dt = await db.Db.SqlQueryable(sql).Where(whereStr).ToDataTablePageAsync(1, 1); + List res = new List(); + foreach (DataColumn item in dt.Columns) + { + res.Add(item.ColumnName.ToLower()); + } + + return res; + } + } + + /// + /// + /// + /// + /// + public string SqlFilters(string source) + { + if (string.IsNullOrEmpty(source)) + { + return source; + } + + //去除执行SQL语句的命令关键字 + // source = Regex.Replace(source, "select", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " insert ", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " update ", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " delete ", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " drop ", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " truncate ", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " declare ", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " xp_cmdshell ", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " /add ", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " net user ", "", RegexOptions.IgnoreCase); + //去除执行存储过程的命令关键字 + source = Regex.Replace(source, " exec ", "", RegexOptions.IgnoreCase); + source = Regex.Replace(source, " execute ", "", RegexOptions.IgnoreCase); + //去除系统存储过程或扩展存储过程关键字 + source = Regex.Replace(source, "xp_", "x p_", RegexOptions.IgnoreCase); + source = Regex.Replace(source, "sp_", "s p_", RegexOptions.IgnoreCase); + //防止16进制注入 + source = Regex.Replace(source, "0x", "0 x", RegexOptions.IgnoreCase); + return source; + } + + ///// + ///// 获取自定义表单数据权限查询条件 + ///// + ///// 自定义表单功能主键 + ///// + //public async Task GetWhereSql(string code) + //{ + // var numIndex = new string[26] {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", + // "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; + + + // // 获取数据权限配置信息 + // List objectIds = new List(); + // objectIds.Add(userInfo.F_UserId); + // objectIds.AddRange(roleIds); + // var list = await service.GetList(code, objectIds.ToArray()); + + // var strRes = new StringBuilder(); + // int sqlNum = 0; + // foreach (var item in list) + // { + + // if (sqlNum > 0) + // { + // strRes.Append(" OR ( "); + // } + // else + // { + // strRes.Append(" ( "); + // } + + // string strSql = ""; + // var itemFormula = item.F_Formula.ToObject(); + // if (!string.IsNullOrEmpty(itemFormula.formula)) + // { + // strSql = itemFormula.formula; + // for (int i = 1; i < itemFormula.Conditions.Count + 1; i++) + // { + // var conditionItem = itemFormula.Conditions[i - 1]; + // conditionItem.index = i; + + // strSql = strSql.Replace("" + i, "{@learun" + i + "learun@}"); + // } + + // if (itemFormula.Formulas != null && itemFormula.Formulas.Count > 0) + // { + // for (int i = 0; i < itemFormula.Formulas.Count; i++) + // { + // strSql = strSql.Replace(numIndex[i], "{@learun" + numIndex[i] + "learun@}"); + // } + // } + // } + // else + // { + // // 默认公式 + // for (int i = 1; i < itemFormula.Conditions.Count + 1; i++) + // { + + // var conditionItem = itemFormula.Conditions[i - 1]; + // conditionItem.index = i; + + // if (string.IsNullOrEmpty(conditionItem.Group)) + // { + // if (strSql != "") + // { + // strSql += " AND "; + // } + // strSql += " {@learun" + i + "learun@} "; + // } + // } + + // if (itemFormula.Formulas != null && itemFormula.Formulas.Count > 0) + // { + // for (int i = 0; i < itemFormula.Formulas.Count; i++) + // { + + // if (itemFormula.Conditions.FindIndex(t => t.Group == numIndex[i]) != -1) + // { + // if (strSql != "") + // { + // strSql += " AND "; + // } + // strSql += " {@learun" + numIndex[i] + "learun@} "; + // } + // } + // } + + // } + + + // // 分组公式处理 + // if (itemFormula.Formulas != null && itemFormula.Formulas.Count > 0) + // { + + + // for (int i = 0; i < itemFormula.Formulas.Count; i++) + // { + // var groupSql = new StringBuilder(); + + // var groupList = itemFormula.Conditions.FindAll(t => t.Group == numIndex[i]); + // if (groupList.Count > 0) + // { + + // groupSql.Append($" {groupList[0].RelationField} in ( SELECT {groupList[0].Field} FROM {groupList[0].Table} WHERE "); + + // // 初始化分组公式 + // var groupSqlWhere = ""; + // if (string.IsNullOrEmpty(itemFormula.Formulas[i].Value)) + // { + // foreach (var groupItem in groupList) + // { + // if (groupSqlWhere != "") + // { + // groupSqlWhere += " AND "; + // } + // groupSqlWhere += " {@learun" + groupItem.index + "learun@} "; + // } + // } + // else + // { + // groupSqlWhere = itemFormula.Formulas[i].Value; + // foreach (var groupItem in groupList) + // { + // groupSqlWhere = groupSqlWhere.Replace("" + groupItem.index, "{@learun" + groupItem.index + "learun@}"); + // } + // } + + + // foreach (var groupItem in groupList) + // { + // var strone = new StringBuilder(); + + + // if (groupItem.F_Symbol == 8) + // { + // strone.Append($" ({groupItem.Cfield} "); + // } + // else + // { + // strone.Append($" {groupItem.Cfield} "); + // } + + + // string value = await GetValue(groupItem.F_FiledValueType, groupItem.F_FiledValue); + + // switch (groupItem.F_Symbol) + // { + // case 1:// 等于 + // strone.Append($" = {value}"); + // break; + // case 2:// 大于 + // strone.Append($" > {value}"); + // break; + // case 3:// 大于等于 + // strone.Append($" >= {value}"); + // break; + // case 4:// 小于 + // strone.Append($" < {value}"); + // break; + // case 5:// 小于等于 + // strone.Append($" <= {value}"); + // break; + // case 6:// 包含 + // value = value.Replace("'", ""); + // strone.Append($" like '%{value}%'"); + // break; + // case 7:// 包含于 + // value = value.Replace(",", "','"); + // strone.Append($" in ({value})"); + // break; + // case 8:// 不等于 + // strone.Append($" != {value} or {groupItem.Cfield} is null ) "); + // break; + // case 9:// 不包含 + // value = value.Replace("'", ""); + // strone.Append($" not like '%{value}%'"); + // break; + // case 10:// 不包含于 + // value = value.Replace(",", "','"); + // strone.Append($" not in ({value})"); + // break; + // default: + // break; + // } + + // groupSqlWhere = groupSqlWhere.Replace("{@learun" + groupItem.index + "learun@}", strone.ToString()); + // } + // groupSql.Append(groupSqlWhere); + // groupSql.Append(" ) "); + + + // strSql = strSql.Replace("{@learun" + numIndex[i] + "learun@}", groupSql.ToString()); + // } + // } + // } + + + // int num = 1; + // foreach (var conditionItem in itemFormula.Conditions) + // { + // if (string.IsNullOrEmpty(conditionItem.Group)) + // { + // var strone = new StringBuilder(); + // if (conditionItem.Type == "glbd") + // { + // strone.Append($" {conditionItem.RelationField} in ( SELECT {conditionItem.Field} FROM {conditionItem.Table} WHERE {conditionItem.Cfield} "); + // } + // else + // { + // if (conditionItem.F_Symbol == 8) + // { + // strone.Append($" ( {conditionItem.F_FieldId}"); + // } + // else + // { + // strone.Append($" {conditionItem.F_FieldId}"); + // } + + // } + + + // string value = await GetValue(conditionItem.F_FiledValueType, conditionItem.F_FiledValue); + + // switch (conditionItem.F_Symbol) + // { + // case 1:// 等于 + // strone.Append($" = {value}"); + // break; + // case 2:// 大于 + // strone.Append($" > {value}"); + // break; + // case 3:// 大于等于 + // strone.Append($" >= {value}"); + // break; + // case 4:// 小于 + // strone.Append($" < {value}"); + // break; + // case 5:// 小于等于 + // strone.Append($" <= {value}"); + // break; + // case 6:// 包含 + // value = value.Replace("'", ""); + // strone.Append($" like '%{value}%'"); + // break; + // case 7:// 包含于 + // value = value.Replace(",", "','"); + // strone.Append($" in ({value})"); + // break; + // case 8:// 不等于 + // strone.Append($" != {value}"); + + // if (conditionItem.Type == "glbd") + // { + // strone.Append($" or {conditionItem.Cfield} is null "); + // } + // else + // { + // strone.Append($" or {conditionItem.F_FieldId} is null ) "); + // } + + + // break; + // case 9:// 不包含 + // value = value.Replace("'", ""); + // strone.Append($" not like '%{value}%'"); + // break; + // case 10:// 不包含于 + // value = value.Replace(",", "','"); + // strone.Append($" not in ({value})"); + // break; + // default: + // break; + // } + // if (conditionItem.Type == "glbd") + // { + // strone.Append(" ) "); + // } + // else + // { + // strone.Append(" "); + // } + + // strSql = strSql.Replace("{@learun" + num + "learun@}", strone.ToString()); + // } + + + // num++; + // } + // strRes.Append(strSql); + // strRes.Append(" ) "); + + // sqlNum++; + // } + + // return strRes.ToString(); + //} + + /// + /// 分页查询方法,返回datatable + /// + /// sql语句 + /// sql参数 + /// 查询条件 + /// 查询参数 + /// 分页参数 + /// + public async Task FindTable(string sqlStr, object sqlparam, PaginationInputDto pagination, + string whereStr = null, object whereParam = null) + { + var (list, total) = await FindTableByPage(sqlStr, sqlparam, whereStr, whereParam, "", pagination.rows, + pagination.page); + pagination.rows = (int)total; + return DBCommonHelper.DtColToLow(list); + } + + /// + /// 分页查询方法,返回datatable + /// + /// datatable数据 + /// sql语句 + /// sql参数 + /// 查询条件 + /// 查询参数 + /// 排序字段 + /// 每页数据条数 + /// 页码 + /// list数据,total 总共条数 + private async Task<(DataTable list, long total)> FindTableByPage(string sqlStr, object sqlparam, + string whereStr, object whereParam, string orderSql, int pageSize, int pageIndex) + { + try + { + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + RefAsync total = 0; + var sqlQueryable = db.Db.SqlQueryable(sqlStr); + if (sqlparam != null) + { + sqlQueryable = sqlQueryable.AddParameters(sqlparam); + } + + if (!string.IsNullOrEmpty(whereStr)) + { + sqlQueryable = sqlQueryable.Where(whereStr, whereParam); + } + + if (!string.IsNullOrEmpty(orderSql)) + { + sqlQueryable = sqlQueryable.OrderBy(orderSql); + } + + var dt = await sqlQueryable.ToDataTablePageAsync(pageIndex, pageSize, total); + return (dt, total); + } + } + catch (Exception ex) + { + throw ex; + } + } + + /// + /// 查询方法,返回datatable + /// + /// datatable数据 + /// sql语句 + /// 参数 + public async Task FindTable(string sql, object sqlparam = null) + { + try + { + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + var sqlQueryable = db.Db.SqlQueryable(sql); + if (sqlparam != null) + { + sqlQueryable = sqlQueryable.AddParameters(sqlparam); + } + var dt = await sqlQueryable.ToDataTableAsync(); + return DBCommonHelper.DtColToLow(dt); + } + } + catch (Exception ex) + { + throw ex; + } + } + + /// + /// 查询方法,返回datatable + /// + /// datatable数据 + /// sql语句 + /// 参数 + public async Task> FindTableNew(string sql, object sqlparam = null) + { + try + { + List list = new List(); + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + var sqlQueryable = db.Db.SqlQueryable(sql); + if (sqlparam != null) + { + sqlQueryable = sqlQueryable.AddParameters(sqlparam); + } + + var dt = await sqlQueryable.ToDataTableAsync(); + // 遍历每一行 + foreach (DataRow row in dt.Rows) + { + // 遍历每一列 + foreach (DataColumn col in dt.Columns) + { + // 获取当前列的值 + var value = row[col]; + + var colvalue = new { col.ColumnName, value }; + list.Add(colvalue); + } + } + //foreach (DataColumn item in dt.Columns) + //{ + // item.ColumnName = item.ColumnName.ToLower(); + // foreach (DataColumn column in dataTable.Columns) + // { + // var colvalue = new { item.ColumnName, dt.Rows.DefaultValue }; + // } + + // list.Add(colvalue); + //} + return list; + } + } + catch (Exception ex) + { + throw ex; + } + } + + /// + /// 获取编码 + /// + /// 字段值 + /// + public async Task GetRuleCodeEx(object value) + { + var code = value; + if (value != null && value.ToString().IndexOf("code_") != -1) + { + if (codeDic == null) + { + codeDic = new ConcurrentDictionary(); + } + + var codeList = value.ToString().Replace("code_", "").Split("|"); + if (codeDic.ContainsKey(codeList[1])) + { + codeDic.TryGetValue(codeList[1], out code); + } + else + { + code = await this.GetRuleCode(codeList[0]); + codeDic.TryAdd(codeList[1], code); + } + } + + return code; + } + + /// + /// 获取编码 + /// + /// 编码规则编码 + /// + public Task GetRuleCode(string code) + { + var codeRuleApp = IocManager.Instance.GetService(); + return codeRuleApp.GetBillCode(code); + } + + #endregion + + #region 代码发布表单 + + /// + /// 获取分页数据 + /// + /// 功能id + /// 桌面参数 + /// 模板信息主键 + /// 分页参数 + /// 查询条件 + /// + public async Task>> GetFormDataPage(string mid, string desktopParam, + string schemeId, PaginationInputDto pagination, string queryJson) + { + Repository.Domain.FormScheme schemeEntity = await GetScheme(schemeId); + if (schemeEntity == null) + { + return new Response> + { + Result = new PageInfo + { + } + }; + } + + FormSchemeModel formSchemeModel = schemeEntity.Scheme.ToObject(); + + + var query = FormHelper.GetQuerySql(formSchemeModel, queryJson); + query.Sql = query.Sql.Replace("{LEARUN_SASSID}", ""); + string sql = ""; + if (!string.IsNullOrEmpty(mid)) + { + sql = await _dataAuthorizeApp.GetWhereSql(mid); + if (!string.IsNullOrEmpty(sql)) + { + query.Sql = $" select * from ({query.Sql})t where {sql} "; + } + } + + //if (!string.IsNullOrEmpty(desktopParam)) + //{ + // var desktopSql = await _iDesktopBLL.GetSql(desktopParam); + + // if (string.IsNullOrEmpty(sql)) + // { + // query.Sql = $" select * from ({query.Sql})t where {desktopSql} "; + // } + // else + // { + // query.Sql = $" {query.Sql} AND ( {desktopSql} ) "; + // } + //} + var dt = await FindTable(query.Sql, query.DbParameter, pagination); + return new Response> + { + Result = new PageInfo + { + Items = dt, + Total = pagination.rows + } + }; + } + + //去掉tablist + public async Task>> GetFormDataNewPage(string mid, string desktopParam, + string schemeId, PaginationInputDto pagination, string queryJson) + { + Repository.Domain.FormScheme schemeEntity = await GetScheme(schemeId); + if (schemeEntity == null) + { + return new Response> + { + Result = new PageInfo + { + } + }; + } + + FormSchemeNewModel formSchemeModel = schemeEntity.Scheme.ToObject(); + + + var query = FormHelper.GetQuerySqlNew(formSchemeModel, queryJson); + query.Sql = query.Sql.Replace("{LEARUN_SASSID}", ""); + string sql = ""; + if (!string.IsNullOrEmpty(mid)) + { + sql = await _dataAuthorizeApp.GetWhereSql(mid); + if (!string.IsNullOrEmpty(sql)) + { + query.Sql = $" select * from ({query.Sql})t where {sql} "; + } + } + + //if (!string.IsNullOrEmpty(desktopParam)) + //{ + // var desktopSql = await _iDesktopBLL.GetSql(desktopParam); + + // if (string.IsNullOrEmpty(sql)) + // { + // query.Sql = $" select * from ({query.Sql})t where {desktopSql} "; + // } + // else + // { + // query.Sql = $" {query.Sql} AND ( {desktopSql} ) "; + // } + //} + var dt = new DataTable(); + if (pagination != null) + { + dt = await FindTable(query.Sql, query.DbParameter, pagination); + return new Response> + { + Result = new PageInfo + { + Items = dt, + Total = pagination.rows + } + }; + } + else + { + dt = await FindTable(query.Sql, query.DbParameter); + return new Response> + { + Result = new PageInfo + { + Items = dt, + } + }; + } + } + + /// + /// 获取列表数据 + /// + /// 功能id + /// 桌面参数 + /// 模板信息主键 + /// 查询条件 + /// 排序字段 + /// + public async Task GetFormDataList(string mid, string schemeId, string queryJson, string sidx) + { + Repository.Domain.FormScheme schemeEntity = await GetScheme(schemeId); + FormSchemeModel formSchemeModel = schemeEntity.Scheme.ToObject(); + var query = FormHelper.GetQuerySql(formSchemeModel, queryJson); + + query.Sql = query.Sql.Replace("{LEARUN_SASSID}", ""); + string sql = ""; + if (!string.IsNullOrEmpty(mid)) + { + //sql = await this.GetDataAuthoritySql(mid); + if (!string.IsNullOrEmpty(sql)) + { + query.Sql = $" select * from ({query.Sql})t where {sql} "; + } + } + + //if (!string.IsNullOrEmpty(desktopParam)) + //{ + // var desktopSql = await _iDesktopBLL.GetSql(desktopParam); + + // if (string.IsNullOrEmpty(sql)) + // { + // query.Sql = $" select * from ({query.Sql})t where {desktopSql} "; + // } + // else + // { + // query.Sql = $" {query.Sql} AND ( {desktopSql} ) "; + // } + //} + + // 排序字段 + if (!string.IsNullOrEmpty(sidx)) + { + query.Sql += $" order by {sidx}"; + } + + + if (formSchemeModel.FormType == 1) + { + Dictionary DbParameter = new Dictionary(); + foreach (var param in query.DbParameter) + { + DbParameter.Add(param.ParameterName, param.Value); + } + + return await FindTable(query.Sql, DbParameter); + } + + return await FindTable(query.Sql, query.DbParameter); + } + + /// + /// 获取表单数据 + /// + /// 模板信息主键 + /// 主键名 + /// 主键值 + /// + public async Task> GetFormData(string schemeId, string key, string keyValue) + { + Repository.Domain.FormScheme schemeEntity = await GetScheme(schemeId); + FormSchemeModel formSchemeModel = schemeEntity.Scheme.ToObject(); + var list = FormHelper.GetQuery(formSchemeModel, key); + var res = new Dictionary(); + foreach (var item in list) + { + item.Sql = item.Sql.Replace("{LEARUN_SASSID}", ""); + if (string.IsNullOrEmpty(item.RelationName)) + { + var dt = await FindTable(item.Sql, new { keyValue }); + res.Add(item.TableName, dt); + } + else + { + var dt = await FindTable(item.Sql, + new { keyValue = res[item.RelationName].Rows[0][item.RelationField.ToLower()] }); + res.Add(item.TableName, dt); + } + } + + return res; + } + + /// + /// 获取表单数据 + /// + /// 模板信息主键 + /// 主键名 + /// 主键值 + /// + public async Task> GetFormDataNew(string schemeId, string key, string keyValue) + { + // 表单 + Repository.Domain.FormScheme schemeEntity = await GetScheme(schemeId); + FormSchemeNewModel formSchemeModel = schemeEntity.Scheme.ToObject(); + var list = FormHelper.GetQueryNew(formSchemeModel, key); + var res = new Dictionary(); + foreach (var item in list) + { + item.Sql = item.Sql.Replace("{LEARUN_SASSID}", ""); + if (string.IsNullOrEmpty(item.RelationName)) + { + var dt = await FindTable(item.Sql, new { keyValue }); + res.Add(item.TableName, dt); + } + else + { + //var dt = await FindTable(item.Sql, new { keyValue = res[item.RelationName].Rows[0][item.RelationField.ToLower()] }); + var dt = await FindTable(item.Sql, new { keyValue }); + res.Add(item.TableName, dt); + } + } + + return res; + } + + /// + /// 保存表单数据 + /// + /// 参数 + /// + public async Task> SaveFormData(FormDataReq dto) + { + Repository.Domain.FormScheme schemeEntity = await GetScheme(dto.SchemeId); + FormSchemeModel formSchemeModel = schemeEntity.Scheme.ToObject(); + var dataJson = dto.Data.ToJObject(); + var list = FormHelper.GetSaveSql(formSchemeModel, dataJson, dto.Pkey, dto.PkeyValue, dto.IsUpdate); + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + foreach (var item in list) + { + // 遍历参数 + foreach (var p in item.DbParameter) + { + p.Value = await GetRuleCodeEx(p.Value); + } + + var properties = dataJson.Properties(); + foreach (var item2 in properties) + { + if (item2.Value.ToString() != null && item2.Value.ToString().IndexOf("code_") != -1) + { + dataJson[item2.Name] = (await GetRuleCodeEx(item2.Value.ToString())).ToString(); + } + } + + switch (item.ExecuteType) + { + case ExecuteType.Insert: + await db.Db.Ado.ExecuteCommandAsync(ExecuteInsert(item.TableName, item.DbParameter), + item.DbParameter); + break; + case ExecuteType.Update: + await db.Db.Ado.ExecuteCommandAsync( + ExecuteUpdate(item.TableName, item.DbParameter, item.Pkey), item.DbParameter); + break; + case ExecuteType.Delete: + await db.Db.Ado.ExecuteCommandAsync(ExecuteDelete(item.TableName, item.DbParameter), + item.DbParameter); + break; + } + } + + + if (dto.DiffFormData != null) + { + //获取表单更改历史记录信息 add by torres + var difflist = GetSaveHistoryList(dto.DiffFormData, dto.Pkey, dto.PkeyValue, dto.SchemeId, + schemeEntity.SchemeInfoId); + if (difflist.Count > 0) + { + if (formSchemeModel.FormInfo.HistoryType == "2") + { + await db.FormDataHistory.InsertRangeAsync(difflist); + } + else if (formSchemeModel.FormInfo.HistoryType == "1") + { + //await formSchemeService.BaseRepository().Inserts(difflist); + await db.FormDataHistory.InsertRangeAsync(difflist); //待定 + } + } + } + + var flag = db.Commit(); + return new Response + { + Result = dataJson, + Message = flag == true ? "提交成功" : "提交失败" + }; + } + } + + /// + /// 保存表单数据 + /// + /// 参数 + /// + public async Task> SaveFormDataNew(FormDataReq dto) + { + Repository.Domain.FormScheme schemeEntity = await GetScheme(dto.SchemeId); + FormSchemeNewModel formSchemeModel = schemeEntity.Scheme.ToObject(); + //数据为空时,不执行保存 + if (string.IsNullOrEmpty(dto.Data) || dto.Data == "{}") + { + throw new Exception("数据不能为空"); + } + var dataJson = dto.Data.ToJObject(); + _logger.LogError("保存表单数据接收: " + Newtonsoft.Json.JsonConvert.SerializeObject(dto)); + var list = FormHelper.GetSaveSqlNew(formSchemeModel, dataJson, dto.Pkey, dto.PkeyValue, dto.IsUpdate); + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + foreach (var item in list) + { + // 遍历参数 + foreach (var p in item.DbParameter) + { + p.Value = await GetRuleCodeEx(p.Value); + } + + var properties = dataJson.Properties(); + foreach (var item2 in properties) + { + if (item2.Value.ToString() != null && item2.Value.ToString().IndexOf("code_") != -1) + { + dataJson[item2.Name] = (await GetRuleCodeEx(item2.Value.ToString())).ToString(); + } + } + + switch (item.ExecuteType) + { + case ExecuteType.Insert: + await db.Db.Ado.ExecuteCommandAsync(ExecuteInsert(item.TableName, item.DbParameter), + item.DbParameter); + break; + case ExecuteType.Update: + await db.Db.Ado.ExecuteCommandAsync( + ExecuteUpdate(item.TableName, item.DbParameter, item.Pkey), item.DbParameter); + break; + case ExecuteType.Delete: + await db.Db.Ado.ExecuteCommandAsync(ExecuteDelete(item.TableName, item.DbParameter), + item.DbParameter); + break; + } + } + + + if (dto.DiffFormData != null) + { + //获取表单更改历史记录信息 add by torres + var difflist = GetSaveHistoryList(dto.DiffFormData, dto.Pkey, dto.PkeyValue, dto.SchemeId, + schemeEntity.SchemeInfoId); + if (difflist.Count > 0) + { + await db.FormDataHistory.InsertRangeAsync(difflist); + //if (formSchemeModel.FormInfo.HistoryType == "2") + //{ + // await db.FormDataHistory.InsertRangeAsync(difflist); + //} + //else if (formSchemeModel.FormInfo.HistoryType == "1") + //{ + // //await formSchemeService.BaseRepository().Inserts(difflist); + // await db.FormDataHistory.InsertRangeAsync(difflist);//待定 + //} + } + } + + var flag = db.Commit(); + return new Response + { + Result = dataJson, + Message = flag == true ? "提交成功" : "提交失败" + }; + } + } + + #region 历史记录实体列表 + + /// + /// 获取历史记录实体列表 + /// + /// 更新的字段信息 + /// 主键字段 + /// 主键值 + /// 表单配置id + /// 表单信息id + /// + public List GetSaveHistoryList(List historyInfo, string pkey, + string pkeyValue, string schemeId, string f_schemeInfoId) + { + if (historyInfo != null && historyInfo.Count > 0) + { + foreach (var item in historyInfo) + { + item.Id = Guid.NewGuid().ToString(); + item.TablePKey = pkey; + item.TablePKeyValue = pkeyValue; + item.SchemeId = schemeId; + item.SchemeInfoId = f_schemeInfoId; + item.CreaterTime = DateTime.Now; + } + } + + return historyInfo; + } + + #endregion + + #region 拼接字符串 + + /// + /// 插入数据 + /// + /// 表名 + /// 参数 + /// + public string ExecuteInsert(string tableName, List dbParameters) + { + var sql = new StringBuilder(); + var sqlValue = new StringBuilder(); + + sql.Append($" INSERT INTO {tableName} ( \""); + sqlValue.Append($" ( "); + bool isfirt = true; + foreach (var item in dbParameters) + { + if (!isfirt) + { + sql.Append(",\""); + sqlValue.Append(","); + } + + sql.Append($"{item.ParameterName}\""); + sqlValue.Append($"@{item.ParameterName}"); + isfirt = false; + } + + sql.Append($" ) VALUES {sqlValue} )"); + + //var strSql = DBCommonHelper.SqlFormat(sql.ToString(), _dataType); + + return sql.ToString(); + } + + /// + /// 更新数据 + /// + /// 表名 + /// 参数 + /// 主键名 + /// + public string ExecuteUpdate(string tableName, List dbParameters, string pkey) + { + var sql = new StringBuilder(); + sql.Append($" UPDATE {tableName} SET "); + + bool isfirt = true; + foreach (var item in dbParameters) + { + if (item.Value == null) + { + if (!isfirt) + { + sql.Append(","); + } + + sql.Append($"\"{item.ParameterName}\" = null "); + isfirt = false; + } + else + { + if (!isfirt) + { + sql.Append(","); + } + + sql.Append($"\"{item.ParameterName}\" = @{item.ParameterName} "); + isfirt = false; + } + } + + sql.Append($" WHERE \"{pkey}\" = @{pkey} "); + + return sql.ToString(); + } + + /// + /// 删除表数据 + /// + /// 表名 + /// 参数 + /// + public string ExecuteDelete(string tableName, List dbParameters) + { + var sql = new StringBuilder(); + sql.Append($" DELETE FROM {tableName} WHERE 1=1 "); + + foreach (var item in dbParameters) + { + sql.Append($" AND \"{item.ParameterName}\" = @{item.ParameterName} "); + } + + return sql.ToString(); + } + + #endregion + + /// + /// 删除表单数据 + /// + /// 模板信息主键 + /// 主键名 + /// 主键值 + /// + public async Task> DeleteFormData(string schemeId, string key, string keyValue) + { + Repository.Domain.FormScheme schemeEntity = await GetScheme(schemeId); + FormSchemeNewModel formSchemeModel = schemeEntity.Scheme.ToObject(); + + var list = FormHelper.GetQueryNew(formSchemeModel, key); + var res = new Dictionary(); + foreach (var item in list) + { + if (string.IsNullOrEmpty(item.RelationName)) + { + var dt = await FindTable(item.Sql, new { keyValue }); + res.Add(item.TableName, dt); + } + else + { + var dt = await FindTable(item.Sql, new { keyValue }); + res.Add(item.TableName, dt); + } + } + + var deleteList = FormHelper.GetDeleteSqlNew(formSchemeModel, key); + var flag = false; + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + try + { + foreach (var item in deleteList) + { + if (string.IsNullOrEmpty(item.RelationName)) + { + await db.Db.Ado.ExecuteCommandAsync(item.Sql, new { keyValue }); + } + else + { + await db.Db.Ado.ExecuteCommandAsync(item.Sql, new { keyValue }); + } + } + + flag = db.Commit(); + } + catch + { + flag = false; + } + + return new Response + { + Result = flag == true ? "success" : "fail", + Message = flag == true ? "删除成功" : "删除失败" + }; + } + } + + #endregion + + #region 获取矢量切片 + + /// + /// 根据表名获取矢量切片 + /// + /// + /// + public byte[] QueryVectorTileByTable(QueryVectorTileByTableReq req) + { + VectorTileSearchModel searchModel = new VectorTileSearchModel + { + x = req.x, + y = req.y, + z = req.z, + field = req.field, + table = req.table, + filter = req.filter, + }; + var result = new CommonDataManager(base.UnitWork.CreateContext().Db).VectorTile(searchModel); + return result; + } + + #endregion + + #region 导入 + + /// + /// + /// + /// 表单设计id + /// 数据 + /// + public async Task<(DataTable elist, int snum, int fnum)> ImportTable(string id, DataTable dt, string pkey) + { + int snum = 0; + int fnum = 0; + //解析表单 + List list = new List(); + Repository.Domain.FormScheme schemeEntity = await GetScheme(id); + FormSchemeNewModel formSchemeModel = schemeEntity.Scheme.ToObject(); + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Schemas) + { + if (component == null || component.ComponentProps == null || + string.IsNullOrEmpty(component.ComponentProps.DataTable)) + { + continue; + } + + ExcelImportFileds excelImportFileds = new ExcelImportFileds(); + excelImportFileds.ColName = component.Label; + excelImportFileds.Name = component.ComponentProps.FieldName; + excelImportFileds.CsType = component.CsType; + excelImportFileds.RelationType = component.ComponentProps.FieldName == pkey ? 1 : 0; + list.Add(excelImportFileds); + } + } + + DataTable failDt = new DataTable(); + dt.Columns.Add("导入错误", typeof(string)); + foreach (DataColumn dc in dt.Columns) + { + failDt.Columns.Add(dc.ColumnName, dc.DataType); + } + + if (dt.Rows.Count > 0) + { + using (SugarDbContext db = base.UnitWork.CreateContext()) + { + foreach (DataRow dr in dt.Rows) + { + // 行数据循环 + try + { + List dbParameters = new List(); + foreach (var col in list) + { + object paramValue = null; + + switch (col.RelationType) + { + case 0: //无关联 + paramValue = dr[col.ColName].ToString(); + break; + case 1: //GUID + paramValue = Guid.NewGuid().ToString(); + break; + case 2: //数据字典 + + break; + case 3: //数据表 + + break; + case 4: //固定值 + paramValue = col.Value; + break; + case 5: //操作人ID + paramValue = ""; + break; + case 6: //操作人名字 + paramValue = ""; + break; + case 7: //操作时间 + paramValue = DateTime.Now; + break; + } + + dbParameters.Add(FormHelper.GetMyDbParameter(col.Name, paramValue.ToString(), + col.CsType)); + } + + await db.Db.Ado.ExecuteCommandAsync(ExecuteInsert(mainTable.Name, dbParameters), + dbParameters); + db.Commit(); + snum++; + } + catch (Exception ex) + { + fnum++; + + dr["导入错误"] = ex.Message; + failDt.Rows.Add(dr.ItemArray); + } + } + } + } + + return (failDt, snum, fnum); + } + + //导出模板 + public async Task> ExportTemplate(string id, DataTable dt, string pkey) + { + Response response = new Response(); + try + { + //解析表单 + List list = new List(); + Repository.Domain.FormScheme schemeEntity = await GetScheme(id); + FormSchemeNewModel formSchemeModel = schemeEntity.Scheme.ToObject(); + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Schemas) + { + if (component == null || component.ComponentProps == null || + string.IsNullOrEmpty(component.ComponentProps.DataTable)) + { + continue; + } + + ExcelImportFileds excelImportFileds = new ExcelImportFileds(); + excelImportFileds.ColName = component.Label; + excelImportFileds.Name = component.ComponentProps.FieldName; + excelImportFileds.CsType = component.CsType; + excelImportFileds.RelationType = component.ComponentProps.FieldName == pkey ? 1 : 0; + list.Add(excelImportFileds); + } + } + + HSSFWorkbook workbook = new HSSFWorkbook(); + ISheet sheet = workbook.CreateSheet(); + + #region 内容样式 + + IFont font1 = workbook.CreateFont(); //创建一个字体样式对象 + font1.FontName = "Microsoft YaHei"; //和excel里面的字体对应 + //font1.Boldweight = short.MaxValue;//字体加粗 + font1.FontHeightInPoints = 12; //字体大小 + ICellStyle style = workbook.CreateCellStyle(); //创建样式对象 + style.BorderBottom = BorderStyle.Thin; + style.BorderLeft = BorderStyle.Thin; + style.BorderRight = BorderStyle.Thin; + style.BorderTop = BorderStyle.Thin; + style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; + style.VerticalAlignment = VerticalAlignment.Center; + style.SetFont(font1); //将字体样式赋给样式对象 + style.WrapText = true; + + #endregion + + #region 标题样式 + + IFont font = workbook.CreateFont(); //创建一个字体样式对象 + font.FontName = "Microsoft YaHei"; //和excel里面的字体对应 + font.Boldweight = (short)FontBoldWeight.Bold; //字体加粗 + font.FontHeightInPoints = 12; //字体大小 + ICellStyle style1 = workbook.CreateCellStyle(); //创建样式对象 + style1.BorderBottom = BorderStyle.Thin; + style1.BorderLeft = BorderStyle.Thin; + style1.BorderRight = BorderStyle.Thin; + style1.BorderTop = BorderStyle.Thin; + style1.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; + style1.VerticalAlignment = VerticalAlignment.Center; + style1.SetFont(font); //将字体样式赋给样式对象 + + #endregion + + #region 创建表头 + + IRow rowHeader = sheet.CreateRow(0); + rowHeader.Height = 20 * 30; + int j = 0; + foreach (var i in list) + { + rowHeader.CreateCell(j); + rowHeader.Cells[j].CellStyle = style1; + rowHeader.Cells[j].SetCellValue(i.ColName); + sheet.SetColumnWidth(j, 20 * 350); + j++; + } + + #endregion + + response.Result = new MemoryStream(); + workbook.Write(response.Result); + workbook = null; + response.Result.Close(); + response.Result.Dispose(); + response.Code = 200; + response.Message = "获取成功"; + } + catch (Exception ex) + { + response.Code = 500; + response.Message = ex.Message; + } + + return response; + } + + public async Task> ExportTemplateNew(string id, DataTable dt, string pkey) + { + Response response = new Response(); + try + { + //解析表单 + List list = new List(); + Repository.Domain.FormScheme schemeEntity = await GetScheme(id); + FormSchemeNewModel formSchemeModel = schemeEntity.Scheme.ToObject(); + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + foreach (var tab in formSchemeModel.FormInfo.TabList) + { + foreach (var component in tab.Schemas) + { + if (component == null || component.ComponentProps == null || + string.IsNullOrEmpty(component.ComponentProps.DataTable)) + { + continue; + } + + ExcelImportFileds excelImportFileds = new ExcelImportFileds(); + excelImportFileds.ColName = component.Label; + excelImportFileds.Name = component.ComponentProps.FieldName; + excelImportFileds.CsType = component.CsType; + excelImportFileds.RelationType = component.ComponentProps.FieldName == pkey ? 1 : 0; + list.Add(excelImportFileds); + } + } + + response.Code = 200; + response.Message = "获取成功"; + } + catch (Exception ex) + { + response.Code = 500; + response.Message = ex.Message; + } + + return response; + } + + #endregion + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/FormScheme/Request/FormDataReq.cs b/OpenAuth.App/BaseApp/FormScheme/Request/FormDataReq.cs new file mode 100644 index 0000000..76e86ec --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Request/FormDataReq.cs @@ -0,0 +1,37 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Request +{ + public class FormDataReq + { + /// + /// 模板Id + /// + public string SchemeId { get; set; } + /// + /// 是否更新 + /// + public bool IsUpdate { get; set; } + /// + /// 表单数据 + /// + public string Data { get; set; } + /// + /// 主键(更新数据时采用) + /// + public string Pkey { get; set; } + /// + /// 主键值(更新数据时采用) + /// + public string PkeyValue { get; set; } + /// + /// 变更数据 + /// + public List DiffFormData { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Request/FormQueryReq.cs b/OpenAuth.App/BaseApp/FormScheme/Request/FormQueryReq.cs new file mode 100644 index 0000000..9235b9f --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Request/FormQueryReq.cs @@ -0,0 +1,30 @@ +using OpenAuth.App.FormScheme.Response; +using OpenAuth.App.Request; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Request +{ + public class FormQueryReq + { + /// + /// 分页参数 + /// + public PaginationInputDto PaginationInputDto { get; set; } + /// + /// 查询参数 + /// + public string QueryJson { get; set; } + /// + /// 桌面参数 + /// + public string Ldparam { get; set; } + /// + /// 排序字段 + /// + public string Sidx { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Request/FormSchemeReq.cs b/OpenAuth.App/BaseApp/FormScheme/Request/FormSchemeReq.cs new file mode 100644 index 0000000..b3d31c4 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Request/FormSchemeReq.cs @@ -0,0 +1,24 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Request +{ + /// + /// 自定义表单模板保存数据 + /// + public class FormSchemeReq + { + /// + /// 模板基础信息 + /// + public FormSchemeInfo Info { get; set; } + /// + /// 模板信息 + /// + public Repository.Domain.FormScheme Scheme { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/ComponentPropsModel.cs b/OpenAuth.App/BaseApp/FormScheme/Response/ComponentPropsModel.cs new file mode 100644 index 0000000..c190bf0 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/ComponentPropsModel.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + public class ComponentPropsModel + { + /// + /// 表名 + /// + public string DataTable { get; set; } + /// + /// 字段 + /// + public string FieldName { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/ExecuteType.cs b/OpenAuth.App/BaseApp/FormScheme/Response/ExecuteType.cs new file mode 100644 index 0000000..d31b9dd --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/ExecuteType.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + public enum ExecuteType + { + /// + /// 新增 + /// + [Description("新增")] + Insert = 0, + /// + /// 更新 + /// + [Description("更新")] + Update = 1, + /// + /// 删除 + /// + [Description("删除")] + Delete = 2 + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormComponentModel.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormComponentModel.cs new file mode 100644 index 0000000..bc17cc3 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormComponentModel.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + /// + /// 表单组件 + /// + public class FormComponentModel + { + /// + /// 组件类型 + /// + public string Type { get; set; } + /// + /// 标识 + /// + public string Prop { get; set; } + /// + /// 绑定表 + /// + public string Table { get; set; } + /// + /// 绑定字段 + /// + public string Field { get; set; } + /// + /// 单据编码 + /// + public string Code { get; set; } + /// + /// 排序字段 + /// + public string OrderId { get; set; } + /// + /// 是否倒叙 + /// + public bool isDESC { get; set; } + /// + /// 数据字段类型 + /// + public string CsType { get; set; } + + /// + /// 子组件列表 + /// + public List children { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormComponentNewModel.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormComponentNewModel.cs new file mode 100644 index 0000000..8633dd1 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormComponentNewModel.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + public class FormComponentNewModel + { + /// + /// 组件类型 + /// + public string Component { get; set; } + /// + /// 标识 + /// + public string Field { get; set; } + /// + /// 名称 + /// + public string Label { get; set; } + /// + /// 绑定表 + /// + public ComponentPropsModel ComponentProps { get; set; } + /// + /// 单据编码 + /// + public string Code { get; set; } + /// + /// 排序字段 + /// + public string OrderId { get; set; } + /// + /// 是否倒叙 + /// + public bool isDESC { get; set; } + /// + /// 数据字段类型 + /// + public string CsType { get; set; } + + /// + /// 子组件列表 + /// + public List children { get; set; } + /// + /// 子表组件列表 + /// + public List Columns { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormDbTable.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormDbTable.cs new file mode 100644 index 0000000..4f5bdec --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormDbTable.cs @@ -0,0 +1,41 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + public class FormDbTable + { + /// + /// 数据库表名 + /// + public string TableName { get; set; } + /// + /// (更新,查询)条件字段名 + /// + public string Pkey { get; set; } + /// + /// 执行操作类型 + /// + public ExecuteType ExecuteType { get; set; } + /// + /// 执行参数 + /// + public List DbParameter { get; set; } + /// + /// 查询语句 + /// + public string Sql { get; set; } + /// + /// 关联表 + /// + public string RelationName { get; set; } + /// + /// 关联表字段 + /// + public string RelationField { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormDbTableInfo.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormDbTableInfo.cs new file mode 100644 index 0000000..c10a8f4 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormDbTableInfo.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + /// + /// 表单数据表信息 + /// + public class FormDbTableInfo + { + /// + /// 唯一标识 + /// + public string Id { get; set; } + + /// + /// SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 + /// + public string Schema { get; set; } + + /// + /// 表名 + /// + public string Name { get; set; } + + /// + /// 表备注,SqlServer下是扩展属性 MS_Description + /// + public string Comment { get; set; } + + /// + /// main 主表 chlid 子表 + /// + public string Type { get; set; } + /// + /// 关联字段 + /// + public string Field { get; set; } + + /// + /// 关联表 + /// + public string RelationName { get; set; } + /// + /// 关联表字段 + /// + public string RelationField { get; set; } + + /// + /// 视图表单sql语句 + /// + public string Sql { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormInfoModel.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormInfoModel.cs new file mode 100644 index 0000000..67ebdb8 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormInfoModel.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + public class FormInfoModel + { + /// + /// 表单页签集合 + /// + public List TabList { get; set; } + + /// + /// 历史记录存储位置 0 无 1 公共 2 私有 + /// + public string HistoryType { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormInfoNewModel.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormInfoNewModel.cs new file mode 100644 index 0000000..13877d5 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormInfoNewModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + public class FormInfoNewModel + { + /// + /// 表单页签集合 + /// + public List TabList { get; set; } + // public List Schemas { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormSchemeModel.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormSchemeModel.cs new file mode 100644 index 0000000..98087e5 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormSchemeModel.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + /// + /// 表单模板 + /// + public class FormSchemeModel + { + /// + /// 数据库编码 + /// + public string DbCode { get; set; } + /// + /// 数据表单信息 + /// + public List Db { get; set; } + /// + /// 表单信息 + /// + public FormInfoModel FormInfo { get; set; } + /// + /// 1 视图表单 0常规表单 + /// + public int FormType { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormSchemeNewModel.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormSchemeNewModel.cs new file mode 100644 index 0000000..81e3565 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormSchemeNewModel.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + public class FormSchemeNewModel + { + /// + /// 数据库编码 + /// + public string DbCode { get; set; } + /// + /// 数据表单信息 + /// + public List Db { get; set; } + /// + /// 表单信息 + /// + public FormInfoNewModel FormInfo { get; set; } + /// + /// 1 视图表单 0常规表单 + /// + public int? FormType { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormTabModel.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormTabModel.cs new file mode 100644 index 0000000..f04b0e3 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormTabModel.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + /// + /// 表单页签模型 + /// + public class FormTabModel + { + /// + /// 表单组件集合 + /// + public List Components { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/FormTabNewModel.cs b/OpenAuth.App/BaseApp/FormScheme/Response/FormTabNewModel.cs new file mode 100644 index 0000000..6baa70e --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/FormTabNewModel.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + public class FormTabNewModel + { + /// + /// 表单组件集合 + /// + public List Schemas { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/FormScheme/Response/PaginationInputDto.cs b/OpenAuth.App/BaseApp/FormScheme/Response/PaginationInputDto.cs new file mode 100644 index 0000000..694fa46 --- /dev/null +++ b/OpenAuth.App/BaseApp/FormScheme/Response/PaginationInputDto.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.FormScheme.Response +{ + public class PaginationInputDto + { + // + // 摘要: + // 每页行数 + public int rows { get; set; } + + // + // 摘要: + // 当前页 + public int page { get; set; } + + // + // 摘要: + // 排序列 + public string sidx { get; set; } + + // + // 摘要: + // 排序类型 + public string sord { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/HostedService/QuartzService.cs b/OpenAuth.App/BaseApp/HostedService/QuartzService.cs new file mode 100644 index 0000000..3aca26a --- /dev/null +++ b/OpenAuth.App/BaseApp/HostedService/QuartzService.cs @@ -0,0 +1,49 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Quartz; + +namespace OpenAuth.App.HostedService +{ + /// + /// 自启动服务,本服务用于启动所有状态为【正在运行】的定时任务 + /// + public class QuartzService : IHostedService, IDisposable + { + private readonly ILogger _logger; + private IScheduler _scheduler; + private OpenJobApp _openJobApp; + + public QuartzService(ILogger logger, IScheduler scheduler, OpenJobApp openJobApp) + { + _logger = logger; + _scheduler = scheduler; + _openJobApp = openJobApp; + } + + public Task StartAsync(CancellationToken cancellationToken) + { + _scheduler.Start(); + var result = _openJobApp.StartAll(); + return result; + + //return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + var result = _scheduler.Shutdown(); + _logger.LogInformation("关闭定时job"); + return result; + + //return Task.CompletedTask; + } + + public void Dispose() + { + + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/ImMsgManager/ChatsHub.cs b/OpenAuth.App/BaseApp/ImMsgManager/ChatsHub.cs new file mode 100644 index 0000000..fb129d6 --- /dev/null +++ b/OpenAuth.App/BaseApp/ImMsgManager/ChatsHub.cs @@ -0,0 +1,79 @@ +using DocumentFormat.OpenXml.InkML; +using DocumentFormat.OpenXml.Spreadsheet; +using Microsoft.AspNetCore.SignalR; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.BaseApp.ImMsgManager +{ + public class ChatsHub : Hub + { + #region 重载Hub方法 + /// + /// 建立连接 + /// + /// + public override async Task OnConnectedAsync() + { + //await AddOnline(); + await base.OnConnectedAsync(); + } + /// + /// 断开连接 + /// + /// 异常信息 + /// + public override async Task OnDisconnectedAsync(Exception exception) + { + await RemoveOnline(); + await base.OnDisconnectedAsync(exception); + } + #endregion + + private static readonly ConcurrentDictionary clientIdMap = + new ConcurrentDictionary(); + + #region 客户端操作 + ///// + ///// 添加在线用户 + ///// + //public async Task AddOnline() + //{ + //} + /// + /// 移除在线用户 + /// + public async Task RemoveOnline() + { + string clientId = Context.ConnectionId; + clientIdMap.TryGetValue(clientId, out string userId); + await Groups.RemoveFromGroupAsync(clientId, userId); + } + /// + /// 发送消息 + /// + /// 我的UserId + /// 对方UserId + /// 消息 + /// 是否系统消息0不是1是 + public async Task SendMsg(string myUserId, string toUserId, string msg, string id, int isSystem) + { + await Clients.Group(toUserId).SendAsync("RevMsg", myUserId, msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), id, isSystem); + } + + + public async Task SendInfo(string userId) + { + string clientId = Context.ConnectionId; + clientIdMap.GetOrAdd(clientId, userId); + await Groups.AddToGroupAsync(clientId, userId); + } + + #endregion + + } +} diff --git a/OpenAuth.App/BaseApp/ImMsgManager/ImMsgApp.cs b/OpenAuth.App/BaseApp/ImMsgManager/ImMsgApp.cs new file mode 100644 index 0000000..188a368 --- /dev/null +++ b/OpenAuth.App/BaseApp/ImMsgManager/ImMsgApp.cs @@ -0,0 +1,303 @@ +using OpenAuth.App.Base; +using OpenAuth.Repository.Domain; +using OpenAuth.Repository; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Infrastructure; +using SqlSugar; +using OpenAuth.App.BaseApp.Request; +using DocumentFormat.OpenXml.Office2010.Excel; +using Infrastructure.Helpers; +using OpenAuth.Repository.Core; +using OpenAuth.App.BaseApp.WFTask; +using OpenAuth.App.BaseApp.ImMsgManager; +using Microsoft.Extensions.Configuration; +using DocumentFormat.OpenXml.EMMA; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App.BaseApp +{ + public class ImMsgApp : SqlSugarBaseApp + { + private ChatsHub _hub; + private readonly IConfiguration _configuration; + private readonly ISqlSugarClient client; + #region 构造函数 + public ImMsgApp(ChatsHub hub, ISqlSugarClient sqlSugarClient, ISugarUnitOfWork unitWork, ISimpleClient repository, IConfiguration configuration) : base(unitWork, repository, null) + { + _hub = hub; + _configuration = configuration; + this.client = sqlSugarClient; + } + #endregion + + #region 数据查询 + /// + /// 分页获取列表数据 + /// + /// + /// + /// + /// + public async Task>>> LoadImMsgList(string sendUserId, string recvUserId, string keyword, int pageindex, int pagesize) + { + //定义且实例化分页数据 + RefAsync totalCount = 0; + //数据查询并返回 + var info = await this.Repository.AsQueryable() + .Where(t => (t.SendUserid == sendUserId && t.RecvUserid == recvUserId)) + .WhereIF(!string.IsNullOrEmpty(keyword), t => t.Content.Contains(keyword)) + .OrderByDescending(t => t.CreateDate) + .ToPageListAsync(pageindex, pagesize, totalCount); + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + + /// + /// 获取收到的未读消息 + /// + ///当前登录用户id + /// + public async Task>> GetLastList(string userId) + { + //数据查询并返回 + var info = await this.Repository.AsQueryable() + .Where(t => t.RecvUserid == userId&&t.IsRead==0) + .OrderByDescending(t => t.CreateDate) + .ToListAsync(); + return new Response> + { + Result = info + }; + } + + /// + /// 分页获取系统消息 + /// + /// + /// + /// + /// + /// + /// + /// + public async Task>>> LoadSysImMsgList(string myId, string sysCode, string keyword, int? isDelete, int pageindex, int pagesize) + { + //定义且实例化分页数据 + RefAsync totalCount = 0; + //数据查询并返回 + var info = await this.Repository.AsQueryable() + .Where(r=>r.Issystem==1) + .WhereIF(!string.IsNullOrEmpty(myId),r=>r.RecvUserid==myId) + .WhereIF(!string.IsNullOrEmpty(sysCode),r=>r.SendUserid==sysCode) + .WhereIF(!string.IsNullOrEmpty(keyword), t => t.Content.Contains(keyword)) + .WhereIF(isDelete!=null,r=>r.DeleteMark==isDelete) + .OrderByDescending(t => t.CreateDate) + .ToPageListAsync(pageindex, pagesize, totalCount); + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + + //根据contentid获取任务信息 + public async Task GetInfoByContentId(string contentid) + { + var info= await client.Queryable().Where(r=>r.Token==contentid) + .Select(r => new + { + r.Id, + r.ProcessCode, + r.Type, + r.ProcessId + }).ToListAsync(); + return new Response + { + Result = info.Count > 0 ? info.First() : null + }; + } + #endregion + + #region 增删改 + /// + /// 保存(新增) + /// + /// 数据源实体 + /// + public async Task> SaveEntity(ImMsgReq imsg) + { + var flag = false; + ImMsg entity = imsg.MapTo(); + entity.MsgId = Guid.NewGuid().ToString(); + entity.CreateDate = DateTime.Now; + entity.Issystem = 0; + entity.DeleteMark = 0; + + flag = await this.Repository.InsertAsync(entity); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + /// + /// 保存(新增) + /// + /// 数据源实体 + /// + public Response SaveEntitys(List mglist) + { + var flag = false; + flag = this.Repository.InsertRange(mglist); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + /// + /// 删除数据源 + /// + /// 主键 + public async Task> DeleteEntity(string id) + { + var flag = await this.Repository.DeleteByIdAsync(id); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 删除数据源 + /// + /// 主键list + public async Task> DeleteEntitys(List ids) + { + List list = new List(); + list = this.Repository.AsQueryable().Where(r => ids.Contains(r.MsgId)).ToList(); + var flag = await this.Repository.DeleteAsync(list); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 删除数据源(虚拟删除) + /// + /// 主键 + public async Task> VirtualDeleteEntity(string id) + { + using (var uow = base.UnitWork.CreateContext()) + { + await uow.ImMsg.UpdateAsync(r => new ImMsg { DeleteMark = 1 }, r => r.MsgId == id); + var flag = uow.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + + /// + /// 删除数据源(虚拟删除) + /// + /// 主键list + public async Task> VirtualDeleteEntitys(List ids) + { + using (var uow = base.UnitWork.CreateContext()) + { + foreach(var id in ids) + { + await uow.ImMsg.UpdateAsync(r => new ImMsg { DeleteMark = 1 }, r => r.MsgId == id); + } + var flag = uow.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + #endregion + + #region 确认阅读 + /// + /// 确认阅读 + /// + /// 主键 + /// + public async Task> ReadMsg(string id) + { + using (var uow = base.UnitWork.CreateContext()) + { + + await uow.ImMsg.UpdateAsync(r => new ImMsg { IsRead = 1 }, r => r.MsgId == id); + var flag = uow.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + #endregion + + #region 扩展方法 + /// + /// 发送消息 + /// + /// 编码 + /// 用户列表 + /// 消息内容 + /// 消息类型1.短信 2.邮箱 3.微信 4.IM(站内消息) + /// 消息内容id + public async Task SendMsg(string code, IEnumerable userIdList, string content, string messageType, string contentId = "") + { + if (!string.IsNullOrEmpty(content) && userIdList != null) + { + foreach (var userId in userIdList) + { + if (messageType.IndexOf("4") != -1) // 站内消息 + { + ImMsg iMMsgEntity = new ImMsg(); + iMMsgEntity.SendUserid = code; + iMMsgEntity.RecvUserid = userId; + iMMsgEntity.Content = content; + iMMsgEntity.ContentId = contentId; + iMMsgEntity.Issystem = 1; + iMMsgEntity.IsRead = 0; + iMMsgEntity.DeleteMark = 0; + + iMMsgEntity.MsgId = Guid.NewGuid().ToString(); + iMMsgEntity.CreateDate = DateTime.Now; + await this.Repository.InsertAsync(iMMsgEntity); + + var url = _configuration.GetSection("AppSetting:IMUrl").Value; + var imopen = _configuration.GetSection("AppSetting:IMOpen").Value; + await SendHubs.callMethod(url, imopen, "SendMsg", code, userId, content, iMMsgEntity.MsgId, 1); + //await _hub.SendMsg(url,imopen,code, userId, content, iMMsgEntity.MsgId, 1); + } + } + } + } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/ImMsgManager/Request/ImMsgReq.cs b/OpenAuth.App/BaseApp/ImMsgManager/Request/ImMsgReq.cs new file mode 100644 index 0000000..8901354 --- /dev/null +++ b/OpenAuth.App/BaseApp/ImMsgManager/Request/ImMsgReq.cs @@ -0,0 +1,62 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.BaseApp.Request +{ + public class ImMsgReq + { + /// + /// Desc:消息主键 + /// + public string MsgId { get; set; } + + /// + /// Desc:发送者ID + /// + public string SendUserid { get; set; } + + /// + /// Desc:接收者ID + /// + public string RecvUserid { get; set; } + + /// + /// Desc:消息内容 + /// + public string Content { get; set; } + + /// + /// Desc:创建时间 + /// + public DateTime? CreateDate { get; set; } + + /// + /// Desc:是否是系统消息 0 不是 1 是 + /// + public int? Issystem { get; set; } + + /// + /// Desc:内容id + /// + public string ContentId { get; set; } + + /// + /// Desc:消息是否已读 1 是 0 不是;系统消息起作用 + /// + public int? IsRead { get; set; } + + /// + /// Desc:是否删除1 是 0 不是 + /// + public int? DeleteMark { get; set; } + + /// + /// Desc:租户ID + /// + public string TenantId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/ImMsgManager/SendHubs.cs b/OpenAuth.App/BaseApp/ImMsgManager/SendHubs.cs new file mode 100644 index 0000000..3131e90 --- /dev/null +++ b/OpenAuth.App/BaseApp/ImMsgManager/SendHubs.cs @@ -0,0 +1,42 @@ +using ce.autofac.extension; +using Infrastructure.Helpers; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.SignalR.Client; + +namespace OpenAuth.App.BaseApp.ImMsgManager +{ + public static class SendHubs + { + // + // 摘要: + // 调用hub方法 + // + // 参数: + // methodName: + // + // args: + // 参数 + public static async Task callMethod(string imurl2, string imopen,string methodName, params object[] args) + { + if (imopen=="false") + { + return; + } + + if (string.IsNullOrEmpty(imurl2)) + { + IHttpContextAccessor accessor = IocManager.Instance.GetService(); + if (accessor.HttpContext != null) + { + imurl2 = accessor.HttpContext.Request.Host.Value; + imurl2 = ((!accessor.HttpContext.Request.IsHttps) ? ("http://" + imurl2) : ("https://" + imurl2)); + } + } + + HubConnection connection = new HubConnectionBuilder().WithUrl(imurl2 + "/chathub").Build(); + await connection.StartAsync(); + await connection.InvokeCoreAsync(methodName, args); + await connection.StopAsync(); + } + } +} diff --git a/OpenAuth.App/BaseApp/Import/ImportApp.cs b/OpenAuth.App/BaseApp/Import/ImportApp.cs new file mode 100644 index 0000000..aa1f133 --- /dev/null +++ b/OpenAuth.App/BaseApp/Import/ImportApp.cs @@ -0,0 +1,337 @@ +using Infrastructure; +using OpenAuth.App.Base; +using OpenAuth.App.FormScheme; +using OpenAuth.App.Permission; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App.Import +{ + public class ImportApp : SqlSugarBaseApp + { + SysDataItemDetailApp _dataItemDetailApp; + FormSchemeApp _formSchemeApp; + public ImportApp(ISugarUnitOfWork unitWork, SysDataItemDetailApp dataItemDetailApp, FormSchemeApp formSchemeApp, + ISimpleClient repository) + : base(unitWork, repository, null) + { + _dataItemDetailApp = dataItemDetailApp; + _formSchemeApp = formSchemeApp; + } + + /// + /// 获取导入的分页数据 + /// + /// 查询关键字 + /// 菜单id + /// + /// + /// + public async Task>>> LoadExcelImportPage(string keyWord, string moduleId, int page, int limit) + { + RefAsync totalCount = 0; + var expression = Expressionable.Create() + .AndIF(!string.IsNullOrEmpty(keyWord), t => t.Name.Contains(keyWord)) + .AndIF(!string.IsNullOrEmpty(moduleId), t => t.ModuleId == moduleId); + var info = await base.Repository.AsQueryable() + .Where(expression.ToExpression()) + .ToPageListAsync(page, limit, totalCount); + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + + /// + /// 获取表单数据 + /// + /// id + /// + public async Task GetEntity(string id) + { + var entity = await base.Repository.AsQueryable() + .Where(t => t.Id == id) + .FirstAsync(); + return entity; + } + /// + /// 获取配置字段列表 + /// + /// 配置信息主键 + /// + public Task> GetFieldList(string importId) + { + return base.Repository.ChangeRepository>().AsQueryable().Where(t => t.ImportId == importId).ToListAsync(); + } + /// + /// 获取导入配置列表根据模块ID + /// + /// 功能模块主键 + /// + public async Task> GetModuleList(string moduleId) + { + var expression = Expressionable.Create(); + expression = expression.And(t => t.ModuleId == moduleId && t.EnabledMark == 1); + return await base.Repository.AsQueryable().Where(expression.ToExpression()).ToListAsync(); + } + /// + /// 删除数据 + /// + /// 主键 + public async Task> DeleteEntity(string keyValue) + { + using (var uow = base.UnitWork.CreateContext()) + { + await uow.ExcelImport.DeleteByIdAsync(keyValue); + await uow.ExcelImportFileds.DeleteAsync(a => a.ImportId == keyValue); + + var falg = uow.Commit(); + return new Response + { + Result = falg, + Message = (falg == true ? "success" : "error") + }; + } + } + + /// + /// 保存表单(新增、修改) + /// + /// 主键值 + /// 实体数据 + /// 字段列表 + /// + public async Task> SaveEntity(string keyValue, ExcelImport entity, List filedList) + { + using (var uow = base.UnitWork.CreateContext()) + { + if (!string.IsNullOrEmpty(keyValue)) + { + entity.Id = keyValue; + entity.ModifyDate = DateTime.Now; + await uow.ExcelImport.UpdateAsync(entity); + } + else + { + entity.Id = Guid.NewGuid().ToString(); + entity.CreateDate = DateTime.Now; + entity.EnabledMark = 1; + await uow.ExcelImport.InsertAsync(entity); + } + await uow.ExcelImportFileds.DeleteAsync(t => t.ImportId == entity.Id); + foreach (var item in filedList) + { + item.ImportId = entity.Id; + await uow.ExcelImportFileds.InsertAsync(item); + } + var falg = uow.Commit(); + return new Response + { + Result = falg, + Message = (falg == true ? "success" : "error") + }; + } + } + + #region 扩展方法 + /// + /// excel 数据导入(未导入数据写入缓存) + /// + /// 导入模板主键 + /// 导入数据 + /// + public async Task<(DataTable elist, int snum, int fnum)> ImportTable(string templateId, DataTable dt) + { + int snum = 0; + int fnum = 0; + // 创建一个datatable容器用于保存导入失败的数据 + DataTable failDt = new DataTable(); + dt.Columns.Add("导入错误", typeof(string)); + foreach (DataColumn dc in dt.Columns) + { + failDt.Columns.Add(dc.ColumnName, dc.DataType); + } + + if (dt.Rows.Count > 0) + { + ExcelImport entity = await GetEntity(templateId); + List list = (List)await GetFieldList(templateId); + + if (entity != null && list.Count > 0) + { + string sqlonly = " select * from " + entity.DbTable + " where 1=1 {LEARUN_SASSID} "; + // 数据字典数据 + Dictionary> dataItemMap = new Dictionary>(); + Dictionary dataSourceMap = new Dictionary(); + + foreach (DataRow dr in dt.Rows) + { // 行数据循环 + try + { + List dbParameters = new List(); + foreach (var col in list) + { + object paramValue = null; + + switch (col.RelationType) + { + case 0://无关联 + paramValue = dr[col.ColName].ToString(); + await IsOnlyOne(col, sqlonly, dr[col.ColName].ToString(), entity.DbId); + break; + case 1://GUID + paramValue = Guid.NewGuid().ToString(); + break; + case 2://数据字典 + string dataItemName = ""; + if (!dataItemMap.ContainsKey(col.DataItemCode)) + { + List dataItemList = (List)await _dataItemDetailApp.Load(col.DataItemCode, ""); + dataItemMap.Add(col.DataItemCode, dataItemList); + } + dataItemName = FindDataItemValue(dataItemMap[col.DataItemCode], dr[col.ColName].ToString(), col.ColName); + paramValue = dataItemName; + await IsOnlyOne(col, sqlonly, dataItemName, entity.DbId); + break; + case 3://数据表 + string v = ""; + try + { + //string queryJson = "{" + col.F_DSourceExcelId + ":\"" + dr[col.F_ColName].ToString() + "\"}"; + if (!dataSourceMap.ContainsKey(col.DSourceId)) + { + //DataTable sourceDt = await _dataSourceIBLL.GetDataTable(col.DSourceId); + DataTable sourceDt = new DataTable(); + dataSourceMap.Add(col.DSourceId, sourceDt); + } + v = FindDataSourceValue(dataSourceMap[col.DSourceId], col.DSourceExcelId.ToLower(), dr[col.ColName].ToString(), col.DSourceDBId.ToLower()); + paramValue = v; + } + catch (Exception) + { + throw (new Exception("【" + col.ColName + "】 找不到对应的数据")); + } + await IsOnlyOne(col, sqlonly, v, entity.DbId); + break; + case 4://固定值 + paramValue = col.Value; + break; + case 5://操作人ID + paramValue = ""; + break; + case 6://操作人名字 + paramValue = ""; + break; + case 7://操作时间 + paramValue = DateTime.Now; + break; + } + + dbParameters.Add(new SugarParameter(col.Name, paramValue)); + } + + //await excelImportService.BaseRepository(entity.DbId).ExecuteInsert(entity.DbTable, dbParameters); + _formSchemeApp.ExecuteInsert(entity.DbTable, dbParameters); + snum++; + } + catch (Exception ex) + { + fnum++; + if (entity.ErrorType == 0)// 如果错误机制是终止 + { + dr["导入错误"] = $"{ex.Message} 【之后数据未被导入】"; + failDt.Rows.Add(dr.ItemArray); + break; + } + else + { + dr["导入错误"] = ex.Message; + failDt.Rows.Add(dr.ItemArray); + } + } + } + } + } + return (failDt, snum, fnum); + } + + /// + /// 数据字典查找Value + /// + /// 数据字典数据 + /// 项目名 + /// 列名 + /// + private string FindDataItemValue(List dataItemList, string itemName, string colName) + { + SysDataItemDetail dataItem = dataItemList.Find(t => t.ItemName == itemName); + if (dataItem != null) + { + return dataItem.ItemValue; + } + else + { + throw (new Exception("【" + colName + "】数据字典找不到对应值")); + } + } + + + /// + /// 获取数据源数据 + /// + /// 数据源 + /// 名称 + /// 值 + /// 列名 + /// + private string FindDataSourceValue(DataTable dt, string name, string value, string colname) + { + + foreach (DataRow dr in dt.Rows) + { + if (dr[name].ToString() == value) + { + return dr[colname].ToString(); + } + } + + return ""; + } + + /// + /// 判断是否数据有重复 + /// + /// + /// + /// + /// + private async Task IsOnlyOne(ExcelImportFileds col, string sqlonly, string value, string dbId) + { + if (col.OnlyOne == 1) + { + var dp = new Dictionary(); + sqlonly += col.Name + " = @" + col.Name; + dp.Add(col.Name, value); + var d = await _formSchemeApp.FindTableNew(sqlonly, dp); + if (d.Count > 0) + { + throw new Exception("【" + col.ColName + "】此项数据不能重复"); + } + } + } + + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/Import/Response/ExcelImportDto.cs b/OpenAuth.App/BaseApp/Import/Response/ExcelImportDto.cs new file mode 100644 index 0000000..253a573 --- /dev/null +++ b/OpenAuth.App/BaseApp/Import/Response/ExcelImportDto.cs @@ -0,0 +1,24 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Import.Response +{ + /// + /// 提交参数 + /// + public class ExcelImportDto + { + /// + /// Excel数据导入设置 + /// + public ExcelImport Entity { get; set; } + /// + /// Excel数据导入设置字段 + /// + public List List { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/Interface/IAuth.cs b/OpenAuth.App/BaseApp/Interface/IAuth.cs new file mode 100644 index 0000000..6c5807a --- /dev/null +++ b/OpenAuth.App/BaseApp/Interface/IAuth.cs @@ -0,0 +1,45 @@ +/* + *单独提取这个接口,为了以下几点: + * 1、可以方便的实现webapi 和本地登录相互切换 + * 2、可以方便的使用mock进行单元测试 + */ + +using Infrastructure; +using OpenAuth.App.SSO; + +namespace OpenAuth.App.Interface +{ + public interface IAuth + { + /// + /// 检验token是否有效 + /// + /// token值 + /// + /// + bool CheckLogin(string token = "", string otherInfo = ""); + AuthStrategyContext GetCurrentUser(); + string GetUserName(string otherInfo = ""); + string GetUserNickName(string otherInfo = ""); + string GetUserId(string otherInfo = ""); + + /// + /// 登录接口 + /// + /// 登录的应用appkey + /// 用户名 + /// 密码 + /// + Response Login(string appKey, string username, string pwd); + /// + /// 退出登录 + /// + /// + bool Logout(); + + + void CoverToken(string account, string name); + + bool IsSystem(); + } +} diff --git a/OpenAuth.App/BaseApp/Interface/IAuthStrategy.cs b/OpenAuth.App/BaseApp/Interface/IAuthStrategy.cs new file mode 100644 index 0000000..8154e06 --- /dev/null +++ b/OpenAuth.App/BaseApp/Interface/IAuthStrategy.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using Infrastructure; +using OpenAuth.App.Response; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.App +{ + public interface IAuthStrategy + { + List Modules { get; } + + List ModuleElements { get; } + + List Roles { get; } + + List Resources { get; } + + List Orgs { get; } + + List Positions { get; } + + SysUser User + { + get; set; + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Interface/ICustomerForm.cs b/OpenAuth.App/BaseApp/Interface/ICustomerForm.cs new file mode 100644 index 0000000..e387de3 --- /dev/null +++ b/OpenAuth.App/BaseApp/Interface/ICustomerForm.cs @@ -0,0 +1,23 @@ +namespace OpenAuth.App.Interface +{ + /// + /// 开发者自定义表单的统一接口 + /// 例如:FrmLeaveReqApp为请假表单对应的应用层,实现该接口,可以自动向数据库中插入对应的记录 + /// + public interface ICustomerForm + { + /// + /// 该接口定义自定义表单模式时需实现向数据库写入表单数据 + /// + /// 表单对应的流程实例ID + /// 表单数据 + void Add(string flowInstanceId, string frmData); + + /// + /// 该接口定义流程自定义表单模式时需实现向数据库更新表单数据 + /// + /// 更新的时候前端没有存储Id,需要用流程实例ID来关联,如果前端设计了Id字段,则可以不用 + /// 表单数据 + void Update(string flowInstanceId, string frmData); + } +} diff --git a/OpenAuth.App/BaseApp/Jobs/OpenJobApp.cs b/OpenAuth.App/BaseApp/Jobs/OpenJobApp.cs new file mode 100644 index 0000000..0e73753 --- /dev/null +++ b/OpenAuth.App/BaseApp/Jobs/OpenJobApp.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Infrastructure; +using Infrastructure.Const; +using Infrastructure.Extensions; +using Microsoft.Extensions.Logging; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Extensions; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using Quartz; +using SqlSugar; + +namespace OpenAuth.App +{ + /// + /// 系统定时任务管理 + /// + public class OpenJobApp : SqlSugarBaseApp + { + private SysLogApp _sysLogApp; + private IScheduler _scheduler; + private ILogger _logger; + + public OpenJobApp( + ISugarUnitOfWork unitWork, + ISimpleClient repository, + IAuth auth, + SysLogApp sysLogApp, + IScheduler scheduler, + ILogger logger) : base(unitWork, repository, auth) + { + _sysLogApp = sysLogApp; + _scheduler = scheduler; + _logger = logger; + } + + /// + /// 加载列表 + /// + public async Task Load(QueryOpenJobListReq request) + { + int totalCount = 0; + var result = new TableData(); + var objs = Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(request.key), u => u.JobName.Contains(request.key)); + + result.data = await objs.OrderBy(u => u.Id).ToPageListAsync(request.page, request.limit, totalCount); + result.count = totalCount; + + return result; + } + + /// + /// 启动所有状态为正在运行的任务 + /// 通常应用在系统加载的时候 + /// + /// + public async Task StartAll() + { + var jobs = await Repository.GetListAsync(u => u.Status == (int)JobStatus.Running); + foreach (var job in jobs) + { + job.Start(_scheduler); + } + _logger.LogInformation("所有状态为正在运行的任务已启动"); + } + + public void Add(AddOrUpdateOpenJobReq req) + { + var obj = req.MapTo(); + obj.Id = Guid.NewGuid().ToString(); + obj.CreateTime = DateTime.Now; + var user = _auth.GetCurrentUser().User; + obj.CreateUserId = user.Id.ToString(); + obj.CreateUserName = user.Name; + Repository.Insert(obj); + } + + public void AddStart(AddOrUpdateOpenJobReq req) + { + var obj = req.MapTo(); + obj.Id = Guid.NewGuid().ToString(); + obj.CreateTime = DateTime.Now; + obj.CreateUserId = "-1"; + obj.CreateUserName = "System"; + var flag=Repository.Insert(obj); + if (flag == true) + { + var job = Repository.GetFirst(r=>r.Id==obj.Id); + job.Start(_scheduler); + } + } + + public void Update(AddOrUpdateOpenJobReq obj) + { + var user = _auth.GetCurrentUser().User; + base.Repository.Update(u => new SysOpenJob + { + JobName = obj.JobName, + JobType = obj.JobType, + JobCall = obj.JobCall, + JobCallParams = obj.JobCallParams, + Cron = obj.Cron, + Status = obj.Status, + Remark = obj.Remark, + UpdateTime = DateTime.Now, + UpdateUserId = user.Id.ToString(), + UpdateUserName = user.Name + }, u => u.Id == obj.Id); + } + + #region 定时任务运行相关操作 + + /// + /// 返回系统的job接口 + /// + /// + public List QueryLocalHandlers() + { + var types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces() + .Contains(typeof(IJob)))) + .ToArray(); + return types.Select(u => u.FullName).ToList(); + } + + public void ChangeJobStatus(ChangeJobStatusReq req) + { + var job = Repository.GetFirst(u => u.Id == req.Id); + if (job == null) + { + throw new Exception("任务不存在"); + } + + + if (req.Status == (int)JobStatus.NotRun) //停止 + { + job.Stop(_scheduler); + } + else //启动 + { + job.Start(_scheduler); + } + + + var user = _auth.GetCurrentUser().User; + + job.Status = req.Status; + job.UpdateTime = DateTime.Now; + job.UpdateUserId = user.Id.ToString(); + job.UpdateUserName = user.Name; + Repository.Update(job); + } + + public void ChangeJobStatus1(ChangeJobStatusReq req) + { + var job = Repository.GetFirst(u => u.Id == req.Id); + if (job == null) + { + throw new Exception("任务不存在"); + } + + + if (req.Status == (int)JobStatus.NotRun) //停止 + { + job.Stop(_scheduler); + } + else //启动 + { + job.Start(_scheduler); + } + + job.Status = req.Status; + job.UpdateTime = DateTime.Now; + job.UpdateUserId = "-1"; + job.UpdateUserName = "System"; + Repository.Update(job); + } + /// + /// 记录任务运行结果 + /// + /// + public void RecordRun(string jobId) + { + var job = Repository.GetFirst(u => u.Id == jobId); + if (job == null) + { + _sysLogApp.Add(new SysLog + { + TypeName = "定时任务", + TypeId = "AUTOJOB", + Content = $"未能找到定时任务:{jobId}" + }); + return; + } + + job.RunCount++; + job.LastRunTime = DateTime.Now; + Repository.Update(job); + + _sysLogApp.Add(new SysLog + { + CreateName = "Quartz", + CreateId = -1, + TypeName = "定时任务", + TypeId = "AUTOJOB", + Content = $"运行了自动任务:{job.JobName}" + }); + _logger.LogInformation($"运行了自动任务:{job.JobName}"); + } + + /// + /// 按id批量删除 + /// + /// + public virtual void Delete(string[] ids) + { + Repository.Delete(u => ids.Contains(u.Id)); + } + + public void DeleteEntity(SysOpenJob job) + { + Repository.Delete(job); + JobKey jbk = new JobKey(job.Id); + + _scheduler.DeleteJob(jbk); + } + public SysOpenJob Get(string id) + { + return Repository.GetFirst(u => u.Id == id); + } + #endregion + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Jobs/Request/AddOrUpdateOpenJobReq.cs b/OpenAuth.App/BaseApp/Jobs/Request/AddOrUpdateOpenJobReq.cs new file mode 100644 index 0000000..6ccbc4e --- /dev/null +++ b/OpenAuth.App/BaseApp/Jobs/Request/AddOrUpdateOpenJobReq.cs @@ -0,0 +1,59 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a CodeSmith Template. +// +// DO NOT MODIFY contents of this file. Changes to this +// file will be lost if the code is regenerated. +// Author:Yubao Li +// +//------------------------------------------------------------------------------ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text; +using OpenAuth.Repository.Core; + +namespace OpenAuth.App.Request +{ + /// + /// 定时任务 + /// + [Table("OpenJob")] + public partial class AddOrUpdateOpenJobReq + { + + /// + /// Id + /// + public string Id { get; set; } + /// + /// 任务名称 + /// + public string JobName { get; set; } + /// + /// 任务执行方式0:本地任务;1:外部接口任务 + /// + public int JobType { get; set; } + /// + /// 任务地址 + /// + public string JobCall { get; set; } + /// + /// 任务参数,JSON格式 + /// + public string JobCallParams { get; set; } + /// + /// CRON表达式 + /// + public string Cron { get; set; } + /// + /// 任务运行状态(0:停止,1:正在运行,2:暂停) + /// + public int Status { get; set; } + /// + /// 备注 + /// + public string Remark { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Jobs/Request/ChangeJobStatusReq.cs b/OpenAuth.App/BaseApp/Jobs/Request/ChangeJobStatusReq.cs new file mode 100644 index 0000000..c63ac55 --- /dev/null +++ b/OpenAuth.App/BaseApp/Jobs/Request/ChangeJobStatusReq.cs @@ -0,0 +1,16 @@ +namespace OpenAuth.App.Request +{ + public class ChangeJobStatusReq + { + /// + /// 任务ID + /// + public string Id { get; set; } + + /// + /// 改变任务状态 + /// 0:停止;1:启动(任务变成正在运行) + /// + public int Status { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/Jobs/Request/QueryOpenJobListReq.cs b/OpenAuth.App/BaseApp/Jobs/Request/QueryOpenJobListReq.cs new file mode 100644 index 0000000..0753001 --- /dev/null +++ b/OpenAuth.App/BaseApp/Jobs/Request/QueryOpenJobListReq.cs @@ -0,0 +1,7 @@ +namespace OpenAuth.App.Request +{ + public class QueryOpenJobListReq : PageReq + { + //todo:添加自己的请求字段 + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Jobs/SysLogJob.cs b/OpenAuth.App/BaseApp/Jobs/SysLogJob.cs new file mode 100644 index 0000000..19dfa75 --- /dev/null +++ b/OpenAuth.App/BaseApp/Jobs/SysLogJob.cs @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using Infrastructure; +using Quartz; + +namespace OpenAuth.App.Jobs +{ + public class SysLogJob : IJob + { + private SysLogApp _sysLogApp; + private OpenJobApp _openJobApp; + + public SysLogJob(SysLogApp sysLogApp, OpenJobApp openJobApp) + { + _sysLogApp = sysLogApp; + _openJobApp = openJobApp; + } + + public Task Execute(IJobExecutionContext context) + { + var jobId = context.MergedJobDataMap.GetString(Define.JOBMAPKEY); + //todo:这里可以加入自己的自动任务逻辑 + _openJobApp.RecordRun(jobId); + return Task.Delay(1); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Jobs/TaskOverTimeJob.cs b/OpenAuth.App/BaseApp/Jobs/TaskOverTimeJob.cs new file mode 100644 index 0000000..6ea21bf --- /dev/null +++ b/OpenAuth.App/BaseApp/Jobs/TaskOverTimeJob.cs @@ -0,0 +1,78 @@ +using Infrastructure; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using OpenAuth.App.BaseApp.WFTask; +using OpenAuth.App.Interface; +using Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.BaseApp.Jobs +{ + public class TaskOverTimeJob:IJob + { + private ImMsgApp _immsgApp; + private OpenJobApp _openJobApp; + private WFTaskApp _wfTaskApp; + private IAuth _auth; + + public TaskOverTimeJob(ImMsgApp immsgApp, OpenJobApp openJobApp, WFTaskApp wfTaskApp, IAuth auth) + { + _immsgApp = immsgApp; + _openJobApp = openJobApp; + _wfTaskApp = wfTaskApp; + _auth = auth; + } + + public async Task Execute(IJobExecutionContext context) + { + var jobId = context.MergedJobDataMap.GetString(Define.JOBMAPKEY); + //todo:这里可以加入自己的自动任务逻辑 + try + { + var job = _openJobApp.Get(jobId); + if (job != null) + { + var parms = (JObject)JsonConvert.DeserializeObject(job.JobCallParams); + string taskid = parms["TaskId"].ToString(); + + //更新任务状态 + var taskInfo = _wfTaskApp.GetEntity(taskid); + if(taskInfo != null && (taskInfo.State == 3 || taskInfo.State == 4)) + { + _openJobApp.DeleteEntity(job); + } + else + { + taskInfo.IsOutTime = 2; + _wfTaskApp.Update(taskInfo); + + //创建消息接收用户集合 + List userlist = new List(); + userlist.Add(taskInfo.UserId); + var users = _wfTaskApp.GetUsers(taskid); + userlist = userlist.Union(users).ToList(); + //创建消息发送内容 + string msg = $"任务{taskInfo.ProcessTitle}{taskInfo.UnitName}已严重超时,请及时办理"; + + //更新Job信息,停止job,运行次数+1 + _openJobApp.RecordRun(jobId); + _openJobApp.ChangeJobStatus1(new App.Request.ChangeJobStatusReq { Id = jobId, Status = 0 }); + + //发送消息 + await _immsgApp.SendMsg("ChaoShi", userlist, msg, "4", taskInfo.Token); + } + } + } + catch + { + + } + + await Task.CompletedTask; + } + } +} diff --git a/OpenAuth.App/BaseApp/Jobs/TaskTimeoutJob.cs b/OpenAuth.App/BaseApp/Jobs/TaskTimeoutJob.cs new file mode 100644 index 0000000..e8de900 --- /dev/null +++ b/OpenAuth.App/BaseApp/Jobs/TaskTimeoutJob.cs @@ -0,0 +1,80 @@ +using Infrastructure; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.WFTask; +using DocumentFormat.OpenXml.Drawing.Diagrams; +using OpenAuth.Repository.Domain; +using OpenAuth.App.Interface; + +namespace OpenAuth.App.BaseApp.Jobs +{ + public class TaskTimeoutJob : IJob + { + private ImMsgApp _immsgApp; + private OpenJobApp _openJobApp; + private WFTaskApp _wfTaskApp; + private IAuth _auth; + + public TaskTimeoutJob(ImMsgApp immsgApp, OpenJobApp openJobApp,WFTaskApp wfTaskApp, IAuth auth) + { + _immsgApp = immsgApp; + _openJobApp = openJobApp; + _wfTaskApp= wfTaskApp; + _auth = auth; + } + + public async Task Execute(IJobExecutionContext context) + { + var jobId = context.MergedJobDataMap.GetString(Define.JOBMAPKEY); + //todo:这里可以加入自己的自动任务逻辑 + try + { + var job = _openJobApp.Get(jobId); + if (job != null) + { + var parms = (JObject)JsonConvert.DeserializeObject(job.JobCallParams); + string taskid = parms["TaskId"].ToString(); + + //更新任务状态 + var taskInfo = _wfTaskApp.GetEntity(taskid); + if (taskInfo != null && (taskInfo.State == 3 || taskInfo.State == 4)) + { + _openJobApp.DeleteEntity(job); + } + else + { + taskInfo.IsOutTime = 1; + _wfTaskApp.Update(taskInfo); + + //创建消息接收用户集合 + List userlist = new List(); + userlist.Add(taskInfo.UserId); + var users = _wfTaskApp.GetUsers(taskid); + userlist = userlist.Union(users).ToList(); + //创建消息发送内容 + string msg = $"任务{taskInfo.ProcessTitle}{taskInfo.UnitName}已超时,请及时办理"; + + //更新Job信息,停止job,运行次数+1 + _openJobApp.RecordRun(jobId); + _openJobApp.ChangeJobStatus1(new App.Request.ChangeJobStatusReq { Id = jobId, Status = 0 }); + + //发送消息 + await _immsgApp.SendMsg("ChaoShi", userlist, msg, "4", taskInfo.Token); + } + } + } + catch + { + return; + } + + await Task.CompletedTask; + } + } +} diff --git a/OpenAuth.App/BaseApp/ModuleManager/ModuleManagerApp.cs b/OpenAuth.App/BaseApp/ModuleManager/ModuleManagerApp.cs new file mode 100644 index 0000000..1e757a4 --- /dev/null +++ b/OpenAuth.App/BaseApp/ModuleManager/ModuleManagerApp.cs @@ -0,0 +1,286 @@ +using System.Collections.Generic; +using System.Linq; +using Infrastructure; +using Microsoft.AspNetCore.Mvc; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; +using OpenAuth.App.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.ModuleManager; +using OpenAuth.App.ModuleManager.Response; +using OpenAuth.App.Request; +using OpenAuth.Repository; +using OpenAuth.Repository.Core; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + public class ModuleManagerApp : StringTreeApp + { + private ISqlSugarClient client; + + public ModuleManagerApp( + ISugarUnitOfWork unitWork, + ISimpleClient repository + , IAuth auth) : base(unitWork, repository, auth) + { + client = base.Repository.AsSugarClient(); + } + + #region 菜单 + + #region 查询 + + #region 菜单树 + + /// + /// 菜单树【全部数据】 + /// + /// + /// + public Response> ModulesTree(string name) + { + var result = new Response>(); + + if (!string.IsNullOrEmpty(name)) + { + object[] orgIds = base.Repository.AsQueryable() + .Where(a => a.Name.Contains(name)) + .Select(it => it.Id).ToList().Cast().ToArray(); + + result.Result = base.Repository.AsQueryable() + .OrderBy(a => a.SortNo) + .Select() + .ToTree(a => a.Children, a => a.ParentId, 0, orgIds); + } + else + { + result.Result = base.Repository.AsQueryable() + .OrderBy(a => a.SortNo) + .Select() + .ToTree(a => a.Children, a => a.ParentId, 0, a => a.Id); + } + + return result; + } + + #endregion + + #region 单个菜单 + + public async Task> ModuleById(string id) + { + var model = await base.Repository.GetByIdAsync(id); + return new Response { Result = model }; + } + + #endregion + + #endregion + + #region 增加 + + public Response Add(SysModule model) + { + var loginContext = _auth.GetCurrentUser(); + if (loginContext == null) + { + throw new CommonException("登录已过期", Define.INVALID_TOKEN); + } + + //后面再看 + //CalculateCascade(model); + model.Id = Guid.NewGuid().ToString(); + var flag = Repository.Insert(model); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + #endregion + + #region 修改 + + public Response Update(SysModule obj) + { + try + { + //var flag = base.Repository.Update(obj); + //if (flag) + //{ + // return new Response { Result = true, Message = "success" }; + //} + //else + //{ + // return new Response { Result = false, Message = "error" }; + //} + UpdateTreeObj(obj); + return new Response { Result = true, Message = "success" }; + } + catch (Exception ex) + { + return new Response { Result = false, Message = "error:" + ex.Message.ToString() }; + } + } + + #endregion + + #region 删除 + + /// + /// 删除指定的菜单 + /// + /// + public async Task> Delete(string[] ids) + { + using (var uow = base.UnitWork.CreateContext()) + { + await uow.Module.DeleteByIdAsync(ids.Cast().ToArray()); + await uow.ModuleElement.DeleteAsync(a => ids.Contains(a.ModuleId)); + var flag = uow.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + + #endregion + + #endregion + + #region 按钮 + + #region 查询 + + #region 根据 ModuleId 获取 Elements + + /// + /// 根据 ModuleId 获取 Elements + /// + /// + /// + public async Task>>> ElementsByModule( + [FromQuery] QueryElementListReq req) + { + RefAsync totalCount = 0; + + var elements = await base.Repository.ChangeRepository>().AsQueryable() + .WhereIF(!string.IsNullOrEmpty(req.key), el => el.Name.Contains(req.key)) + .WhereIF(!string.IsNullOrEmpty(req.ModuleId), el => el.ModuleId == req.ModuleId) + .ToPageListAsync(req.page, req.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = elements, + Total = totalCount + } + }; + } + + #endregion + + #endregion + + #region 添加 + + public Response AddMenu(SysModuleElement model) + { + var loginContext = _auth.GetCurrentUser(); + if (loginContext == null) + { + throw new CommonException("登录已过期", Define.INVALID_TOKEN); + } + + using (var uow = base.UnitWork.CreateContext()) + { + model.Id = Guid.NewGuid().ToString(); + uow.ModuleElement.Insert(model); + var flag = uow.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + + #endregion + + #region 修改 + + public Response UpdateMenu(SysModuleElement model) + { + var flag = base.Repository.ChangeRepository>().Update(model); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + #endregion + + #region 删除 + + public async Task> DelMenu(string[] ids) + { + var flag = await base.Repository.ChangeRepository>() + .DeleteByIdAsync(ids.Cast().ToArray()); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + #endregion + + #endregion + + #region 用户/角色分配模块 + + /// + /// 加载特定角色的模块 + /// + /// The role unique identifier. + public async Task> LoadForRole(long roleId) + { + var respone = new Response(); + + using (var uwo = UnitWork.CreateContext()) + { + respone.Result = new ModulesWithElements + { + ElementIds = (await uwo.SysRoleElement.GetListAsync(a => a.RoleId == roleId)) + .Select(a => a.ElementId).ToList(), + ModuleIds = (await uwo.SysRoleModule.GetListAsync(a => a.RoleId == roleId)) + .Select(a => a.ModuleId).ToList() + }; + } + + return respone; + } + + #endregion 用户/角色分配模块 + + public async Task>> AllModule() + { + var modules = + await Repository.AsQueryable().Select(a => new SysModule + { + Id = a.Id, + ModuleTypeId = a.ModuleTypeId + }).Where(a => a.Status == 1).OrderBy(a => a.SortNo) + .ToListAsync(); + return new Response> { Result = modules }; + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/ModuleManager/Request/QueryElementListReq.cs b/OpenAuth.App/BaseApp/ModuleManager/Request/QueryElementListReq.cs new file mode 100644 index 0000000..fb2512e --- /dev/null +++ b/OpenAuth.App/BaseApp/ModuleManager/Request/QueryElementListReq.cs @@ -0,0 +1,14 @@ +using OpenAuth.App.Request; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.ModuleManager +{ + public class QueryElementListReq : PageReq + { + public string ModuleId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/ModuleManager/Response/ModuleElementVM.cs b/OpenAuth.App/BaseApp/ModuleManager/Response/ModuleElementVM.cs new file mode 100644 index 0000000..a95b493 --- /dev/null +++ b/OpenAuth.App/BaseApp/ModuleManager/Response/ModuleElementVM.cs @@ -0,0 +1,49 @@ +namespace OpenAuth.App.Response +{ + /// + /// 用户ID + /// + public class ModuleElementVM + { + /// + /// 用户ID + /// + /// + public int Id { get; set; } + + /// + /// DOM ID + /// + /// + public string DomId { get; set; } + + /// + /// 组织名称 + /// + /// + public string Name { get; set; } + + //模块ID + public int ModuleId { get; set; } + + /// + /// 所属模块名称 + /// + public string ModuleName { get; set; } + + /// + /// 授权状态 + /// + public bool Accessed { get; set; } + + public ModuleElementVM() + { + this.Id = 0; + this.DomId = string.Empty; + this.Name = string.Empty; + this.ModuleId = 0; + this.ModuleName = string.Empty; + this.Accessed = false; + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/ModuleManager/Response/ModuleView.cs b/OpenAuth.App/BaseApp/ModuleManager/Response/ModuleView.cs new file mode 100644 index 0000000..6ca865e --- /dev/null +++ b/OpenAuth.App/BaseApp/ModuleManager/Response/ModuleView.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using Infrastructure; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.App.Response +{ + public class ModuleView + { + /// + /// ID + /// + /// + public string Id { get; set; } + + /// + /// 节点语义ID + /// + public string CascadeId { get; set; } + + /// + /// 名称 + /// + /// + public string Name { get; set; } + + /// + /// 主页面URL + /// + /// + public string Url { get; set; } + + /// + /// 父节点流水号 + /// + /// + public string ParentId { get; set; } + + /// + /// 父节点流水号 + /// + /// + public string ParentName { get; set; } + + /// + /// 节点图标文件名称 + /// + /// + public string IconName { get; set; } + + + /// + /// 当前状态,0:正常,-1:隐藏,不在导航列表中显示 + /// + public int Status { get; set; } + + + public bool Checked { get; set; } + + /// + /// 排序号 + /// + public int SortNo { get; set; } + + public string Code { get; set; } + + public bool IsSys { get; set; } + public string ModuleTypeId { get; set; } + + /// + /// 模块中的元素 + /// + public List Elements { get; set; } + + public static implicit operator ModuleView(SysModule module) + { + return module.MapTo(); + } + + public static implicit operator SysModule(ModuleView view) + { + return view.MapTo(); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/ModuleManager/Response/ModulesWithElements.cs b/OpenAuth.App/BaseApp/ModuleManager/Response/ModulesWithElements.cs new file mode 100644 index 0000000..79b4910 --- /dev/null +++ b/OpenAuth.App/BaseApp/ModuleManager/Response/ModulesWithElements.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.ModuleManager.Response +{ + public class ModulesWithElements + { + public List ModuleIds { get; set; } + + public List ElementIds { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/OrgManager/OrgManagerApp.cs b/OpenAuth.App/BaseApp/OrgManager/OrgManagerApp.cs new file mode 100644 index 0000000..424ead0 --- /dev/null +++ b/OpenAuth.App/BaseApp/OrgManager/OrgManagerApp.cs @@ -0,0 +1,633 @@ +using Infrastructure; +using Infrastructure.Extensions; +using OpenAuth.App.Base; +using OpenAuth.App.Base.Tree; +using OpenAuth.App.BasicQueryService; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.Repository; +using OpenAuth.Repository.Core; +using OpenAuth.Repository.Domain; +using SqlSugar; +using SqlSugar.Extensions; +using System.Collections.Generic; +using System.Diagnostics; + +namespace OpenAuth.App +{ + public class OrgManagerApp : LongTreeApp + { + UserManager userManager; + + private ISqlSugarClient client; + public OrgManagerApp( + ISugarUnitOfWork unitWork, + ISimpleClient repository, + ISqlSugarClient sqlSugarClient, + UserManager userManager, + IAuth auth) : base(unitWork, repository, auth) + { + this.client = sqlSugarClient; + this.userManager = userManager; + + } + + #region 查询 + + #region 部门树 + /// + /// name 为空查全部 + /// + /// + /// + public async Task>> OrgsAllTree(string name) + { + var result = new Response>(); + var user = _auth.GetCurrentUser().User; + string sql = "select \"min\"(\"Level\") from sys_userorg where \"UserId\"='" + user.Id + "' "; + var level = client.Ado.GetInt(sql); + if (level>0) + { + + string sql2 = "select \"OrgId\" from sys_userorg where \"Level\"="+level + " and \"UserId\"='" + user.Id + "' "; + List orgIds1 = client.Ado.SqlQuery(sql2); + int count = orgIds1.Count; + for (int i = 0; i < count; i++) { + List longs = getAllChildOrgId(orgIds1[i]); + orgIds1.AddRange(longs); + } + + var orglist = base.Repository.AsSugarClient().Queryable() + .Where(a => a.UserId == user.Id).Select(a => a.OrgId) + .ToList(); + var query = base.Repository.AsQueryable().Where(a => orgIds1.Contains(a.Id) || a.CreateId == user.Id) + .Select(); + + if (!string.IsNullOrEmpty(name)) + { + object[] orgIds = (await base.Repository.AsQueryable() + .Where(a => a.Name.Contains(name)) + .Select(it => it.Id).ToListAsync()).Cast().ToArray(); + + result.Result = await query.ToTreeAsync(a => a.Children, a => a.ParentId, 0, orgIds); + } + else + { + result.Result = await query.ToTreeAsync(a => a.Children, a => a.ParentId, 0, a => a.Id); + } + + return result; + } + else { + var query = base.Repository.AsQueryable() + .Select(); + + if (!string.IsNullOrEmpty(name)) + { + object[] orgIds = (await base.Repository.AsQueryable() + .Where(a => a.Name.Contains(name)) + .Select(it => it.Id).ToListAsync()).Cast().ToArray(); + + result.Result = await query.ToTreeAsync(a => a.Children, a => a.ParentId, 0, orgIds); + } + else + { + result.Result = await query.ToTreeAsync(a => a.Children, a => a.ParentId, 0, a => a.Id); + } + + return result; + } + } + public List getAllChildOrgId( long parentId) { + var query = base.Repository.AsSugarClient().Queryable() + .Where(c => c.ParentId == parentId) + .Select(c => new { c.Id, c.ParentId }) + .ToList(); + + var childIds = query.Select(c => c.Id).ToList(); + var grandChildIds = query.SelectMany(c => getAllChildOrgId( c.Id)).ToList(); + + childIds.AddRange(grandChildIds); + return childIds; + } + /// + /// name 为空查全部 + /// + /// + /// + public async Task>> OrgsTree(string name) + { + /* var result = new Response>(); + + var userId = long.Parse(_auth.GetUserId()); + + var query = userManager.UserOrgs(userId); + + var orgs = await query + .WhereIF(!string.IsNullOrEmpty(name), (u, o) => o.Name.Contains(name)) + .Select().ToListAsync(); + + //if (!string.IsNullOrEmpty(name)) + //{ + // object[] orgIds = (await query + // .Where((u, o) => o.Name.Contains(name)) + // .Select((u, o) => o.Id).ToListAsync()).Cast().ToArray(); + + // result.Result = await query.Select() + // .ToTreeAsync(a => a.Children, a => a.ParentId, 0, orgIds); + //} + //else + //{ + // result.Result = await query.Select() + // .ToTreeAsync(a => a.Children, a => a.ParentId, 0, a => a.Id); + //} + + result.Result = orgs.BuildTree().ToList(); + + return result;*/ + var result = new Response>(); + var user = _auth.GetCurrentUser().User; + string sql = "select \"min\"(\"Level\") from sys_userorg where \"UserId\"='" + user.Id + "' "; + var level = client.Ado.GetInt(sql); + if ( level > 0) + { + + string sql2 = "select \"OrgId\" from sys_userorg where \"Level\"=" + level + " and \"UserId\"='" + user.Id + "' "; + List orgIds1 = client.Ado.SqlQuery(sql2); + int count = orgIds1.Count; + for (int i = 0; i < count; i++) + { + List longs = getAllChildOrgId(orgIds1[i]); + orgIds1.AddRange(longs); + } + + + var query = await base.Repository.AsQueryable().Where(a => orgIds1.Contains(a.Id) || a.CreateId == user.Id) + .Select().ToListAsync(); + + if (!string.IsNullOrEmpty(name)) + { + object[] orgIds = (await base.Repository.AsQueryable() + .Where(a => a.Name.Contains(name)) + .Select(it => it.Id).ToListAsync()).Cast().ToArray(); + + result.Result = query.BuildTree().ToList(); + } + else + { + result.Result = query.BuildTree().ToList(); + } + + return result; + } + else + { + var query = base.Repository.AsQueryable() + .Select(); + + if (!string.IsNullOrEmpty(name)) + { + object[] orgIds = (await base.Repository.AsQueryable() + .Where(a => a.Name.Contains(name)) + .Select(it => it.Id).ToListAsync()).Cast().ToArray(); + + result.Result = await query.ToTreeAsync(a => a.Children, a => a.ParentId, 0, orgIds); + } + else + { + result.Result = await query.ToTreeAsync(a => a.Children, a => a.ParentId, 0, a => a.Id); + } + + return result; + } + } + + /// + /// 部门和职级组合树 + /// + /// + public async Task>> OrgPositonTree() + { + var client = base.Repository.AsSugarClient(); + + var orgQuery = base.Repository.AsQueryable() + .Select(a => new TreeItemLong { Key = 0, Tag = "" }, true); + + var posQuery = client.Queryable((p, o) => + new JoinQueryInfos(JoinType.Left, p.GroupId == o.PosGroupId)) + .Where((p, o) => o.Id != null) + .Select((p, o) => new TreeItemLong + { + Key = p.Id, + Tag = o.Id.ToString(), + Id = p.Id, + Name = p.Name, + ParentId = p.ParentId == 0 ? o.Id : p.ParentId, + }); + + var poses = posQuery.ToList(); + + var list = await client.UnionAll(orgQuery, posQuery) + .Mapper(a => + { + if (a.Id == a.Key) + { + var item = poses.Where(m => m.Id == a.Id).First(); + item.Id = Yitter.IdGenerator.YitIdHelper.NextId(); + + a.Id = item.Id; + + var parent = poses.Where(m => m.Key == a.ParentId && m.Tag == a.Tag).FirstOrDefault(); + if (parent != null) + { + a.ParentId = parent.Id; + } + } + }) + .ToTreeAsync(a => a.Children, a => a.ParentId, 0, a => a.Id); + + return new Response> + { + Result = list + }; + + } + #endregion + + #region 分页 + /// + /// 查询部门列表 + /// + /// + /// + public async Task>>> LoadAllPage(QueryOrgListReq req) + { + var user = _auth.GetCurrentUser().User; + string sql = "select \"min\"(\"Level\") from sys_userorg where \"UserId\"='" + user.Id + "' "; + var level = client.Ado.GetInt(sql); + if ( level > 0) + { + + string sql2 = "select \"OrgId\" from sys_userorg where \"Level\"=" + level + " and \"UserId\"='" + user.Id + "' "; + List orgIds1 = client.Ado.SqlQuery(sql2); + int count = orgIds1.Count; + for (int i = 0; i < count; i++) + { + List longs = getAllChildOrgId(orgIds1[i]); + orgIds1.AddRange(longs); + } + RefAsync totalCount = 0; + + var orgs = await base.Repository.AsQueryable() + .WhereIF(req.OrgId != 0, o => o.ParentId == req.OrgId) + .WhereIF(!string.IsNullOrEmpty(req.key), o => o.Name.Contains(req.key)) + .Where(a => orgIds1.Contains(a.Id) || a.CreateId == user.Id) + .OrderByDescending(o => o.CreateTime) + .ToPageListAsync(req.page, req.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = orgs, + Total = totalCount + } + }; + } + else { + RefAsync totalCount = 0; + + var orgs = await base.Repository.AsQueryable() + .WhereIF(req.OrgId != 0, o => o.ParentId == req.OrgId) + .WhereIF(!string.IsNullOrEmpty(req.key), o => o.Name.Contains(req.key)) + .OrderByDescending(o => o.CreateTime) + .ToPageListAsync(req.page, req.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = orgs, + Total = totalCount + } + }; + } + + } + + public async Task>>> LoadPage(QueryOrgListReq req) + { + + var user = _auth.GetCurrentUser().User; + string sql = "select \"min\"(\"Level\") from sys_userorg where \"UserId\"='" + user.Id + "' "; + var level = client.Ado.GetInt(sql); + if (level > 0) + { + + string sql2 = "select \"OrgId\" from sys_userorg where \"Level\"=" + level + " and \"UserId\"='" + user.Id + "' "; + List orgIds1 = client.Ado.SqlQuery(sql2); + int count = orgIds1.Count; + for (int i = 0; i < count; i++) + { + List longs = getAllChildOrgId(orgIds1[i]); + orgIds1.AddRange(longs); + } + RefAsync totalCount = 0; + + var orgs = await base.Repository.AsQueryable() + .WhereIF(req.OrgId != 0, o => o.ParentId == req.OrgId) + .WhereIF(!string.IsNullOrEmpty(req.key), o => o.Name.Contains(req.key)) + .Where(a => orgIds1.Contains(a.Id) || a.CreateId == user.Id) + .OrderByDescending(o => o.CreateTime) + .ToPageListAsync(req.page, req.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = orgs, + Total = totalCount + } + }; + } + else + { + RefAsync totalCount = 0; + + var userId = long.Parse(_auth.GetUserId()); + + var orgs = await userManager.UserOrgs(userId) + .WhereIF(req.OrgId != 0, (u, o) => o.ParentId == req.OrgId) + .WhereIF(!string.IsNullOrEmpty(req.key), (u, o) => o.Name.Contains(req.key)) + .OrderByDescending((u, o) => o.CreateTime) + .Select((u, o) => o) + .ToPageListAsync(req.page, req.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = orgs, + Total = totalCount + } + }; + } + + } + #endregion + + #region 实体 + public SysOrg Get(string id) + { + return Repository.GetById(id); + } + #endregion + + #region 子节点 + public async Task> LoadChildren(long? parentId) + { + SysUser user = _auth.GetCurrentUser().User; + //string sql = "select \"min\"(\"Level\") from sys_userorg where \"UserId\"='"+user.Id+"' "; + //var level = client.Ado.GetInt(sql); + /*if (user.Id == -1||level==0) + {*/ + List children = new List(); + if (parentId != null) + { + children= await base.Repository.AsQueryable().Where(r=>r.ParentId==parentId).OrderBy(r=>r.SortNo).ToListAsync(); + } + return children; + /* } + else + { + if (parentId == 0) + { + return await base.Repository.GetListAsync(a => a.ParentId == parentId); + } else if(parentId== 371300) + { + var orglist = base.Repository.AsSugarClient().Queryable() + .Where(a => a.UserId == user.Id).Select(a => a.OrgId) + .ToList(); + return await base.Repository.GetListAsync(a => orglist.Contains(a.Id) || a.CreateId == user.Id); + } + else + { + var orglist = base.Repository.AsSugarClient().Queryable() + .Where(a => a.UserId == user.Id).Select(a => a.OrgId) + .ToList(); + return await base.Repository.GetListAsync(a => a.ParentId == parentId && orglist.Contains(a.Id) || a.CreateId == user.Id); + } + + }*/ + } + + #region 用户关联的部分和职级 + public async Task> UserOrgs(long userId) + { + return await base.Repository.AsSugarClient().Queryable() + .Where(a => a.UserId == userId) + .ToListAsync(); + } + #endregion + #endregion + + #region 父节点 + public async Task> LoadParents(long childId) + { + return await client.Queryable().ToParentListAsync(it => it.ParentId, childId); + } + #endregion + + #endregion + + #region 增删改 + + #region 增加 + /// + /// 添加部门 + /// + /// The org. + /// System.Int32. + /// 未能找到该组织的父节点信息 + public Response Add(OrgForm org) + { + var loginContext = _auth.GetCurrentUser(); + if (loginContext == null) + { + throw new CommonException("登录已过期", Define.INVALID_TOKEN); + } + + SysOrg model = org.MapTo(); + + //后边再看 + //CalculateCascade(model); + + using (var uow = base.UnitWork.CreateContext()) + { + if (model.Id <= 0) { + model.Id = Yitter.IdGenerator.YitIdHelper.NextId(); + } + + model.ParentName = getParentName(model.ParentId); + model.CreateId = loginContext.User.Id; + model.CreateTime = DateTime.Now; + if (model.ParentId == 0) { + model.Level = 0; + model.CascadeId = "0."+model.Id; + }else + { + long parentId = model.ParentId; + int Level = 0; + string cascade = ""; + while (true) + { + String sql = "select \"ParentId\" from sys_org where \"Id\"=" + parentId; + long id = client.Ado.GetLong(sql); + // long id = base.Repository.AsSugarClient().Queryable().Where(a => a.Id == parentId).Select(a => a.ParentId).ToLong(); + if (!string.IsNullOrEmpty(cascade)) { + cascade = id + "." + cascade; + }else + { + cascade = id + cascade; + } + + parentId = id; + Level++; + if (id == 0) { + break; }} + model.Level = Level; + model.CascadeId = cascade+"."+model.ParentId+"."+model.Id; + } + + uow.SysOrg.Insert(model); + var falg = uow.Commit(); + return new Response + { + Result = falg, + Message = (falg == true ? "添加成功" : "添加失败") + }; + } + } + #endregion + + #region 修改 + public Response Update(SysOrg sysOrg) + { + if (sysOrg.Id == sysOrg.ParentId) + { + throw new Exception("上级节点不能为自己"); + } + try + { + var user = _auth.GetCurrentUser().User; + sysOrg.ParentName=getParentName(sysOrg.ParentId); + sysOrg.CreateId = user.Id; + UpdateSysOrg(sysOrg); + + return new Response { Result = true, Message = "success" }; + } + catch (Exception ex) + { + return new Response { Result = false, Message = "error:" + ex.Message.ToString() }; + } + } + #endregion + + #region 删除 + /// + /// 删除指定ID的部门及其所有子部门 + /// + public Response DelOrgCascade(string[] ids) + { + var delOrgCascadeIds = base.Repository.GetList(u => ids.Contains(u.Id.ToString())).Select(u => u.CascadeId).ToArray(); + var delOrgIds = new List(); + foreach (var cascadeId in delOrgCascadeIds) + { + delOrgIds.AddRange(base.Repository.GetList(u => u.CascadeId.Contains(cascadeId)).Select(u => u.Id).ToArray()); + } + + using (var uow = base.UnitWork.CreateContext()) + { + //得改 代码先注释 + //uow.Relevance.Delete(u => u.Key == Define.USERORG && delOrgIds.Contains(u.SecondId)); + uow.SysOrg.Delete(u => delOrgIds.Contains(u.Id)); + var flag = uow.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + #endregion + + #region 分配职级组 + /// + /// 为部门分配职级组 + /// + /// + /// + public async Task> OrgPosGroup(AssignOrgPosGroup assignOrgPos) + { + var flag = await base.Repository.UpdateAsync(a => new SysOrg { PosGroupId = assignOrgPos.PosGroupId }, a => a.Id == assignOrgPos.OrgId); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + #endregion + + #endregion + public string getParentName(long parentId) { + string name = base.Repository.AsSugarClient().Queryable().First(a => a.Id == parentId).Name; + return name; + } + + + + + public void UpdateSysOrg(SysOrg obj) + { + if (obj.ParentId == 0) + { + obj.Level = 0; + obj.CascadeId = "0." + obj.Id; + } + else + { + long parentId = obj.ParentId; + int Level = 0; + string cascade = ""; + while (true) + { + string sql = "select \"ParentId\" from sys_org where \"Id\"=" + parentId; + long id = base.Repository.AsSugarClient().Ado.GetLong(sql); + //long id = base.Repository.AsSugarClient().Queryable().Where(a => a.Id == parentId).Select(a => a.ParentId).ToLong(); + if (!string.IsNullOrEmpty(cascade)) + { + cascade = id + "." + cascade; + } + else + { + cascade = id + cascade; + } + + parentId = id; + Level++; + if (id == 0) + { + break; + } + } + obj.Level = Level; + obj.CascadeId = cascade + "." + obj.ParentId + "." + obj.Id; + } + base.Repository.AsSugarClient().Updateable(obj).ExecuteCommand(); + } + + + + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/OrgManager/Request/AssignOrgPosGroup.cs b/OpenAuth.App/BaseApp/OrgManager/Request/AssignOrgPosGroup.cs new file mode 100644 index 0000000..b8b8e15 --- /dev/null +++ b/OpenAuth.App/BaseApp/OrgManager/Request/AssignOrgPosGroup.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class AssignOrgPosGroup + { + public long OrgId { get; set; } + + public long PosGroupId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/OrgManager/Request/OrgForm.cs b/OpenAuth.App/BaseApp/OrgManager/Request/OrgForm.cs new file mode 100644 index 0000000..76928d6 --- /dev/null +++ b/OpenAuth.App/BaseApp/OrgManager/Request/OrgForm.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace OpenAuth.App.Request +{ + public class OrgForm + { + public long Id { get; set; } + public string CascadeId { get; set; } + public string Name { get; set; } + public int Status { get; set; } + public int SortNo { get; set; } + public long ParentId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/OrgManager/Request/OrgPos.cs b/OpenAuth.App/BaseApp/OrgManager/Request/OrgPos.cs new file mode 100644 index 0000000..1b93994 --- /dev/null +++ b/OpenAuth.App/BaseApp/OrgManager/Request/OrgPos.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class OrgPos + { + public long OrgId { get; set; } + + public long PosId { get; set; } + + public int Level { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/OrgManager/Request/QueryOrgListReq.cs b/OpenAuth.App/BaseApp/OrgManager/Request/QueryOrgListReq.cs new file mode 100644 index 0000000..29895fd --- /dev/null +++ b/OpenAuth.App/BaseApp/OrgManager/Request/QueryOrgListReq.cs @@ -0,0 +1,14 @@ +using OpenAuth.App.Request; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class QueryOrgListReq : PageReq + { + public long OrgId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/Permission/BaseDataAuthorizeApp.cs b/OpenAuth.App/BaseApp/Permission/BaseDataAuthorizeApp.cs new file mode 100644 index 0000000..8420223 --- /dev/null +++ b/OpenAuth.App/BaseApp/Permission/BaseDataAuthorizeApp.cs @@ -0,0 +1,507 @@ +using System.Text; +using Infrastructure; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Permission.Request; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App.Permission; + +/// +/// 数据权限业务类 +/// +public class BaseDataAuthorizeApp : SqlSugarBaseApp +{ + /// + /// 构造函数 + /// + /// + /// + /// + public BaseDataAuthorizeApp(ISugarUnitOfWork unitWork, ISimpleClient repository, + IAuth auth) : base(unitWork, repository, auth) + { + } + + + #region 获取数据 + + /// + /// 获取数据权限对应关系数据列表 + /// + /// 编码 + /// 用户或角色主键 + /// + public Task> GetList(string code, string[] objectIds) + { + return Repository.AsQueryable() + .Where(t => t.Code.Equals(code) + && (objectIds.Contains(t.ObjectId) || t.ObjectType == 3) + ).ToListAsync(); + } + + /// + /// 获取数据权限列表(分页) + /// + public async Task>>> GetPageList(BaseDataAuthListReq req) + { + RefAsync totalCount = 0; + // 实现查询及分页 + var result = await Repository.AsQueryable() + .WhereIF(req.Type != null, t => t.Type == req.Type) + .WhereIF(!string.IsNullOrEmpty(req.ObjectId), t => t.ObjectId == req.ObjectId) + .WhereIF(!string.IsNullOrEmpty(req.key), t => t.Name.Contains(req.key) || t.Code.Contains(req.key)) + .ToPageListAsync(req.page, req.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = result, + Total = totalCount + } + }; + } + + /// + /// 获取实体 + /// + /// 主键 + /// + public Task GetEntity(string keyValue) + { + return Repository.GetByIdAsync(keyValue); + } + + #endregion + + #region 提交数据 + + /// + /// 删除实体数据 + /// + /// 主键 + /// + public async Task DeleteEntity(string keyValue) + { + await Repository.DeleteByIdAsync(keyValue); + } + + /// + /// 保存实体数据(新增、修改) + /// + /// 主键 + /// 实体 + /// + public async Task SaveEntity(string keyValue, BaseDataAuthReq record) + { + var user = _auth.GetCurrentUser(); + var entity = record.MapTo(); + entity.Formula = record.Formula.ToJson(); + if (string.IsNullOrEmpty(keyValue)) + { + entity.Id = Guid.NewGuid().ToString(); + entity.CreateDate = DateTime.Now; + entity.CreateUserId = user.User.Id.ToString(); + entity.CreateUserName = user.User.Name; + } + else + { + entity.Id = keyValue; + entity.ModifyDate = DateTime.Now; + entity.ModifyUserId = user.User.Id.ToString(); + entity.ModifyUserName = user.User.Name; + } + // 全部值都更新了 + await Repository.InsertOrUpdateAsync(entity); + } + + #endregion + + #region 扩展方法 + + /// + /// 获取自定义表单数据权限查询条件 + /// + /// 自定义表单功能主键 + /// + /// todo 可以优化,使代码逻辑清晰,减少代码量,比如有无公式,可以合并部分逻辑 + /// 逻辑:1. 超级用户不做过滤 2. 先看有无公式(默认条件使用and连接),再看有无分组公式(分组公式使用and连接) + public async Task GetWhereSql(string code) + { + // 取得当前用户信息 + var userInfo = _auth.GetCurrentUser(); + // 超级用户不做过滤 todo 暂时注释 + /*if (userInfo.User.Id.Equals(-1)) + { + return ""; + }*/ + + // 26个字母干嘛用的?别名? + var numIndex = new[] + { + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", + "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + }; + + // 获取数据权限配置信息 + // 查询当前用户所拥有的角色或者岗位 + var roleIds = userInfo.Roles.Select(t => t.Id).MapToList(); + var objectIds = new List { userInfo.User.Id + "", }; + objectIds.AddRange(roleIds); + // code 自定义表单功能主键 查询当前用户或者用户所属角色是否有设置的权限规则 + var baseDataAuths = await GetList(code, objectIds.ToArray()); + + // 保存拼接的sql + var whereSqlSb = new StringBuilder(); + var sqlNum = 0; + foreach (var auth in baseDataAuths) + { + //{"formula":"A and B", + //"conditions":[ + //{"f_FieldId":"F_text0","f_Symbol":1,"f_FieldValueType":1,"f_FieldValue":"xxx","group":"","type":"","table":"","cfield":"","field":"","relationField":""}], + //"formulas":[1 or 2]} + // 判断是否是开头 + // 先运行这里 + // 不同数据权限规则使用or ,很可能只有一条吧 + whereSqlSb.Append(sqlNum > 0 ? " AND ( " : " ( "); + var strSql = ""; + // 反序列化数据权限公式 + var itemFormula = auth.Formula.ToObject(); + // formula 不存在时,直接使用and连接 + if (string.IsNullOrEmpty(itemFormula.Formula)) + { + // Conditions + // 默认公式 + for (var i = 1; i < itemFormula.Conditions.Count + 1; i++) + { + var conditionItem = itemFormula.Conditions[i - 1]; + conditionItem.index = i; // 赋值索引,后面应该会用到,从1开始 + // 这里的Group是字符串,大概是字母 A B 之类 ,如何没有Group,条件之间用 and 连接 + if (!string.IsNullOrEmpty(conditionItem.Group)) + { + continue; + } + + if (strSql != "") + { + strSql += " AND "; + } + + strSql += " {@hopetry" + i + "hopetry@} "; + } + + // 公式为空,分组公式不为空 + if (itemFormula.Formulas != null && itemFormula.Formulas.Count > 0) + { + // 假设分组公式只有1个 【{“value”: "1 or 2"}】 多个分组公式之间,使用and连接 + for (var i = 0; i < itemFormula.Formulas.Count; i++) + { + if (itemFormula.Conditions.FindIndex(t => t.Group == numIndex[i]) != -1) + { + if (strSql != "") + { + strSql += " AND "; + } + + strSql += " {@hopetry" + numIndex[i] + "hopetry@} "; + } + } + } + } + // 存在公式 + else + { + // 当分组公式存在时,公式含有分组信息,如: A and B + strSql = itemFormula.Formula; + // 为什么从1开头 + for (var i = 1; i < itemFormula.Conditions.Count + 1; i++) + { + var conditionItem = itemFormula.Conditions[i - 1]; + // 取了条件没有使用 + conditionItem.index = i; + strSql = strSql.Replace("" + i, "{@hopetry" + i + "hopetry@}"); + } + + if (itemFormula.Formulas != null && itemFormula.Formulas.Count > 0) + { + for (var i = 0; i < itemFormula.Formulas.Count; i++) + { + strSql = strSql.Replace(numIndex[i], "{@hopetry" + numIndex[i] + "hopetry@}"); + } + } + } + + // 针对公组公式存在,再做部分处理,todo 暂时可以忽略,不实现分组 + if (itemFormula.Formulas != null && itemFormula.Formulas.Count > 0) + { + // 分组公式 + for (var i = 0; i < itemFormula.Formulas.Count; i++) + { + var groupSql = new StringBuilder(); + var groupList = itemFormula.Conditions.FindAll(t => t.Group == numIndex[i]); + if (groupList.Count > 0) + { + groupSql.Append( + // relationField 关联字段(外键) 这里的Table应该是子表吧 + $" {groupList[0].RelationField} in ( SELECT {groupList[0].Field} FROM {groupList[0].Table} WHERE "); + + // 初始化分组公式 + var groupSqlWhere = ""; + if (string.IsNullOrEmpty(itemFormula.Formulas[i].Value)) + { + foreach (var groupItem in groupList) + { + if (groupSqlWhere != "") + { + groupSqlWhere += " AND "; + } + + groupSqlWhere += " {@hopetry" + groupItem.index + "hopetry@} "; + } + } + else + { + groupSqlWhere = itemFormula.Formulas[i].Value; + foreach (var groupItem in groupList) + { + groupSqlWhere = groupSqlWhere.Replace("" + groupItem.index, + "{@hopetry" + groupItem.index + "hopetry@}"); + } + } + + foreach (var groupItem in groupList) + { + var strone = new StringBuilder(); + if (groupItem.F_Symbol.Equals("8")) + { + strone.Append($" ({groupItem.Cfield} "); + } + else + { + strone.Append($" {groupItem.Cfield} "); + } + + var value = await GetValue(int.Parse(groupItem.F_FieldValueType), groupItem.F_FieldValue); + switch (int.Parse(groupItem.F_Symbol)) + { + case 1: // 等于 + strone.Append($" = {value}"); + break; + case 2: // 大于 + strone.Append($" > {value}"); + break; + case 3: // 大于等于 + strone.Append($" >= {value}"); + break; + case 4: // 小于 + strone.Append($" < {value}"); + break; + case 5: // 小于等于 + strone.Append($" <= {value}"); + break; + case 6: // 包含 + value = value.Replace("'", ""); + strone.Append($" like '%{value}%'"); + break; + case 7: // 包含于 + value = value.Replace(",", "','"); + strone.Append($" in ({value})"); + break; + case 8: // 不等于 + strone.Append($" != {value} or {groupItem.Cfield} is null ) "); + break; + case 9: // 不包含 + value = value.Replace("'", ""); + strone.Append($" not like '%{value}%'"); + break; + case 10: // 不包含于 + value = value.Replace(",", "','"); + strone.Append($" not in ({value})"); + break; + default: + break; + } + + groupSqlWhere = groupSqlWhere.Replace("{@hopetry" + groupItem.index + "hopetry@}", + strone.ToString()); + } + + groupSql.Append(groupSqlWhere); + groupSql.Append(" ) "); + strSql = strSql.Replace("{@hopetry" + numIndex[i] + "hopetry@}", groupSql.ToString()); + } + } + } + + // 填充占位符,生成实际wheresql + var num = 1; + foreach (var conditionItem in itemFormula.Conditions) + { + // 这里的group应该是 A B C 之类的字母 + if (string.IsNullOrEmpty(conditionItem.Group)) + { + var strone = new StringBuilder(); + if (conditionItem.Type == "glbd") // 未使用 + { + strone.Append( + $" {conditionItem.RelationField} in ( SELECT {conditionItem.Field} FROM {conditionItem.Table} WHERE {conditionItem.Cfield} "); + } + else + { + // 8 不等于 + if (conditionItem.F_Symbol.Equals("8")) + { + strone.Append($" ( {conditionItem.F_FieldId}"); + } + else + { + strone.Append($" {conditionItem.F_FieldId}"); + } + } + + var value = await GetValue(int.Parse(conditionItem.F_FieldValueType), conditionItem.F_FieldValue); + // 如果 value 值是 userId + switch (int.Parse(conditionItem.F_Symbol)) + { + case 1: // 等于 + strone.Append($" = {value}"); + break; + case 2: // 大于 + strone.Append($" > {value}"); + break; + case 3: // 大于等于 + strone.Append($" >= {value}"); + break; + case 4: // 小于 + strone.Append($" < {value}"); + break; + case 5: // 小于等于 + strone.Append($" <= {value}"); + break; + case 6: // 包含 + value = value.Replace("'", ""); + strone.Append($" like '%{value}%'"); + break; + case 7: // 包含于 + value = value.Replace(",", "','"); + value = value.Replace("#", ","); + strone.Append($" in ({value})"); + break; + case 8: // 不等于 + strone.Append($" != {value}"); + + if (conditionItem.Type == "glbd") + { + strone.Append($" or {conditionItem.Cfield} is null "); + } + else + { + strone.Append($" or {conditionItem.F_FieldId} is null ) "); + } + + break; + case 9: // 不包含 + value = value.Replace("'", ""); + strone.Append($" not like '%{value}%'"); + break; + case 10: // 不包含于 + value = value.Replace(",", "','"); + strone.Append($" not in ({value})"); + break; + default: + break; + } + + strone.Append(conditionItem.Type == "glbd" ? " ) " : " "); + strSql = strSql.Replace("{@hopetry" + num + "hopetry@}", strone.ToString()); + } + + num++; + } + + whereSqlSb.Append(strSql); + whereSqlSb.Append(" ) "); + + sqlNum++; + } + + Console.WriteLine("strRes:" + whereSqlSb.ToString()); + return whereSqlSb.ToString(); + } + + /// + /// 获取数据 where 值部分 + /// + /// 数据类型 + /// 数据值 + /// + /// + + // todo 扩展改造 + private async Task GetValue(int? type, string value) + { + var userInfo = _auth.GetCurrentUser(); + //1.文本(string) 2.登录者ID 3.登录者账号 4.登录者部门 5. 登录者部门及下属部门 6.登录者岗位 7.登录者角色 10. 文本(int) + string text; + switch (type) + { + case 1: // 文本(string) + text = $"'{value}'"; + break; + case 10: // 文本(int) + text = value; + break; + case 2: // 登录者ID(本地创建数据) + text = userInfo.User.Id + ""; + break; + case 3: // 登录者账号 + text = $"'{userInfo.User.Account}'"; + break; + // todo 扩展实现 + case 4: // 本部门 + text = + $"( SELECT CAST ( \"OrgId\" AS VARCHAR ) AS \"OrgId\" FROM sys_userorg WHERE \"UserId\" = '{userInfo.User.Id}' )"; + break; + case 5: // 本部门及子部门 + text = + $"select CAST(\"Id\" AS VARCHAR) from sys_org where string_to_array(\"CascadeId\"#'.') && ARRAY['{string.Join(",", userInfo.Orgs.Select(t => t.Id).MapToList())}']"; + break; + case 6: + text = ""; + break; + case 7: + text = $"'{string.Join(",", userInfo.Roles.Select(t => t.Id).MapToList())}'"; + break; + default: + text = $"'{value}'"; + break; + } + + return text; + } + + #endregion + + public async Task> GetEntityByCode(string code) + { + var formModuleEntity = await Repository + .ChangeRepository>() + .GetFirstAsync(r => r.Id == code); + if (formModuleEntity != null) + { + var formScheme = await base.Repository.ChangeRepository>() + .GetFirstAsync(r => r.Id == formModuleEntity.FormVerison); + return new Response() + { + Result = formScheme, + Message = "查询成功" + }; + } + + throw new Exception("code无效"); + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Permission/Request/BaseDataAuthListReq.cs b/OpenAuth.App/BaseApp/Permission/Request/BaseDataAuthListReq.cs new file mode 100644 index 0000000..1d6ee96 --- /dev/null +++ b/OpenAuth.App/BaseApp/Permission/Request/BaseDataAuthListReq.cs @@ -0,0 +1,16 @@ +using OpenAuth.App.Request; + +namespace OpenAuth.App.Permission.Request; + +public class BaseDataAuthListReq : PageReq +{ + /// + /// 用户或角色主键 + /// + public string ObjectId { get; set; } + + /// + /// 1.普通权限 2.自定义表单权限 + /// + public int? Type { get; set; } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Permission/Request/BaseDataAuthReq.cs b/OpenAuth.App/BaseApp/Permission/Request/BaseDataAuthReq.cs new file mode 100644 index 0000000..f07a018 --- /dev/null +++ b/OpenAuth.App/BaseApp/Permission/Request/BaseDataAuthReq.cs @@ -0,0 +1,53 @@ +namespace OpenAuth.App.Permission.Request; + +/// +/// 数据权限对应表的实体类。 +/// +public class BaseDataAuthReq +{ + /// + /// 主键ID。 + /// + public string Id { get; set; } + + /// + /// 权限名称。 + /// + public string Name { get; set; } + + /// + /// 权限类型。1表示普通权限,2表示自定义表单权限。 + /// + public int Type { get; set; } + + /// + /// 权限编码。 + /// + public string Code { get; set; } + + /// + /// 对象主键。 + /// + public string ObjectId { get; set; } + + /// + /// 对象类型。1表示角色,2表示用户。 + /// + public int ObjectType { get; set; } + + /// + /// 用户名/角色名 + /// + public string ObjectName { get; set; } + + /// + /// 自定义表单名称 + /// + public string CodeName { get; set; } + + // 使用实体实现 + /// + /// 条件公式。 + /// + public FormulaObject Formula { get; set; } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Permission/Request/Condition.cs b/OpenAuth.App/BaseApp/Permission/Request/Condition.cs new file mode 100644 index 0000000..080cd78 --- /dev/null +++ b/OpenAuth.App/BaseApp/Permission/Request/Condition.cs @@ -0,0 +1,77 @@ +using Newtonsoft.Json; + +namespace OpenAuth.App.Permission.Request; + +/// +/// 设置条件 +/// +public class Condition +{ + /// + /// 编号 + /// + public int index { get; set; } + + /// + /// 字段ID + /// + /// + [JsonProperty("f_FieldId")] + public string F_FieldId { get; set; } + + /// + /// 比较符 1.等于 2.包含 3.包含于 4.不等于 5.不包含 6.不包含于 + /// + /// + [JsonProperty("f_Symbol")] + public string F_Symbol { get; set; } + + /// + /// 字段值类型1.文本 2.登录者ID 3.登录者账号 4.登录者部门 5. 登录都部门及下属部门 6.登录者岗位 7.登录者角色 + /// + [JsonProperty("f_FieldValueType")] + public string F_FieldValueType { get; set; } + + /// + /// 字段值 + /// + /// + [JsonProperty("f_FieldValue")] + public string F_FieldValue { get; set; } + + /// + /// 类型 glbd关联表单数据类型,需要特殊处理 + /// + [JsonProperty("type")] + public string Type { get; set; } + + /// + /// 表名称 + /// + [JsonProperty("table")] + public string Table { get; set; } + + /// + /// 比较字段 + /// + [JsonProperty("cfield")] + public string Cfield { get; set; } + + /// + /// 外键 + /// + [JsonProperty("field")] + public string Field { get; set; } + + /// + /// 关联表字段 + /// + [JsonProperty("relationField")] + public string RelationField { get; set; } + + /// + /// 分组编号 这里的Group是属性名称和下面的Group类不是一回事 + /// + [JsonProperty("group")] + public string Group { get; set; } +} diff --git a/OpenAuth.App/BaseApp/Permission/Request/FormulaObject.cs b/OpenAuth.App/BaseApp/Permission/Request/FormulaObject.cs new file mode 100644 index 0000000..0ae1d52 --- /dev/null +++ b/OpenAuth.App/BaseApp/Permission/Request/FormulaObject.cs @@ -0,0 +1,28 @@ +using Newtonsoft.Json; + +namespace OpenAuth.App.Permission.Request; + +/// +/// 公式 +/// +public class FormulaObject +{ + /// + /// 设置公式 1 and 2 + /// + [JsonProperty("formula")] + public string Formula { get; set; } + + /// + /// 设置条件 + /// + [JsonProperty("conditions")] + public List Conditions { get; set; } + + + /// + /// 分组公式 (A or B) + /// + [JsonProperty("formulas")] + public List Formulas { get; set; } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Permission/Request/Group.cs b/OpenAuth.App/BaseApp/Permission/Request/Group.cs new file mode 100644 index 0000000..bac8cf8 --- /dev/null +++ b/OpenAuth.App/BaseApp/Permission/Request/Group.cs @@ -0,0 +1,9 @@ +namespace OpenAuth.App.Permission.Request; + +/// +/// 分组公式 +/// +public class Group +{ + public string Value { get; set; } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Relevance/Request/AssignDataReq.cs b/OpenAuth.App/BaseApp/Relevance/Request/AssignDataReq.cs new file mode 100644 index 0000000..f19c83f --- /dev/null +++ b/OpenAuth.App/BaseApp/Relevance/Request/AssignDataReq.cs @@ -0,0 +1,21 @@ +namespace OpenAuth.App.Request +{ + /// + /// 为角色分配数据字段权限 + /// + public class AssignDataReq + { + /// + /// 角色ID + /// + public string RoleId { get; set; } + /// + /// 模块的Code,比如Category/Resource + /// + public string ModuleCode { get; set; } + /// + /// 字段名称列表 + /// + public string[] Properties { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Relevance/Request/AssignOrgUsers.cs b/OpenAuth.App/BaseApp/Relevance/Request/AssignOrgUsers.cs new file mode 100644 index 0000000..cf0c5bc --- /dev/null +++ b/OpenAuth.App/BaseApp/Relevance/Request/AssignOrgUsers.cs @@ -0,0 +1,17 @@ +namespace OpenAuth.App.Request +{ + /// + /// 部门分配用户 + /// + public class AssignOrgUsers + { + /// + /// 部门id + /// + public string OrgId { get; set; } + /// + /// 用户id列表 + /// + public string[] UserIds { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Relevance/Request/AssignReq.cs b/OpenAuth.App/BaseApp/Relevance/Request/AssignReq.cs new file mode 100644 index 0000000..fff707d --- /dev/null +++ b/OpenAuth.App/BaseApp/Relevance/Request/AssignReq.cs @@ -0,0 +1,18 @@ +namespace OpenAuth.App.Request +{ + /// + /// 比如给用户分配资源,那么firstId就是用户ID,secIds就是资源ID列表 + /// + public class AssignReq + { + /// + /// 分配的关键字,比如:UserRole + /// + public string type { get; set; } + /// + /// 比如给用户分配角色,那么firstId就是用户ID,secIds就是角色ID列表 + /// + public string firstId { get; set; } + public string[] secIds { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Relevance/Request/AssignRoleUsers.cs b/OpenAuth.App/BaseApp/Relevance/Request/AssignRoleUsers.cs new file mode 100644 index 0000000..e1fa8f7 --- /dev/null +++ b/OpenAuth.App/BaseApp/Relevance/Request/AssignRoleUsers.cs @@ -0,0 +1,17 @@ +namespace OpenAuth.App.Request +{ + /// + /// 角色分配用户 + /// + public class AssignRoleUsers + { + /// + /// 角色id + /// + public string RoleId { get; set; } + /// + /// 用户id列表 + /// + public string[] UserIds { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Relevance/RevelanceManagerApp.cs b/OpenAuth.App/BaseApp/Relevance/RevelanceManagerApp.cs new file mode 100644 index 0000000..35c3b54 --- /dev/null +++ b/OpenAuth.App/BaseApp/Relevance/RevelanceManagerApp.cs @@ -0,0 +1,240 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Infrastructure; +using Microsoft.Extensions.Logging; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + public class RevelanceManagerApp : SqlSugarBaseApp + { + private readonly ILogger _logger; + + public RevelanceManagerApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + + } + + /// + /// 添加关联 + /// 比如给用户分配资源,那么firstId就是用户ID,secIds就是资源ID列表 + /// + /// 关联的类型,如Define.USERRESOURCE + public void Assign(AssignReq request) + { + Assign(request.type, request.secIds.ToLookup(u => request.firstId)); + } + + /// + /// 添加关联,需要人工删除以前的关联 + /// + /// + /// + public void Assign(string key, ILookup idMaps) + { + Repository.InsertRange((from sameVals in idMaps + from value in sameVals + select new SysRelevance + { + Key = key, + FirstId = sameVals.Key, + SecondId = value, + OperateTime = DateTime.Now + }).ToArray()); + } + + /// + /// 取消关联 + /// + /// 关联的类型,如Define.USERRESOURCE + /// The first identifier. + /// The sec ids. + public void UnAssign(AssignReq req) + { + if (req.secIds == null || req.secIds.Length == 0) + { + DeleteBy(req.type, req.firstId); + } + else + { + DeleteBy(req.type, req.secIds.ToLookup(u => req.firstId)); + } + } + + /// + /// 删除关联 + /// + /// 关联标识 + /// 关联的<firstId, secondId>数组 + private void DeleteBy(string key, ILookup idMaps) + { + foreach (var sameVals in idMaps) + { + foreach (var value in sameVals) + { + _logger.LogInformation($"start=> delete {key} {sameVals.Key} {value}"); + try + { + Repository.Delete(u => u.Key == key && u.FirstId == sameVals.Key && u.SecondId == value); + } + catch (Exception e) + { + _logger.LogError(e, e.Message); + } + _logger.LogInformation($"end=> {key} {sameVals.Key} {value}"); + } + } + } + + public void DeleteBy(string key, params string[] firstIds) + { + Repository.Delete(u => firstIds.Contains(u.FirstId) && u.Key == key); + } + + + /// + /// 根据关联表的一个键获取另外键的值 + /// + /// 映射标识 + /// 返回的是否为映射表的第二列,如果不是则返回第一列 + /// 已知的ID列表 + /// List<System.String>. + public List Get(string key, bool returnSecondIds, params string[] ids) + { + if (returnSecondIds) + { + return Repository.GetList(u => u.Key == key + && ids.Contains(u.FirstId)).Select(u => u.SecondId).ToList(); + } + else + { + return Repository.GetList(u => u.Key == key + && ids.Contains(u.SecondId)).Select(u => u.FirstId).ToList(); + } + } + + /// + /// 根据key ,firstId,secondId获取thirdId + /// + /// + /// + /// + /// + public List Get(string key, string firstId, string secondId) + { + return Repository.GetList(u => u.Key == key && u.FirstId == firstId && u.SecondId == secondId) + .Select(u => u.ThirdId).ToList(); + } + + /// + /// 分配数据字段权限 + /// + /// + public void AssignData(AssignDataReq request) + { + if (!request.Properties.Any()) + { + return; + } + + var relevances = new List(); + foreach (var requestProperty in request.Properties) + { + relevances.Add(new SysRelevance + { + Key = Define.ROLEDATAPROPERTY, + FirstId = request.RoleId, + SecondId = request.ModuleCode, + ThirdId = requestProperty, + OperateTime = DateTime.Now + }); + } + + Repository.InsertRange(relevances.ToArray()); + + } + + /// + /// 取消数据字段分配 + /// + /// + public void UnAssignData(AssignDataReq request) + { + if (request.Properties == null || request.Properties.Length == 0) + { + if (string.IsNullOrEmpty(request.ModuleCode)) //模块为空,直接把角色的所有授权删除 + { + DeleteBy(Define.ROLEDATAPROPERTY, request.RoleId); + } + else //把角色的某一个模块权限全部删除 + { + DeleteBy(Define.ROLEDATAPROPERTY, new[] { request.ModuleCode }.ToLookup(u => request.RoleId)); + } + } + else //按具体的id删除 + { + foreach (var property in request.Properties) + { + Repository.Delete(u => u.Key == Define.ROLEDATAPROPERTY + && u.FirstId == request.RoleId + && u.SecondId == request.ModuleCode + && u.ThirdId == property); + } + } + } + + /// + /// 为角色分配用户,需要统一提交,会删除以前该角色的所有用户 + /// + /// + public void AssignRoleUsers(AssignRoleUsers request) + { + using (var uow = UnitWork.CreateContext()) + { + //删除以前的所有用户 + uow.Relevance.Delete(u => u.SecondId == request.RoleId && u.Key == Define.USERROLE); + //批量分配用户角色 + uow.Relevance.InsertRange((from firstId in request.UserIds + select new SysRelevance + { + Key = Define.USERROLE, + FirstId = firstId, + SecondId = request.RoleId, + OperateTime = DateTime.Now + }).ToArray()); + uow.Commit(); + + } + } + + /// + /// 为部门分配用户,需要统一提交,会删除以前该部门的所有用户 + /// + /// + public void AssignOrgUsers(AssignOrgUsers request) + { + using (var uow = UnitWork.CreateContext()) + { + //删除以前的所有用户 + uow.Relevance.Delete(u => u.SecondId == request.OrgId && u.Key == Define.USERORG); + //批量分配用户角色 + uow.Relevance.InsertRange((from firstId in request.UserIds + select new SysRelevance + { + Key = Define.USERORG, + FirstId = firstId, + SecondId = request.OrgId, + OperateTime = DateTime.Now + }).ToArray()); + uow.Commit(); + } + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Resources/Request/AddOrUpdateResReq.cs b/OpenAuth.App/BaseApp/Resources/Request/AddOrUpdateResReq.cs new file mode 100644 index 0000000..fbf59da --- /dev/null +++ b/OpenAuth.App/BaseApp/Resources/Request/AddOrUpdateResReq.cs @@ -0,0 +1,64 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a CodeSmith Template. +// +// DO NOT MODIFY contents of this file. Changes to this +// file will be lost if the code is regenerated. +// Author:Yubao Li +// +//------------------------------------------------------------------------------ + + namespace OpenAuth.Repository.Domain +{ + /// + /// 资源表 + /// + public class AddOrUpdateResReq + { + public string Id { get; set; } + /// + /// 节点语义ID + /// + public string CascadeId { get; set; } + /// + /// 名称 + /// + public string Name { get; set; } + /// + /// 排序号 + /// + public int SortNo { get; set; } + /// + /// 描述 + /// + public string Description { get; set; } + /// + /// 父节点名称 + /// + public string ParentName { get; set; } + /// + /// 父节点流ID + /// + public string ParentId { get; set; } + /// + /// 资源所属应用ID + /// + public string AppId { get; set; } + /// + /// 所属应用名称 + /// + public string AppName { get; set; } + /// + /// 分类名称 + /// + public string TypeName { get; set; } + /// + /// 分类ID + /// + public string TypeId { get; set; } + /// + /// 是否可用 + /// + public bool Disable { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/Resources/Request/QueryResourcesReq.cs b/OpenAuth.App/BaseApp/Resources/Request/QueryResourcesReq.cs new file mode 100644 index 0000000..f6c3a9b --- /dev/null +++ b/OpenAuth.App/BaseApp/Resources/Request/QueryResourcesReq.cs @@ -0,0 +1,11 @@ +namespace OpenAuth.App.Request +{ + public class QueryResourcesReq : PageReq + { + /// + /// TypeID + /// + public string appId { get; set; } + + } +} diff --git a/OpenAuth.App/BaseApp/Resources/ResourceApp.cs b/OpenAuth.App/BaseApp/Resources/ResourceApp.cs new file mode 100644 index 0000000..8b6ccc3 --- /dev/null +++ b/OpenAuth.App/BaseApp/Resources/ResourceApp.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using Infrastructure; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Interface; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + /// + /// 分类管理 + /// + public class ResourceApp : SqlSugarBaseApp + { + private RevelanceManagerApp _revelanceApp; + + public ResourceApp( + ISugarUnitOfWork unitWork, + ISimpleClient repository, + RevelanceManagerApp app, + IAuth auth) : base(unitWork, repository, auth) + { + _revelanceApp = app; + } + public void Add(AddOrUpdateResReq resource) + { + var obj = resource.MapTo(); + //先注释,后边再看具体原因 + //CaculateCascade(obj); + obj.CreateTime = DateTime.Now; + var user = _auth.GetCurrentUser().User; + obj.CreateUserId = user.Id; + obj.CreateUserName = user.Name; + obj.Id = Guid.NewGuid().ToString(); + Repository.Insert(obj); + } + + public void Update(AddOrUpdateResReq obj) + { + var user = _auth.GetCurrentUser().User; + base.Repository.Update(u => new SysResource + { + Name = obj.Name, + Disable = obj.Disable, + CascadeId = obj.CascadeId, + AppId = obj.AppId, + AppName = obj.AppName, + ParentId = obj.ParentId, + ParentName = obj.ParentName, + TypeId = obj.TypeId, + TypeName = obj.TypeName, + Description = obj.Description, + UpdateTime = DateTime.Now, + UpdateUserId = user.Id, + UpdateUserName = user.Name + //todo:要修改的字段赋值 + }, u => u.Id == obj.Id); + } + + public IEnumerable LoadForRole(string appId, string roleId) + { + var elementIds = _revelanceApp.Get(Define.ROLERESOURCE, true, roleId); + return base.Repository.GetList(u => elementIds.Contains(u.Id) && (appId == null || appId == "" || u.AppId == appId)); + } + + public void Delete(string[] ids) + { + Repository.DeleteByIds(ids); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/RoleManager/Request/ModuleElementWithRole.cs b/OpenAuth.App/BaseApp/RoleManager/Request/ModuleElementWithRole.cs new file mode 100644 index 0000000..59b2feb --- /dev/null +++ b/OpenAuth.App/BaseApp/RoleManager/Request/ModuleElementWithRole.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class ModuleElementWithRole + { + public long RoleId { get; set; } + public List ModuleIds { get; set; } + public List ElementIds { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/RoleManager/Request/QueryRoleListReq.cs b/OpenAuth.App/BaseApp/RoleManager/Request/QueryRoleListReq.cs new file mode 100644 index 0000000..75e94fc --- /dev/null +++ b/OpenAuth.App/BaseApp/RoleManager/Request/QueryRoleListReq.cs @@ -0,0 +1,6 @@ +namespace OpenAuth.App.Request +{ + public class QueryRoleListReq : PageReq + { + } +} diff --git a/OpenAuth.App/BaseApp/RoleManager/Response/RoleView.cs b/OpenAuth.App/BaseApp/RoleManager/Response/RoleView.cs new file mode 100644 index 0000000..0d1ac7e --- /dev/null +++ b/OpenAuth.App/BaseApp/RoleManager/Response/RoleView.cs @@ -0,0 +1,60 @@ +// *********************************************************************** +// Assembly : OpenAuth.App +// Author : yubaolee +// Created : 11-29-2015 +// +// Last Modified By : yubaolee +// Last Modified On : 11-29-2015 +// *********************************************************************** +// +// Copyright (c) www.cnblogs.com/yubaolee. All rights reserved. +// +// 角色模型视图 +// *********************************************************************** + +using Infrastructure; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.App.Response +{ + public partial class RoleView + { + /// + /// 用户ID + /// + /// + public long Id { get; set; } + + /// + /// 名称 + /// + /// + public string Name { get; set; } + + /// + /// 当前状态 + /// + public int Status { get; set; } + /// + /// 角色类型 + /// + public int Type { get; set; } + + + /// + ///是否属于某用户 + /// + public bool Checked { get; set; } + + public static implicit operator RoleView(SysRole role) + { + return role.MapTo(); + } + + public static implicit operator SysRole(RoleView rolevm) + { + return rolevm.MapTo(); + } + + } +} diff --git a/OpenAuth.App/BaseApp/RoleManager/RoleApp.cs b/OpenAuth.App/BaseApp/RoleManager/RoleApp.cs new file mode 100644 index 0000000..62fd41c --- /dev/null +++ b/OpenAuth.App/BaseApp/RoleManager/RoleApp.cs @@ -0,0 +1,179 @@ +using OpenAuth.App.Interface; +using OpenAuth.App.Response; +using OpenAuth.Repository.Domain; +using Infrastructure; +using OpenAuth.App.Request; +using OpenAuth.Repository; +using SqlSugar; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.BasicQueryService; + +namespace OpenAuth.App +{ + public class RoleApp : SqlSugarBaseApp + { + UserManager userManager; + public RoleApp( + ISugarUnitOfWork unitWork, + ISimpleClient repository, + IAuth auth, + UserManager userManager + ) : base(unitWork, repository, auth) + { + this.userManager = userManager; + } + + #region 查询 + /// + /// 查询所有角色分页 + /// + public async Task>>> LoadAllPage(QueryRoleListReq request) + { + RefAsync totalCount = 0; + var result = new PageInfo(); + var roles = await base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(request.key), r => r.Name.Contains(request.key)) + .OrderByDescending(r => r.CreateTime) + .ToPageListAsync(request.page, request.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = roles, + Total = totalCount + } + }; + } + + /// + /// 登录用户可访问的角色分页 + /// + /// + /// + public async Task>>> LoadPage(QueryRoleListReq request) + { + long userId = long.Parse(_auth.GetUserId()); + + RefAsync totalCount = 0; + var result = new PageInfo(); + var roles = await userManager.UserRoles(userId) + .WhereIF(!string.IsNullOrEmpty(request.key), (u, r) => r.Name.Contains(request.key)) + .OrderByDescending((u, r) => r.CreateTime) + .Select((u, r) => r) + .ToPageListAsync(request.page, request.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = roles, + Total = totalCount + } + }; + } + + public async Task> UserRoles(long userId) + { + return await base.Repository.AsSugarClient().Queryable() + .Where(ur => ur.UserId == userId) + .Select(ur => ur.RoleId).ToListAsync(); + } + #endregion + + + + public SysRole Get(long id) + { + return Repository.GetById(id); + } + + + + /// + /// 添加角色 + /// + public async Task> Add(RoleView obj) + { + SysRole role = obj; + role.CreateTime = DateTime.Now; + role.Id = Yitter.IdGenerator.YitIdHelper.NextId(); + var flag = await Repository.InsertAsync(role); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + + + /// + /// 删除角色时,需要删除角色对应的权限 + /// + /// + public async Task> Delete(long[] ids) + { + using (var uwo = UnitWork.CreateContext()) + { + await uwo.SysRoleModule.DeleteAsync(a => ids.Contains(a.RoleId)); + await uwo.SysRoleElement.DeleteAsync(a => ids.Contains(a.RoleId)); + await uwo.Role.DeleteAsync(u => ids.Contains(u.Id)); + var flag = uwo.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + + /// + /// 更新角色属性 + /// + /// + public async Task> Update(RoleView obj) + { + SysRole role = obj; + + bool flag = await base.Repository.UpdateAsync(u => new SysRole + { + Name = role.Name, + Status = role.Status + }, u => u.Id == obj.Id); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 为角色分配菜单和按钮 + /// + /// + /// + public async Task> AssignModule(ModuleElementWithRole model) + { + using (var uwo = UnitWork.CreateContext()) + { + await uwo.SysRoleModule.DeleteAsync(a => a.RoleId == model.RoleId); + await uwo.SysRoleElement.DeleteAsync(a => a.RoleId == model.RoleId); + await uwo.SysRoleModule.InsertRangeAsync(model.ModuleIds.Select(a => new SysRoleModule { RoleId = model.RoleId, ModuleId = a }).ToList()); + await uwo.SysRoleElement.InsertRangeAsync(model.ElementIds.Select(a => new SysRoleElement { RoleId = model.RoleId, ElementId = a }).ToList()); + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SSO/LocalAuth.cs b/OpenAuth.App/BaseApp/SSO/LocalAuth.cs new file mode 100644 index 0000000..1c61c08 --- /dev/null +++ b/OpenAuth.App/BaseApp/SSO/LocalAuth.cs @@ -0,0 +1,242 @@ +using Infrastructure.Cache; +using Microsoft.AspNetCore.Http; +using OpenAuth.App.Interface; +using System; +using Infrastructure; +using Microsoft.Extensions.Options; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.App.SSO +{ + /// + /// 使用本地登录。这个注入IAuth时,只需要OpenAuth.Mvc一个项目即可,无需webapi的支持 + /// + public class LocalAuth : IAuth + { + private IHttpContextAccessor _httpContextAccessor; + private IOptions _appConfiguration; + private SysLogApp _logApp; + + private AuthContextFactory _app; + private LoginParse _loginParse; + private ICacheContext _cacheContext; + + public LocalAuth(IHttpContextAccessor httpContextAccessor + , AuthContextFactory app + , LoginParse loginParse + , ICacheContext cacheContext, IOptions appConfiguration, SysLogApp logApp) + { + _httpContextAccessor = httpContextAccessor; + _app = app; + _loginParse = loginParse; + _cacheContext = cacheContext; + _appConfiguration = appConfiguration; + _logApp = logApp; + } + + /// + /// 如果是Identity,则返回信息为用户账号 + /// + /// + private string GetToken() + { + if (_appConfiguration.Value.IsIdentityAuth) + { + return _httpContextAccessor.HttpContext.User.Identity.Name; + } + string token = _httpContextAccessor.HttpContext.Request.Query[Define.TOKEN_NAME]; + if (!String.IsNullOrEmpty(token)) return token; + + token = _httpContextAccessor.HttpContext.Request.Headers[Define.TOKEN_NAME]; + if (!String.IsNullOrEmpty(token)) return token; + + var cookie = _httpContextAccessor.HttpContext.Request.Cookies[Define.TOKEN_NAME]; + return cookie ?? String.Empty; + } + + public void CoverToken(string account, string name) + { + var user = _cacheContext.Get(GetToken()); + user.Name = name; + user.Account = account; + _cacheContext.Set(user.Token, user, DateTime.Now.AddDays(10)); + } + + public bool CheckLogin(string token = "", string otherInfo = "") + { + if (_appConfiguration.Value.IsIdentityAuth) + { + return (!string.IsNullOrEmpty(_httpContextAccessor.HttpContext.User.Identity.Name)); + } + + if (string.IsNullOrEmpty(token)) + { + token = GetToken(); + } + + if (string.IsNullOrEmpty(token)) + { + return false; + } + + try + { + var result = _cacheContext.Get(token) != null; + return result; + } + catch (Exception ex) + { + throw ex; + } + } + + /// + /// 获取当前登录的用户信息 + /// 通过URL中的Token参数或Cookie中的Token + /// + /// The account. + /// LoginUserVM. + public AuthStrategyContext GetCurrentUser() + { + if (_appConfiguration.Value.IsIdentityAuth) + { + return _app.GetAuthStrategyContext(GetToken()); + } + AuthStrategyContext context = null; + var user = _cacheContext.Get(GetToken()); + if (user != null) + { + context = _app.GetAuthStrategyContext(user.Account); + } + return context; + } + + /// + /// 获取当前登录的用户名 + /// 通过URL中的Token参数或Cookie中的Token + /// + /// The account. + /// System.String. + public string GetUserName(string otherInfo = "") + { + if (_appConfiguration.Value.IsIdentityAuth) + { + return _httpContextAccessor.HttpContext.User.Identity.Name; + } + + var user = _cacheContext.Get(GetToken()); + if (user != null) + { + return user.Account; + } + + return ""; + } + + public string GetUserNickName(string otherInfo = "") + { + if (_appConfiguration.Value.IsIdentityAuth) + { + return _httpContextAccessor.HttpContext.User.Identity.Name; + } + + var user = _cacheContext.Get(GetToken()); + if (user != null) + { + return user.Name; + } + + return ""; + } + + /// + /// 获取 UserId + /// + /// + /// + public string GetUserId(string otherInfo = "") + { + if (_appConfiguration.Value.IsIdentityAuth) + { + return _httpContextAccessor.HttpContext.User.Identity.Name; + } + + var user = _cacheContext.Get(GetToken()); + if (user != null) + { + return user.UserId; + } + + return ""; + } + + /// + /// 登录接口 + /// + /// 应用程序key. + /// 用户名 + /// 密码 + /// System.String. + public Response Login(string appKey, string username, string pwd) + { + //throw new Exception("hahah"); + if (_appConfiguration.Value.IsIdentityAuth) + { + return new Response + { + Code = 500, + Message = "接口启动了OAuth认证,暂时不能使用该方式登录" + }; + } + + var result = _loginParse.Do(new PassportLoginRequest + { + AppKey = appKey, + Account = username, + Password = pwd + }); + + var log = new SysLog + { + Content = $"用户登录,结果:{result.Message}", + Result = result.Code == 200 ? 0 : 1, + CreateId = -1, + CreateName = username, + TypeName = "登录日志" + }; + _logApp.Add(log); + + return result; + } + + /// + /// 注销,如果是Identity登录,需要在controller处理注销逻辑 + /// + public bool Logout() + { + var token = GetToken(); + if (String.IsNullOrEmpty(token)) return true; + + try + { + _cacheContext.Remove(token); + return true; + } + catch + { + return false; + } + + + } + + /// + /// 是否是超级管理员 + /// + /// + public bool IsSystem() + { + return Define.SYSTEM_USERNAME == GetUserName(); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SSO/LoginParse.cs b/OpenAuth.App/BaseApp/SSO/LoginParse.cs new file mode 100644 index 0000000..5f632e7 --- /dev/null +++ b/OpenAuth.App/BaseApp/SSO/LoginParse.cs @@ -0,0 +1,104 @@ +using System; +using Infrastructure; +using Infrastructure.Cache; +using Infrastructure.Helpers; +using Infrastructure.Utilities; +using Microsoft.Extensions.Configuration; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App.SSO +{ + public class LoginParse + { + //这个地方使用IRepository 而不使用UserManagerApp是防止循环依赖 + public ISimpleClient _app; + private ICacheContext _cacheContext; + private IConfiguration configuration; + + + public LoginParse(ICacheContext cacheContext, ISimpleClient userApp, IConfiguration configuration) + { + _cacheContext = cacheContext; + _app = userApp; + this.configuration = configuration; + } + + public Response Do(PassportLoginRequest model) + { + var result = new Response(); + try + { + model.Trim(); + //todo:如果需要判定应用,可以取消该注释 + // var appInfo = _appInfoService.GetByAppKey(model.AppKey); + // if (appInfo == null) + // { + // throw new Exception("应用不存在"); + // } + //获取用户信息 + SysUser userInfo = null; + if (model.Account == Define.SYSTEM_USERNAME) + { + userInfo = new SysUser + { + Id = -1, + Account = Define.SYSTEM_USERNAME, + Name = "超级管理员", + Password = Md5Helper.Encrypt(DESEncrypt.Encrypt(Md5Helper.Hash(configuration.GetSection("AppSetting:SYSTEM_USERPWD").Value), Define.SYSTEM_SECRETKEY).ToLower(), 32).ToLower(), + //Password = Define.SYSTEM_USERPWD, + Secretkey = Define.SYSTEM_SECRETKEY + }; + } + else + { + userInfo = _app.GetFirst(u => u.Account == model.Account); + } + + if (userInfo == null) + { + throw new Exception("用户不存在"); + } + + string dbPwd = Md5Helper.Encrypt(DESEncrypt.Encrypt(model.Password, userInfo.Secretkey).ToLower(), 32).ToLower(); + if (userInfo.Password != dbPwd) + { + throw new Exception("密码错误"); + } + + if (userInfo.Status != 0) + { + throw new Exception("账号状态异常,可能已停用"); + } + + var currentSession = new UserAuthSession + { + UserId = userInfo.Id.ToString(), + Account = model.Account, + Name = userInfo.Name, + Token = Guid.NewGuid().ToString().GetHashCode().ToString("x"), + AppKey = model.AppKey, + CreateTime = DateTime.Now + // , IpAddress = HttpContext.Current.Request.UserHostAddress + }; + + //创建Session + _cacheContext.Set(currentSession.Token, currentSession, DateTime.Now.AddDays(10)); + + result.Code = 200; + result.Result = new LoginResult + { + Token = currentSession.Token + }; + + } + catch (Exception ex) + { + result.Code = 500; + result.Message = ex.Message; + } + + return result; + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SSO/LoginResult.cs b/OpenAuth.App/BaseApp/SSO/LoginResult.cs new file mode 100644 index 0000000..2d054ed --- /dev/null +++ b/OpenAuth.App/BaseApp/SSO/LoginResult.cs @@ -0,0 +1,17 @@ +using Infrastructure; + +namespace OpenAuth.App.SSO +{ + //public class LoginResult : Response + //{ + + // public string ReturnUrl; + // public string Token; + //} + + public class LoginResult + { + public string ReturnUrl; + public string Token; + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SSO/PassportLoginRequest.cs b/OpenAuth.App/BaseApp/SSO/PassportLoginRequest.cs new file mode 100644 index 0000000..a56dabd --- /dev/null +++ b/OpenAuth.App/BaseApp/SSO/PassportLoginRequest.cs @@ -0,0 +1,37 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace OpenAuth.App.SSO +{ + + public class PassportLoginRequest + { + /// System + public string Account { get; set; } + + /// e10adc3949ba59abbe56e057f20f883e + public string Password { get; set; } + + /// + /// 应用的AppSecrect,目前没判定可以随便填一个。如果需要判定请根据注释调整LoginParse.Do方法 + /// + /// openauth + public string AppKey { get; set; } + + public void Trim() + { + if (string.IsNullOrEmpty(Account)) + { + throw new Exception("用户名不能为空"); + } + + if (string.IsNullOrEmpty(Password)) + { + throw new Exception("密码不能为空"); + } + Account = Account.Trim(); + Password = Password.Trim(); + if (!string.IsNullOrEmpty(AppKey)) AppKey = AppKey.Trim(); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SSO/UserAuthSession.cs b/OpenAuth.App/BaseApp/SSO/UserAuthSession.cs new file mode 100644 index 0000000..10e348a --- /dev/null +++ b/OpenAuth.App/BaseApp/SSO/UserAuthSession.cs @@ -0,0 +1,30 @@ +using System; + +namespace OpenAuth.App.SSO +{ + [Serializable] + public class UserAuthSession + { + public string Token { get; set; } + + public string AppKey { get; set; } + /// + /// 用户主键 + /// + public string UserId { get; set; } + + /// + /// 用户账号 + /// + public string Account { get; set; } + + /// + /// 用户名 + /// + public string Name { get; set; } + + public string IpAddress { get; set; } + + public DateTime CreateTime { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SysAppFiles/SysAppFilesApp.cs b/OpenAuth.App/BaseApp/SysAppFiles/SysAppFilesApp.cs new file mode 100644 index 0000000..a0820be --- /dev/null +++ b/OpenAuth.App/BaseApp/SysAppFiles/SysAppFilesApp.cs @@ -0,0 +1,105 @@ +using Infrastructure; +using Newtonsoft.Json.Linq; +using OpenAuth.App.Base; +using OpenAuth.App.Interface; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App +{ + public class SysAppFilesApp : SqlSugarBaseApp + { + public SysAppFilesApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + + } + #region app文件 + + /// + /// 添加App文件 + /// + /// + /// + public Response AddAppFiles(SysAppFiles model) + { + var response = new Response(); + + var user = _auth.GetCurrentUser().User; + + model.Id = Guid.NewGuid().ToString(); + model.createtime = DateTime.Now; + model.createuser = user.Account; + + var flag = base.Repository.Insert(model); + if (flag) + { + response.Result = true; + response.Message = "添加成功"; + } + else + { + response.Result = false; + response.Message = "添加失败"; + } + return response; + } + + /// + /// 获取下载更新的文件路径 + /// + /// + /// + public object GetUpdateFiles(string project) + { + + var model = base.Repository.AsQueryable().Where(c => c.project_name == project).OrderBy(c => c.createtime, OrderByType.Desc).Select(c => new + { + c.Id, + edition = SqlFunc.ToInt32(c.edition), + c.description, + c.filepath, + c.createtime, + c.createuser, + c.must_update, + c.project_name, + }).First(); + + if (model != null) + { + JObject obj = new JObject(); + + string filename = model.filepath.Substring(model.filepath.LastIndexOf("\\") + 1); + + obj.Add("Id", model.Id); + obj.Add("edition", model.edition); + obj.Add("description", model.description); + obj.Add("filepath", model.filepath); + obj.Add("filename", filename); + obj.Add("createtime", model.createtime); + obj.Add("createuser", model.createuser); + obj.Add("must_update", model.must_update); + obj.Add("project_name", model.project_name); + + return obj; + } + else + { + return null; + } + } + + + public SysAppFiles GetByProject(string project) + { + return base.Repository.AsQueryable().Where(c => c.project_name == project).OrderBy(c => c.createtime, SqlSugar.OrderByType.Desc).First(); + } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/SysDataItem/SysDataItemApp.cs b/OpenAuth.App/BaseApp/SysDataItem/SysDataItemApp.cs new file mode 100644 index 0000000..e4a58cd --- /dev/null +++ b/OpenAuth.App/BaseApp/SysDataItem/SysDataItemApp.cs @@ -0,0 +1,84 @@ +using OpenAuth.App.Base; +using OpenAuth.Repository.Domain; +using OpenAuth.Repository; +using SqlSugar; +using OpenAuth.App.Interface; +using Infrastructure; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App +{ + public class SysDataItemApp : SqlSugarBaseApp + { + public SysDataItemApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + } + + public async Task> Load(string keyword, bool enabledMark = true) + { + var list = await base.Repository.AsQueryable() + .Where(a => a.DeleteMark == 0) + .WhereIF(enabledMark == true, a => a.EnabledMark == 1) + .WhereIF(!string.IsNullOrEmpty(keyword), a => a.ItemName.Contains(keyword) || a.ItemCode.Contains(keyword)) + .ToListAsync(); + + return list; + } + + public async Task GetDataItem(string code) + { + var mdeol = await base.Repository.GetFirstAsync(a => a.DeleteMark == 0 && a.ItemCode == code); + return mdeol; + } + + public async Task> SaveClassifyEntity(SysDataItem entity) + { + var flag = false; + + if (string.IsNullOrEmpty(entity.ItemId)) + { + entity.ItemId = Guid.NewGuid().ToString(); + entity.CreateDate = DateTime.Now; + if (string.IsNullOrEmpty(entity.ParentId)) + { + entity.ParentId = "0"; + } + entity.DeleteMark = 0; + entity.CreateUserId = base._auth.GetUserId(); + entity.CreateUserName = base._auth.GetUserName(); + flag = await base.Repository.InsertAsync(entity); + } + else + { + entity.ModifyDate = DateTime.Now; + entity.ModifyUserId = base._auth.GetUserId(); + entity.ModifyUserName = base._auth.GetUserName(); + flag = await base.Repository.UpdateAsync(entity); + } + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + public async Task> DeleteClassify(string keyValue) + { + using (var uow = base.UnitWork.CreateContext()) + { + await uow.SysDataItem.DeleteByIdAsync(keyValue); + await uow.SysDataItemDetail.DeleteAsync(a => a.ItemId == keyValue); + + var falg = uow.Commit(); + return new Response + { + Result = falg, + Message = (falg == true ? "success" : "error") + }; + } + } + + + } +} diff --git a/OpenAuth.App/BaseApp/SysDataItemDetail/SysDataItemDetailApp.cs b/OpenAuth.App/BaseApp/SysDataItemDetail/SysDataItemDetailApp.cs new file mode 100644 index 0000000..16d790c --- /dev/null +++ b/OpenAuth.App/BaseApp/SysDataItemDetail/SysDataItemDetailApp.cs @@ -0,0 +1,109 @@ +using Infrastructure; +using Infrastructure.Extensions; +using OpenAuth.App.Base; +using OpenAuth.App.Interface; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; +using System.Web; + +namespace OpenAuth.App +{ + public class SysDataItemDetailApp : SqlSugarBaseApp + { + ISqlSugarClient client; + public SysDataItemDetailApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + client = base.Repository.AsSugarClient(); + } + + public async Task> Load(string code, string keyWord) + { + var list = await client.Queryable() + .LeftJoin((a, b) => a.ItemId == b.ItemId) + .Where((a, b) => b.ItemCode == code) + .WhereIF(!string.IsNullOrEmpty(keyWord), (a => a.ItemName.Contains(keyWord) || a.ItemCode.Contains(keyWord))) + .OrderBy(a => a.SortCode) + .Select(a => a) + .ToListAsync(); + + return list; + } + + /// + /// 获取字段数据(有父级编号) + /// + /// 编码 + /// 筛选条件 + /// 父级编号 + /// + public async Task> LoadWithPid(string code, string keyWord,string pid) + { + var list = await client.Queryable() + .LeftJoin((a, b) => a.ItemId == b.ItemId) + .Where((a, b) => b.ItemCode == code) + .WhereIF(!string.IsNullOrEmpty(keyWord), (a => a.ItemName.Contains(keyWord) || a.ItemCode.Contains(keyWord))) + .WhereIF(!string.IsNullOrEmpty(pid),a=>a.ParentId==pid) + .OrderBy(a => a.SortCode) + .Select(a => a) + .ToListAsync(); + + return list; + } + + public async Task> SaveDetailEntity(SysDataItemDetail entity) + { + var flag = false; + + var dataItem = await client.Queryable() + .Where(a => a.DeleteMark == 0 && a.ItemId == entity.ItemId).FirstAsync(); + ; + if (dataItem.IsTree != 1 || string.IsNullOrEmpty(dataItem.ParentId)) + { + entity.ParentId = "0"; + } + + entity.QuickQuery = StringExtension.ConvertPinYin(entity.ItemName).ToUpper(); + entity.SimpleSpelling = StringExtension.PinYin(entity.ItemName); + if (string.IsNullOrEmpty(entity.ItemDetailId)) + { + entity.ItemDetailId = Guid.NewGuid().ToString(); + entity.CreateDate = DateTime.Now; + if (string.IsNullOrEmpty(entity.ParentId)) + { + entity.ParentId = "0"; + } + entity.DeleteMark = 0; + flag = await base.Repository.InsertAsync(entity); + } + else + { + entity.ItemDetailId = entity.ItemDetailId; + entity.ModifyDate = DateTime.Now; + flag = await base.Repository.UpdateAsync(entity); + } + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + public async Task> Delete(string id) + { + var flag = await base.Repository.DeleteByIdAsync(id); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } +} diff --git a/OpenAuth.App/BaseApp/SysDatabaseLink/Response/TreeModel.cs b/OpenAuth.App/BaseApp/SysDatabaseLink/Response/TreeModel.cs new file mode 100644 index 0000000..789893e --- /dev/null +++ b/OpenAuth.App/BaseApp/SysDatabaseLink/Response/TreeModel.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.SysDatabaseLink.Response +{ + public class TreeModel + { + // + // 摘要: + // 节点id + public string id { get; set; } + + // + // 摘要: + // 节点显示数据 + public string text { get; set; } + + // + // 摘要: + // 节点提示 + public string title { get; set; } + + // + // 摘要: + // 节点数值 + public string value { get; set; } + + // + // 摘要: + // 显示图标 + public string icon { get; set; } + + // + // 摘要: + // 是否显示勾选框 + public bool showcheck { get; set; } + + // + // 摘要: + // 是否被勾选0 for unchecked, 1 for partial checked, 2 for checked + public int checkstate { get; set; } + + // + // 摘要: + // 是否有子节点 + public bool hasChildren { get; set; } + + // + // 摘要: + // 是否展开 + public bool isexpand { get; set; } + + // + // 摘要: + // 子节点是否已经加载完成了 + public bool complete { get; set; } + + // + // 摘要: + // 子节点列表数据 + public List ChildNodes { get; set; } + + // + // 摘要: + // 父级节点ID + public string parentId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/SysDatabaseLink/SysDatabaseLinkApp.cs b/OpenAuth.App/BaseApp/SysDatabaseLink/SysDatabaseLinkApp.cs new file mode 100644 index 0000000..b837ffd --- /dev/null +++ b/OpenAuth.App/BaseApp/SysDatabaseLink/SysDatabaseLinkApp.cs @@ -0,0 +1,241 @@ +using Infrastructure; +using Infrastructure.Extensions; +using OpenAuth.App.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.SysDatabaseLink.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Core; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App.SysDatabaseLink +{ + public class SysDatabaseLinkApp : SqlSugarBaseApp + { + public SysDatabaseLinkApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + + } + + /// + /// 获取树形数据 + /// + /// + public async Task>> LoadDataBaseLinkTree() + { + var list = await this.Repository.AsQueryable().Where(r => r.DeleteMark == 0).ToListAsync(); + List treelist = new List(); + Dictionary> dic = new Dictionary>(); + + TreeModel mynode = new TreeModel(); + mynode.id = "hcsystemdb"; + mynode.text = "本地数据库"; + mynode.value = "hcsystemdb"; + mynode.complete = true; + mynode.hasChildren = false; + treelist.Add(mynode); + foreach (var item in list) + { + TreeModel node = new TreeModel(); + node.id = item.DBName; + node.text = item.DBAlias; + node.value = item.DBName; + node.complete = true; + node.hasChildren = false; + + if (!dic.ContainsKey(item.ServerAddress)) + { + TreeModel pnode = new TreeModel(); + pnode.id = item.ServerAddress; + pnode.text = item.ServerAddress; + pnode.value = "hcServerAddress"; + pnode.isexpand = true; + pnode.complete = true; + pnode.hasChildren = true; + pnode.ChildNodes = new List(); + treelist.Add(pnode); + dic.Add(item.ServerAddress, pnode.ChildNodes); + } + dic[item.ServerAddress].Add(node); + } + return new Response> + { + Result = treelist + }; + } + + /// + /// 分页获取列表数据 + /// + /// + /// + /// + /// + public async Task>>> LoadDataBaseInfo(string keyword, int pageindex, int pagesize) + { + //定义且实例化分页数据 + RefAsync totalCount = 0; + + //数据查询并返回 + var info = await this.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(keyword), t => t.DBName.Contains(keyword)) + .OrderBy(r=>r.DBName) + .ToPageListAsync(pageindex, pagesize, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = info, + Total = totalCount + } + }; + } + + /// + /// 获取实体数据 + /// + /// 数据库连接主键 + /// + public async Task> GetDataBaseForm(string id) + { + var info = await this.Repository.GetByIdAsync(id); + return new Response + { + Result = info + }; + } + /// + /// 添加数据库连接(新增、修改) + /// + /// 主键值 + /// 数据库实体 + /// + public async Task> SaveBaseLinkEntity(string keyValue, Repository.Domain.SysDatabaseLink baseLink) + { + /*测试数据库连接串"******";*/ + if (!string.IsNullOrEmpty(keyValue) && baseLink.DBConnection == "******") + { + baseLink.DBConnection = null;// 不更新连接串地址 + } + else + { + var testRes = TestConnection(baseLink.DBConnection, baseLink.DBType); + if (testRes != "success") + { + return new Response + { + Result = false, + Message = "字符串连接失败" + }; + } + } + var user = _auth.GetCurrentUser().User; + using (var uwo = base.UnitWork.CreateContext()) + { + if (!string.IsNullOrEmpty(keyValue)) + { + + baseLink.DatabaseLinkId = keyValue; + baseLink.ModifyDate = DateTime.Now; + baseLink.ModifyUserId = user.Id.ToString(); + baseLink.ModifyUsername = user.Name; + await uwo.SysDatabaseLink.UpdateAsync(baseLink); + } + else + { + baseLink.DatabaseLinkId = Guid.NewGuid().ToString(); + baseLink.Createdate = DateTime.Now; + baseLink.DeleteMark = 0; + baseLink.EnabledMark = 1; + baseLink.CreateUserId = user.Id.ToString(); + baseLink.CreateUsername = user.Name; + await uwo.SysDatabaseLink.InsertAsync(baseLink); + } + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "操作成功" : "操作失败" + }; + } + } + + /// + /// 删除数据库连接 + /// + /// 主键 + /// + public async Task> DeleteBaseLink(string id) + { + using (var uwo = base.UnitWork.CreateContext()) + { + await uwo.SysDatabaseLink.DeleteByIdAsync(id); + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "操作成功" : "操作失败" + }; + } + } + + #region 扩展方法 + /// + /// 测试数据数据库是否能连接成功 + /// + /// 连接串 + /// 数据库类型 + public string TestConnection(string connection, string dbType) + { + try + { + this.TestLinkClient(connection, dbType).BeginTran(); + this.TestLinkClient(connection, dbType).CommitTran(); + return "success"; + } + catch (Exception ex) + { + return ex.Message; + } + } + + /// + /// 测试连接串是否正确 + /// + /// 连接串 + /// 数据库类型 + /// 主键 + /// + public async Task> TestDataBaseLink(string connection, string dbType, string id) + { + if (!string.IsNullOrEmpty(id) && connection == "******") + { + Repository.Domain.SysDatabaseLink entity = await this.Repository.GetByIdAsync(id); + if (entity != null) + { + connection = entity.DBConnection; + } + } + string res = TestConnection(connection, dbType); + var flag = false; + if (res == "success") + { + flag = true; + } + return new Response + { + Result = flag, + Message = flag == true ? "连接成功" : "连接失败" + }; + } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/SysLogs/Request/QuerySysLogListReq.cs b/OpenAuth.App/BaseApp/SysLogs/Request/QuerySysLogListReq.cs new file mode 100644 index 0000000..a3fa012 --- /dev/null +++ b/OpenAuth.App/BaseApp/SysLogs/Request/QuerySysLogListReq.cs @@ -0,0 +1,7 @@ +namespace OpenAuth.App.Request +{ + public class QuerySysLogListReq : PageReq + { + //todo:添加自己的请求字段 + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SysLogs/SysLogApp.cs b/OpenAuth.App/BaseApp/SysLogs/SysLogApp.cs new file mode 100644 index 0000000..5fa8592 --- /dev/null +++ b/OpenAuth.App/BaseApp/SysLogs/SysLogApp.cs @@ -0,0 +1,61 @@ +using System.Reflection; +using System.Threading.Tasks; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + public class SysLogApp : SqlSugarBaseApp + { + public SysLogApp(ISugarUnitOfWork unitWork, ISimpleClient repository) : base(unitWork, repository, null) + { + } + + /// + /// 加载列表 + /// + public async Task Load(QuerySysLogListReq request) + { + int totalCount = 0; + var result = new TableData(); + var objs = base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(request.key), u => u.Content.Contains(request.key)); + + result.data = await objs.OrderByDescending(u => u.CreateTime).ToPageListAsync(request.page, request.limit, totalCount); + result.count = totalCount; + + return result; + } + + public void Add(SysLog obj) + { + //程序类型取入口应用的名称,可以根据自己需要调整 + obj.Application = Assembly.GetEntryAssembly().FullName.Split(',')[0]; + obj.Id = Yitter.IdGenerator.YitIdHelper.NextId(); + Repository.Insert(obj); + } + + public void Update(SysLog obj) + { + base.Repository.Update(u => new SysLog + { + //todo:要修改的字段赋值 + }, u => u.Id == obj.Id); + } + + public SysLog Get(string id) + { + return Repository.GetById(id); + } + + public void Delete(string[] ids) + { + Repository.DeleteByIds(ids); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SysMessage/Request/QuerySysMessageListReq.cs b/OpenAuth.App/BaseApp/SysMessage/Request/QuerySysMessageListReq.cs new file mode 100644 index 0000000..895c93f --- /dev/null +++ b/OpenAuth.App/BaseApp/SysMessage/Request/QuerySysMessageListReq.cs @@ -0,0 +1,10 @@ +namespace OpenAuth.App.Request +{ + public class QuerySysMessageListReq : PageReq + { + /// + /// 消息状态 0:未读;1:已读; 999:全部 + /// + public int Status { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SysMessage/SysMessageApp.cs b/OpenAuth.App/BaseApp/SysMessage/SysMessageApp.cs new file mode 100644 index 0000000..f3edc3f --- /dev/null +++ b/OpenAuth.App/BaseApp/SysMessage/SysMessageApp.cs @@ -0,0 +1,130 @@ +using Infrastructure; +using Microsoft.Extensions.Logging; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + public class SysMessageApp : SqlSugarBaseApp + { + private readonly ILogger _logger; + + public SysMessageApp( + ISugarUnitOfWork unitWork, + ISimpleClient repository, + IAuth auth, + ILogger logger) : base(unitWork, repository, auth) + { + _logger = logger; + } + + /// + /// 加载列表 + /// + public async Task Load(QuerySysMessageListReq request) + { + var loginContext = _auth.GetCurrentUser(); + if (loginContext == null) + { + throw new CommonException("登录已过期", Define.INVALID_TOKEN); + } + + int totalCount = 0; + var result = new TableData(); + var objs = base.Repository.AsQueryable().Where(u => u.ToId == loginContext.User.Id && u.ToStatus != -1) + .WhereIF(!string.IsNullOrEmpty(request.key), u => u.Title.Contains(request.key)) + .WhereIF(request.Status != 999, u => u.ToStatus == request.Status); + + result.data = await objs.OrderByDescending(u => u.CreateTime).ToPageListAsync(request.page, request.limit, totalCount); + result.count = totalCount; + + return result; + } + + public void Add(SysMessage obj) + { + obj.Id = Yitter.IdGenerator.YitIdHelper.NextId(); + Repository.Insert(obj); + } + + /// + /// 发送指定消息给用户 + /// + /// + /// + public void SendMsgTo(long userId, string message) + { + SysUser user = null; + if (userId == -1) + { + user = new SysUser + { + Name = Define.SYSTEM_USERNAME, + Id = userId + }; + } + else + { + user = (Repository.ChangeRepository>()).GetFirst(u => u.Id == userId); + } + if (user == null) + { + _logger.LogError($"未能找到用户{userId},不能给该用户发送消息"); + return; + } + Repository.Insert(new SysMessage + { + ToId = user.Id, + ToName = user.Name, + TypeName = "系统消息", + TypeId = "SYS_MSG", + FromId = Guid.Empty.ToString(), + FromName = "系统管理员", + Content = message, + CreateTime = DateTime.Now + }); + } + + /// + /// 消息变为已读 + /// + /// + public void Read(IdRequest req) + { + Repository.Update(u => new SysMessage + { + ToStatus = 1 + }, u => u.Id == req.Id); + } + /// + /// 消息采用逻辑删除 + /// + /// + public void Del(long[] ids) + { + Repository.Update(u => new SysMessage + { + ToStatus = -1 //逻辑删除 + }, u => ids.Contains(u.Id)); + + } + + public void Delete(string[] ids) + { + Repository.DeleteByIds(ids); + } + + public SysMessage Get(string id) + { + return Repository.GetById(id); + } + + + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/SysPosGroup/Request/PosGroupForm.cs b/OpenAuth.App/BaseApp/SysPosGroup/Request/PosGroupForm.cs new file mode 100644 index 0000000..b357dbe --- /dev/null +++ b/OpenAuth.App/BaseApp/SysPosGroup/Request/PosGroupForm.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class PosGroupForm + { + public string Name { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/SysPosGroup/SysPosGroupApp.cs b/OpenAuth.App/BaseApp/SysPosGroup/SysPosGroupApp.cs new file mode 100644 index 0000000..ff2f208 --- /dev/null +++ b/OpenAuth.App/BaseApp/SysPosGroup/SysPosGroupApp.cs @@ -0,0 +1,54 @@ +using OpenAuth.App.Base; +using OpenAuth.Repository.Domain; +using OpenAuth.Repository; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using OpenAuth.App.Interface; +using Infrastructure; +using OpenAuth.App; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Request; + +namespace OpenAuth.App +{ + public class SysPosGroupApp : SqlSugarBaseApp + { + public SysPosGroupApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + } + + + public async Task>> Load(string name) + { + var groups = await base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(name), g => g.Name.Contains(name)) + .ToListAsync(); + + return new Response> + { + Result = groups + }; + } + + public async Task> Add(PosGroupForm pos) + { + var userId = base._auth.GetCurrentUser().User.Id; + + var model = pos.MapTo(); + model.Id = Yitter.IdGenerator.YitIdHelper.NextId(); + model.CreateId = userId; + model.CreateTime = DateTime.Now; + + var flag = await base.Repository.InsertAsync(model); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } +} diff --git a/OpenAuth.App/BaseApp/SysPosition/Request/QueryPositonListReq.cs b/OpenAuth.App/BaseApp/SysPosition/Request/QueryPositonListReq.cs new file mode 100644 index 0000000..4a42172 --- /dev/null +++ b/OpenAuth.App/BaseApp/SysPosition/Request/QueryPositonListReq.cs @@ -0,0 +1,14 @@ +using OpenAuth.App.Request; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class QueryPositonListReq : PageReq + { + public long GroupId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/SysPosition/SysPositionApp.cs b/OpenAuth.App/BaseApp/SysPosition/SysPositionApp.cs new file mode 100644 index 0000000..aabd0e0 --- /dev/null +++ b/OpenAuth.App/BaseApp/SysPosition/SysPositionApp.cs @@ -0,0 +1,137 @@ +using OpenAuth.App.Base; +using OpenAuth.Repository.Domain; +using OpenAuth.Repository; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using OpenAuth.App.Interface; +using Infrastructure; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.Repository.Core; +using Oracle.ManagedDataAccess.Types; + +namespace OpenAuth.App +{ + public class SysPositionApp : SqlSugarBaseApp + { + public SysPositionApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + } + + public async Task> Get(long id) + { + var pos = await base.Repository.GetByIdAsync(id); + return new Response + { + Result = pos, + Message = "success" + }; + } + + public async Task>>> Load(QueryPositonListReq req) + { + RefAsync totalCount = 0; + var list = await base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(req.key), p => p.Name.Contains(req.key)) + .WhereIF(req.GroupId != 0, p => p.GroupId == req.GroupId) + .OrderBy(p => p.Id) + .ToPageListAsync(req.page, req.limit, totalCount); + + return new Response>> + { + Result = new PageInfo> + { + Items = list, + Total = totalCount + } + }; + } + + public async Task>> PositionsTree(long groupId) + { + var result = new Response>(); + + if (groupId != 0) + { + object[] posIds = (await base.Repository.AsQueryable() + .Where(a => a.GroupId == groupId) + .Select(it => it.Id).ToListAsync()).Cast().ToArray(); + + result.Result = await base.Repository.AsQueryable() + .Select() + .ToTreeAsync(a => a.Children, a => a.ParentId, 0, posIds); + } + else + { + result.Result = await base.Repository.AsQueryable() + .Select() + .ToTreeAsync(a => a.Children, a => a.ParentId, 0, a => a.Id); + } + + return result; + } + + public async Task> Add(SysPosition pos) + { + pos.Id = Yitter.IdGenerator.YitIdHelper.NextId(); + var flag = await base.Repository.InsertAsync(pos); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + public async Task> Update(SysPosition pos) + { + var flag = await base.Repository.UpdateAsync(pos); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + #region 根据部门查询职级 + public async Task>> LoadPositionByOrg(long orgid) + { + //var list = new List(); + //var org = base.Repository.ChangeRepository>().AsQueryable() + // .Where(r => r.Id == orgid).First(); + //if (org != null) + //{ + // list = await base.Repository + // .AsQueryable() + // .Where(r => r.GroupId == org.PosGroupId) + // .OrderBy(r => r.Name) + // .Select() + // .ToTreeAsync(a => a.Children, a => a.ParentId, 0, a => a.Id); + //} + //return new Response> + //{ + // Result = list + //}; + + var poses = await base.Repository.AsQueryable() + .LeftJoin((p1, p2) => p1.ParentId == p2.Id && p2.OrgId == orgid) + .Where(p1 => p1.OrgId == orgid) + .Select((p1, p2) => new TreeItemLong + { + Id = p1.Id, + ParentId = p2.Id == null ? 0 : p1.ParentId, + Name = p1.Name + }).ToTreeAsync(a => a.Children, a => a.ParentId, 0, a => a.Id); + + return new Response> + { + Result = poses + }; + + + } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/Request/AssignUserOrgs.cs b/OpenAuth.App/BaseApp/UserManager/Request/AssignUserOrgs.cs new file mode 100644 index 0000000..d329f66 --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/Request/AssignUserOrgs.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class AssignUserOrgs + { + public long UserId { get; set; } + public List OrgPoses { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/Request/AssignUserRoles.cs b/OpenAuth.App/BaseApp/UserManager/Request/AssignUserRoles.cs new file mode 100644 index 0000000..078de5c --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/Request/AssignUserRoles.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class AssignUserRoles + { + public long UserId { get; set; } + + public List RoleIds { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/Request/ChangePasswordReq.cs b/OpenAuth.App/BaseApp/UserManager/Request/ChangePasswordReq.cs new file mode 100644 index 0000000..892a5e9 --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/Request/ChangePasswordReq.cs @@ -0,0 +1,8 @@ +namespace OpenAuth.App.Request +{ + public class ChangePasswordReq + { + public string Account { get; set; } + public string Password { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/Request/ChangeProfileReq.cs b/OpenAuth.App/BaseApp/UserManager/Request/ChangeProfileReq.cs new file mode 100644 index 0000000..065f8c1 --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/Request/ChangeProfileReq.cs @@ -0,0 +1,16 @@ +namespace OpenAuth.App.Request +{ + public class ChangeProfileReq + { + public string Account { get; set; } + + /// + /// 用户姓名 + /// + public string Name { get; set; } + /// + /// 性别 + /// + public int Sex { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/Request/QueryUserListByOrgReq.cs b/OpenAuth.App/BaseApp/UserManager/Request/QueryUserListByOrgReq.cs new file mode 100644 index 0000000..4ced4d5 --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/Request/QueryUserListByOrgReq.cs @@ -0,0 +1,7 @@ +namespace OpenAuth.App.Request +{ + public class QueryUserListByOrgReq : PageReq + { + public long orgId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/Request/QueryUserListByRoleReq.cs b/OpenAuth.App/BaseApp/UserManager/Request/QueryUserListByRoleReq.cs new file mode 100644 index 0000000..0cfabc0 --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/Request/QueryUserListByRoleReq.cs @@ -0,0 +1,7 @@ +namespace OpenAuth.App.Request +{ + public class QueryUserListByRoleReq : PageReq + { + public long roleId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/Request/QueryUserListReq.cs b/OpenAuth.App/BaseApp/UserManager/Request/QueryUserListReq.cs new file mode 100644 index 0000000..88ea0f0 --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/Request/QueryUserListReq.cs @@ -0,0 +1,7 @@ +namespace OpenAuth.App.Request +{ + public class QueryUserListReq : PageReq + { + public long orgId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/Request/UpdateUserReq.cs b/OpenAuth.App/BaseApp/UserManager/Request/UpdateUserReq.cs new file mode 100644 index 0000000..98fc4ec --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/Request/UpdateUserReq.cs @@ -0,0 +1,67 @@ +using System.ComponentModel.DataAnnotations; +using Infrastructure; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.App.Request +{ + /// + /// 添加或修改用户信息的请求 + /// + public class UpdateUserReq + { + /// + /// 用户ID + /// + /// + public long Id { get; set; } + + + /// + /// + /// + [Required(ErrorMessage = "账号肯定不能为空啊~~")] + public string Account { get; set; } + + /// + /// + /// + public string Password { get; set; } + + + /// + /// 用户姓名 + /// + /// + [Required(ErrorMessage="姓名不能为空")] + public string Name { get; set; } + + + /// + /// + /// + public int Sex { get; set; } + + + /// + /// 当前状态 + /// + /// + public int Status { get; set; } + + + public static implicit operator UpdateUserReq(SysUser user) + { + return user.MapTo(); + } + + public static implicit operator SysUser(UpdateUserReq view) + { + return view.MapTo(); + } + + public UpdateUserReq() + { + + } + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/Response/UserView.cs b/OpenAuth.App/BaseApp/UserManager/Response/UserView.cs new file mode 100644 index 0000000..dd832e6 --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/Response/UserView.cs @@ -0,0 +1,85 @@ +using System; +using Infrastructure; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.App.Response +{ + public class UserView + { + /// + /// 用户ID + /// + /// + public long Id { get; set; } + + + /// + /// + /// + public string Account { get; set; } + + + /// + /// 组织名称 + /// + /// + public string Name { get; set; } + + + /// + /// + /// + public int Sex { get; set; } + + + /// + /// 当前状态 + /// + /// + public int Status { get; set; } + + + /// + /// 组织类型 + /// + /// + public int Type { get; set; } + + + + /// + /// 创建时间 + /// + /// + public DateTime CreateTime { get; set; } + + + /// + /// 创建人名字 + /// + /// The create user. + public long CreateUser { get; set; } + + /// + /// 所属组织名称,多个可用,分隔 + /// + /// The organizations. + public string Organizations { get; set; } + + public string OrganizationIds { get; set; } + /// + /// 用户最大部门等级 + /// + public string OrgMaxLevel { get; set; } + + public static implicit operator UserView(SysUser user) + { + return user.MapTo(); + } + + public static implicit operator SysUser(UserView view) + { + return view.MapTo(); + } + } +} diff --git a/OpenAuth.App/BaseApp/UserManager/UserManagerApp.cs b/OpenAuth.App/BaseApp/UserManager/UserManagerApp.cs new file mode 100644 index 0000000..2bcbf99 --- /dev/null +++ b/OpenAuth.App/BaseApp/UserManager/UserManagerApp.cs @@ -0,0 +1,669 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using DocumentFormat.OpenXml.Spreadsheet; +using DocumentFormat.OpenXml.Wordprocessing; +using Infrastructure; +using Infrastructure.Extensions; +using Infrastructure.Helpers; +using Infrastructure.Utilities; +using Microsoft.AspNetCore.Http; +using NetModular.DocX.Core; +using NPOI.HSSF.UserModel; +using NPOI.SS.Formula.Functions; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; +using OpenAuth.App.Base; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Config; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SixLabors.ImageSharp; +using SqlSugar; +using Yitter.IdGenerator; +using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData; + +namespace OpenAuth.App +{ + public class UserManagerApp : SqlSugarBaseApp + { + private ISqlSugarClient client; + + #region 构造函数 + public UserManagerApp( + ISugarUnitOfWork unitWork, + ISimpleClient repository, + IAuth auth, + ISqlSugarClient sqlSugarClient + ) : base(unitWork, repository, auth) + { + this.client = sqlSugarClient; + } + #endregion + + #region 用户查询 + + public async Task>>> LoadAll(QueryUserListReq request) + { + RefAsync totalNumber = 0; + //过滤orgid传参 + List dpt = new List(); + if (request.orgId != 0) + { + dpt = client.Queryable().ToChildList(it => it.ParentId, request.orgId)?.Select(it => it.Id).ToList(); + } + var aa = client.Queryable().Where(r => dpt.Contains(r.OrgId)).ToList(); + var table = await base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(request.key), u => u.Account.Contains(request.key) || u.Name.Contains(request.key)) + .LeftJoin((u, o) => u.Id == o.UserId) + .WhereIF(request.orgId != 0, (u, o) => dpt.Contains(o.OrgId)) + .OrderByDescending((u, o) => u.CreateTime) + .Distinct() + .Select((u, o) => new + { + id = u.Id, + account = u.Account, + name = u.Name, + createtime = u.CreateTime, + department = SqlFunc.Subqueryable().Where(a => a.UserId == u.Id).LeftJoin((a, o) => a.OrgId == o.Id).SelectStringJoin((a, o) => o.Name, ","), + role = SqlFunc.Subqueryable().Where(a => a.UserId == u.Id).LeftJoin((a, o) => a.RoleId == o.Id).SelectStringJoin((a, o) => o.Name, ","), + }) + .ToPageListAsync(request.page, request.limit, totalNumber); + + return new Response>>() + { + Result = new PageInfo> + { + Items = table, + Total = totalNumber + } + }; + } + public List getAllChildOrgId(long parentId) + { + var query = base.Repository.AsSugarClient().Queryable() + .Where(c => c.ParentId == parentId) + .Select(c => new { c.Id, c.ParentId }) + .ToList(); + + var childIds = query.Select(c => c.Id).ToList(); + var grandChildIds = query.SelectMany(c => getAllChildOrgId(c.Id)).ToList(); + + childIds.AddRange(grandChildIds); + return childIds; + } + + + public async Task>>> Load(QueryUserListReq request) + { + + var user = _auth.GetCurrentUser().User; + + string sqlstr = "select \"min\"(\"Level\") from sys_userorg where \"UserId\"='" + user.Id + "' "; + var level = client.Ado.GetInt(sqlstr); + if (level == 0 || user.Id == -1) + { + + + RefAsync totalNumber = 0; + + var table = await base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(request.key), u => u.Account.Contains(request.key) || u.Name.Contains(request.key)) + .WhereIF(request.orgId != 0, + u => SqlFunc.Subqueryable().Where(uo => uo.OrgId == request.orgId && uo.UserId == u.Id).Any()) + .OrderByDescending(u => u.CreateTime) + .Select() + .ToPageListAsync(request.page, request.limit, totalNumber); + + return new Response>>() + { + Result = new PageInfo> + { + Items = table, + Total = totalNumber + } + }; + + + } + else + { + string sqlstr1 = "select \"OrgId\" from sys_userorg where \"Level\"=" + level + " and \"UserId\"='" + user.Id + "' "; + List orgIds1 = client.Ado.SqlQuery(sqlstr1); + int count11 = orgIds1.Count; + for (int i = 0; i < count11; i++) + + { + List longs = getAllChildOrgId(orgIds1[i]); + orgIds1.AddRange(longs); + } + string keyword = ""; + if (!string.IsNullOrEmpty(request.key)) + { + keyword = keyword + "and a.\"Name\" like '%" + request.key + "%'"; + } + string orgsql = ""; + if (request.orgId != 0) + { + orgsql = " and \"OrgId\" ='" + request.orgId + "'"; + } + string orgIds = ""; + for (int j = 0; j < orgIds1.Count; j++) + { + if (j == orgIds1.Count - 1) + { + orgIds = orgIds + orgIds1[j]; + } + else + { + orgIds = orgIds + orgIds1[j] + ","; + } + + } + + string sql = "WITH t as (\r\nselect \"UserId\" from ( select * from sys_userorg where \"UserId\" not in (select \"UserId\" from sys_userorg where \"Level\"<(select \"min\"(\"Level\") from sys_userorg " + + // " where \"UserId\"='"+ user.Id+ "' ))) a where a.\"OrgId\" in (select \"OrgId\" from sys_userorg where \"UserId\"='"+ user.Id+ "'"+ orgsql + " ) GROUP BY \"UserId\")"; + " where \"UserId\"='" + user.Id + "' ))) a where a.\"OrgId\" =ANY(array[" + orgIds + "]) GROUP BY \"UserId\")"; + string sql1 = "((SELECT a.* FROM t LEFT JOIN sys_user a on t.\"UserId\"=a.\"Id\" where 1=1 " + keyword + " ) UNION (SELECT * FROM sys_user a where a.\"CreateId\"='" + user.Id + "' " + keyword + ")) limit " + request.limit + "OFFSET " + (request.page - 1) * request.limit; + string sql2 = "(SELECT COUNT(a.*) FROM t LEFT JOIN sys_user a on t.\"UserId\"=a.\"Id\" where 1=1 " + keyword + " ) "; + string sql3 = "SELECT COUNT(a.*) FROM sys_user a where a.\"CreateId\"='" + user.Id + "' " + keyword; + + + var table = client.Ado.SqlQuery(sql + sql1); + int count1 = client.Ado.GetInt(sql + sql2); + int count2 = client.Ado.GetInt(sql + sql3); + + int count = count1 + count2; + /* var orgIds = base._auth.GetCurrentUser().Orgs.Select(o => o.Id); + + RefAsync totalNumber = 0; + + var table = await base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(request.key), u => u.Account.Contains(request.key) || u.Name.Contains(request.key)) + .WhereIF(request.orgId != 0, + u => SqlFunc.Subqueryable().Where(uo => uo.OrgId == request.orgId && uo.UserId == u.Id).Any()) + .Where(u => SqlFunc.Subqueryable().Where(uo => orgIds.Contains(uo.OrgId) && uo.UserId == u.Id).Any()) + .OrderByDescending(u => u.CreateTime) + .Select() + .ToPageListAsync(request.page, request.limit, totalNumber);*/ + + return new Response>>() + { + Result = new PageInfo> + { + Items = table, + Total = count + } + }; + } + } + + public async Task>>> LoadUsers(QueryUserListReq request) + { + //获取当前用户 + var user = _auth.GetCurrentUser().User; + RefAsync totalNumber = 0; + //该用户下包含所有部门 + List deplist = new List(); + if (user != null) + { + var departs = client.Queryable().Where(r => r.UserId == user.Id).ToList(); + foreach (var item in departs) + { + var list = client.Queryable().ToChildList(it => it.ParentId, item.OrgId)?.Select(it => it.Id).ToList(); + deplist = deplist.Union(list).ToList(); + } + } + + //过滤orgid传参 + List dpt = new List(); + if (request.orgId != 0) + { + dpt = client.Queryable().ToChildList(it => it.ParentId, request.orgId)?.Select(it => it.Id).ToList(); + } + + //获取列表数据 + var table = await base.Repository.AsQueryable() + .WhereIF(!string.IsNullOrEmpty(request.key), u => u.Account.Contains(request.key) || u.Name.Contains(request.key))//过滤key + .LeftJoin((u, o) => u.Id == o.UserId) + .Where((u, o) => deplist.Contains(o.OrgId) || u.CreateId == user.Id) //部门及创建人 + .WhereIF(request.orgId != 0, (u, o) => dpt.Contains(o.OrgId)) //部门及左侧选择部门 + .Distinct() + .OrderByDescending((u, o) => u.CreateTime) + .Select((u, o) => new + { + id = u.Id, + account = u.Account, + name = u.Name, + create = u.CreateTime, + department = SqlFunc.Subqueryable().Where(a => a.UserId == u.Id).LeftJoin((a, o) => a.OrgId == o.Id).SelectStringJoin((a, o) => o.Name, ","), + role = SqlFunc.Subqueryable().Where(a => a.UserId == u.Id).LeftJoin((a, o) => a.RoleId == o.Id).SelectStringJoin((a, o) => o.Name, ","), + }) + .ToPageListAsync(request.page, request.limit, totalNumber); + + return new Response>>() + { + Result = new PageInfo> + { + Items = table, + Total = totalNumber + } + }; + } + + /// + /// 获取指定角色包含的用户列表 + /// + /// + /// + public async Task>>> LoadByRole(QueryUserListByRoleReq request) + { + RefAsync totalCount = 0; + + var users = await client.Queryable() + .LeftJoin((ur, u) => ur.UserId == u.Id) + .Where(ur => ur.RoleId == request.roleId) + .Select((ur, u) => new UserView + { + Id = u.Id, + Account = u.Account, + Name = u.Name + }).ToPageListAsync(request.page, request.limit, totalCount); + + return new Response>> + { + Code = 200, + Message = "success", + Result = new PageInfo> + { + Items = users, + Total = totalCount + } + }; + + } + + + /// + /// 获取指定机构包含的用户列表 + /// + /// + /// + public async Task LoadByOrg(QueryUserListByOrgReq request) + { + var db = base.Repository.AsSugarClient(); + RefAsync totalCount = 0; + + var users = await db.CopyNew().Queryable() + .LeftJoin((uo, u) => uo.UserId == u.Id) + .Where((uo, u) => uo.OrgId == request.orgId) + .ToPageListAsync(request.page, request.limit, totalCount); + + return new TableData + { + count = (int)totalCount, + data = users + }; + } + + /// + /// 根据 account 判断帐号是否存在 + /// + /// + /// + public bool IsExistUser(string account) + { + return base.Repository.IsAny(a => a.Account == account); + } + + public SysUser Get(long id) + { + return Repository.GetById(id); + } + + public SysUser GetByAccount(string account) + { + return Repository.GetFirst(u => u.Account == account); + } + #endregion + + #region 用户增删改 + + #region 添加/修改 + public Response AddOrUpdate(UpdateUserReq request) + { + request.ValidationEntity(u => new { u.Account, u.Name }); + + SysUser requser = request; + requser.CreateId = _auth.GetCurrentUser().User.Id; + + using (var uow = base.UnitWork.CreateContext()) + { + if (request.Id == 0) + { + if (uow.User.IsAny(u => u.Account == request.Account)) + { + throw new Exception("用户账号已存在"); + } + + requser.Secretkey = Md5Helper.Encrypt(CommonHelper.CreateNo(), 16).ToLower(); + if (string.IsNullOrEmpty(requser.Password)) + { + requser.Password = Md5Helper.Encrypt(DESEncrypt.Encrypt(Md5Helper.Hash(requser.Account), requser.Secretkey).ToLower(), 32).ToLower(); //如果客户端没提供密码,默认密码同账号 + } + else + { + requser.Password = Md5Helper.Encrypt(DESEncrypt.Encrypt(requser.Password, requser.Secretkey).ToLower(), 32).ToLower(); + } + requser.CreateTime = DateTime.Now; + requser.Id = Yitter.IdGenerator.YitIdHelper.NextId(); + uow.User.Insert(requser); + request.Id = requser.Id; //要把保存后的ID存入view + } + else + { + uow.User.Update(u => new SysUser + { + Account = requser.Account, + BizCode = requser.BizCode, + Name = requser.Name, + Sex = requser.Sex, + Status = requser.Status + }, u => u.Id == request.Id); + if (!string.IsNullOrEmpty(requser.Password)) //密码为空的时候,不做修改 + { + var userInfo = uow.User.GetById(requser.Id); + + requser.Password = Md5Helper.Encrypt(DESEncrypt.Encrypt(requser.Password, userInfo.Secretkey).ToLower(), 32).ToLower(); + uow.User.Update(u => new SysUser + { + Password = requser.Password + }, u => u.Id == request.Id); + } + } + + var flag = uow.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + #endregion + + #region 删除 + /// + /// 删除用户,包含用户与组织关系、用户与角色关系 + /// + /// + public Response Delete(long[] ids) + { + using (var uow = base.UnitWork.CreateContext()) + { + uow.SysUserOrg.Delete(a => ids.Contains(a.UserId)); + uow.SysUserRole.Delete(a => ids.Contains(a.UserId)); + uow.User.Delete(u => ids.Contains(u.Id)); + var flag = uow.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + #endregion + + #region 分配角色 + public async Task> UserRoles(AssignUserRoles userRoles) + { + using (var uow = base.UnitWork.CreateContext()) + { + //删除用户相关角色 + await uow.SysUserRole.DeleteByIdAsync(userRoles.UserId); + //重新添加本次角色 + var models = userRoles.RoleIds.Select(r => new SysUserRole { UserId = userRoles.UserId, RoleId = r }).ToList(); + await uow.SysUserRole.InsertRangeAsync(models); + + var flag = uow.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + #endregion + + #region 分配部门 + public async Task> UserOrgs(AssignUserOrgs userOrgs) + { + using (var uow = base.UnitWork.CreateContext()) + { + //删除用户相关部门 + await uow.SysUserOrg.DeleteByIdAsync(userOrgs.UserId); + //重新添加本次部门 + var models = userOrgs.OrgPoses.Select(o => new SysUserOrg { UserId = userOrgs.UserId, OrgId = o.OrgId, PositionId = o.PosId, Level = o.Level }).ToList(); + await uow.SysUserOrg.InsertRangeAsync(models); + + var flag = uow.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + #endregion + #region 修改密码 + /// + /// 修改密码 + /// + /// + public void ChangePassword(ChangePasswordReq request) + { + var user = base.Repository.GetFirst(a => a.Account == request.Account); + + if (user != null) + { + var pwd = Md5Helper.Encrypt(DESEncrypt.Encrypt(request.Password, user.Secretkey).ToLower(), 32).ToLower(); + + Repository.Update(user => new SysUser + { + Password = pwd + }, u => u.Account == request.Account); + } + } + #endregion + + #region 修改用户资料 + /// + /// 修改用户资料 + /// + /// + public void ChangeProfile(ChangeProfileReq request) + { + if (request.Account == Define.SYSTEM_USERNAME) + { + throw new Exception("不能修改超级管理员信息"); + } + + Repository.Update(user => new SysUser + { + Name = request.Name, + Sex = request.Sex + }, u => u.Account == request.Account); + } + #endregion + + #region 更新数据库实体类 + /// + /// 更新数据库实体类 + /// + /// + public string AddEntity() + { + using (var uow = base.UnitWork.CreateContext()) + { + foreach (var item in uow.Db.DbMaintenance.GetTableInfoList().Where(r => r.Name.ToLower().StartsWith("drone_caseinfo_sthx"))) + { + //string entityName = item.Name.Substring(0, 1).ToUpper() + item.Name.Substring(1, 7).ToLower() + item.Name.Substring(9, 1).ToUpper() + item.Name.Substring(10).ToLower();/*实体名大写*/ + string entityName = "DroneCaseInfoSTHX"; + uow.Db.MappingTables.Add(entityName, item.Name); + //foreach (var col in db.DbMaintenance.GetColumnInfosByTableName(item.Name)) + //{ + // db.MappingColumns.Add(col.DbColumnName.ToUpper() /*类的属性大写*/, col.DbColumnName, entityName); + //} + } + uow.Db.DbFirst.Where(r => r.ToLower().StartsWith("drone_caseinfo_sthx")).IsCreateAttribute().CreateClassFile("E:\\天空地\\codeLinyi\\Project1\\OpenAuth.Repository\\Domain", "OpenAuth.Repository.Domain"); + uow.Commit(); + } + return "更新实体成功"; + } + #endregion + + + + #endregion + + + /// + /// 上传用户信息 + /// + /// + /// + public Response ImportUserInfo(IFormFileCollection formFiles) + { + IFormFile file = formFiles[0]; + //存储文件到服务器 + if (file != null) + { + if (file.FileName.IndexOf(".xls") > 0 || file.FileName.IndexOf(".xlsx") > 0) + { + //数据库导入 + IWorkbook workbook = null; + if (file.FileName.IndexOf(".xlsx") > 0) + { + using (var stream = file.OpenReadStream()) + { + workbook = new XSSFWorkbook(stream);//excel的版本2007 + } + } + else if (file.FileName.IndexOf(".xls") > 0) + { + using (var stream = file.OpenReadStream()) + { + workbook = new HSSFWorkbook(stream);//excel的版本2003 + } + } + + //数据处理 + using (var uow = base.UnitWork.CreateContext()) + { + //获取sheet + ISheet sheet; + sheet = workbook.GetSheetAt(0); + //处理sheet数据 + string res = ""; + if (sheet != null) + { + IRow firstRow = sheet.GetRow(0); + //获取有效数据行数 + int lastRow = sheet.LastRowNum; + int rowCount = 0; + //具体excel数据解析 + for (int i = 1; i <= lastRow; ++i) + { + IRow row = sheet.GetRow(i); + if (row == null || string.IsNullOrEmpty(row.GetCell(0).ToString())) continue; + + SysUser user = new SysUser(); + user.Id = YitIdHelper.NextId(); + user.CreateTime = DateTime.Now; + user.Name = row.GetCell(4).ToString(); + user.CreateId = _auth.GetCurrentUser().User.Id; + user.Account=row.GetCell(5).ToString(); + user.Password = Md5Helper.Encrypt(user.Account, 32).ToLower(); + + if (uow.User.IsAny(u => u.Account == user.Account)) + { + res += "账号" + user.Account + "已存在,"; + } + else + { + user.Secretkey = Md5Helper.Encrypt(CommonHelper.CreateNo(), 16).ToLower(); + if (string.IsNullOrEmpty(user.Password)) + { + user.Password = Md5Helper.Encrypt(DESEncrypt.Encrypt(Md5Helper.Hash(user.Account), user.Secretkey).ToLower(), 32).ToLower(); //如果客户端没提供密码,默认密码同账号 + } + else + { + + user.Password = Md5Helper.Encrypt(DESEncrypt.Encrypt(user.Password, user.Secretkey).ToLower(), 32).ToLower(); + } + uow.User.Insert(user); + + if (!string.IsNullOrEmpty(row.GetCell(7).ToString())) + { + //为用户分配角色 + SysUserRole userrole = new SysUserRole(); + userrole.UserId = user.Id; + userrole.RoleId = Convert.ToInt64(row.GetCell(7).ToString()); + //删除用户相关角色 + uow.SysUserRole.DeleteById(user.Id); + //添加 + uow.SysUserRole.Insert(userrole); + } + + if (!string.IsNullOrEmpty(row.GetCell(2).ToString())) + { + //为用户分配部门 + SysUserOrg userorg = new SysUserOrg(); + userorg.UserId = user.Id; + userorg.OrgId = Convert.ToInt64(row.GetCell(2).ToString()); + userorg.PositionId = 0; + userorg.Level = Convert.ToInt16(row.GetCell(3).ToString()); + //删除用户相关部门 + uow.SysUserOrg.DeleteById(user.Id); + //重新添加本次部门 + uow.SysUserOrg.Insert(userorg); + } + } + } + } + var flag = uow.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "更新成功 "+res : "更新失败" + }; + } + } + else + { + return new Response + { + Result = false, + Message = "上传文件类型错误,请上传Excel文件" + }; + } + } + else + { + return new Response + { + Result = false, + Message = "文件为空" + }; + } + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/WFDelegate/Request/WFDelegateDto.cs b/OpenAuth.App/BaseApp/WFDelegate/Request/WFDelegateDto.cs new file mode 100644 index 0000000..6aced72 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFDelegate/Request/WFDelegateDto.cs @@ -0,0 +1,22 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class WFDelegateDto + { + /// + /// 委托信息 + /// + public WFDelegateRule entity { get; set; } + + /// + /// 模板信息 + /// + public List list { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFDelegate/WFDelegateApp.cs b/OpenAuth.App/BaseApp/WFDelegate/WFDelegateApp.cs new file mode 100644 index 0000000..f689450 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFDelegate/WFDelegateApp.cs @@ -0,0 +1,203 @@ +using Infrastructure; +using OpenAuth.App.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App +{ + public class WFDelegateApp : SqlSugarBaseApp + { + ISqlSugarClient client; + public WFDelegateApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + client = base.Repository.AsSugarClient(); + } + + + #region 获取数据 + /// + /// 获取分页列表 + /// + /// 分页参数 + /// 查询参数 + /// + public async Task>> GetPageList(PageReq pageReq, WFDelegateRule queryParams) + { + RefAsync totalCount = 0; + var userId = _auth.GetUserId(); + var exp = Expressionable.Create() + .AndIF(!string.IsNullOrEmpty(queryParams.ToUserName), t => t.ToUserName.Contains(queryParams.ToUserName)) + .AndIF(queryParams.EnabledMark != null, t => t.EnabledMark == queryParams.EnabledMark) + .AndIF(queryParams.Type != null, t => t.Type == queryParams.Type) + .And(t => t.CreateUserId == userId).ToExpression(); + + var list = await client.Queryable().Where(exp) + .ToPageListAsync(pageReq.page, pageReq.limit, totalCount); + return new PageInfo> + { + Items = list, + Total = totalCount + }; + + } + /// + /// 根据委托人获取委托记录 + /// + /// 0 审核委托 1发起委托 + /// + public Task> GetList(int type = 0) { return null; } + /// + /// 获取关联的模板数据 + /// + /// + public async Task> GetRelationList(string keyValue) + { + return await client.Queryable().Where(a => a.DelegateRuleId == keyValue).ToListAsync(); + } + /// + /// 获取委托信息 + /// + /// + public Task Get(string keyValue) { return null; } + /// + /// 获取我的委托人(发起委托) + /// + /// 流程模板编码 + /// + public async Task> GetMyUserList(string code) + { + var list = new List(); + var userInfo = base._auth.GetCurrentUser().User; + var listTmp = await GetMyUserList(userInfo, code); + var dic = new Dictionary(); + foreach (var item in listTmp) + { + if (!dic.ContainsKey(item.CreateUserId)) + { + dic.Add(item.CreateUserId, true); + list.Add(item.CreateUserId); + } + } + if (list.Count > 0) + { + return await client.Queryable().Where(t => list.Contains(t.Id.ToString())).ToListAsync(); + } + else + { + return new List(); + } + } + + public async Task GetEntity(string keyValue) + { + return await base.Repository.GetByIdAsync(keyValue); + } + #endregion + + #region 提交数据 + /// + /// 删除实体 + /// + /// 主键 + public async Task> DeleteEntity(string keyValue) + { + using (var uwo = UnitWork.CreateContext()) + { + await uwo.WFDelegateRule.DeleteByIdAsync(keyValue); + await uwo.WFDelegateRelation.DeleteAsync(t => t.DelegateRuleId == keyValue); + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + /// + /// 保存实体 + /// + /// 主键 + /// 实体数据 + /// 关联模板主键 + public async Task> SaveEntity(string keyValue, WFDelegateRule wfDelegateRuleEntity, string[] schemeInfoList) + { + using (var uwo = UnitWork.CreateContext()) + { + if (string.IsNullOrEmpty(keyValue)) + { + wfDelegateRuleEntity.Id = Guid.NewGuid().ToString(); + wfDelegateRuleEntity.CreateDate = DateTime.Now; + wfDelegateRuleEntity.EnabledMark = 1; + wfDelegateRuleEntity.CreateUserId = _auth.GetUserId(); + wfDelegateRuleEntity.CreateUserName = _auth.GetUserName(); + + await uwo.WFDelegateRule.InsertAsync(wfDelegateRuleEntity); + } + else + { + wfDelegateRuleEntity.Id = keyValue; + await uwo.WFDelegateRule.UpdateAsync(wfDelegateRuleEntity); + await uwo.WFDelegateRelation.DeleteAsync(t => t.DelegateRuleId == keyValue); + } + + foreach (string schemeInfoId in schemeInfoList) + { + WFDelegateRelation wfDelegateRuleRelationEntity = new WFDelegateRelation(); + wfDelegateRuleRelationEntity.Id = Guid.NewGuid().ToString(); + wfDelegateRuleRelationEntity.DelegateRuleId = wfDelegateRuleEntity.Id; + wfDelegateRuleRelationEntity.SchemeInfoId = schemeInfoId; + await uwo.WFDelegateRelation.InsertAsync(wfDelegateRuleRelationEntity); + } + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + /// + /// 更新委托规则状态信息 + /// + /// 主键 + /// + public async Task> UpdateState(string keyValue, int state) + { + var flag = await base.Repository.UpdateSetColumnsTrueAsync(a => new WFDelegateRule { EnabledMark = state }, a => a.Id == keyValue); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + #endregion + + + public async Task> GetMyUserList(SysUser userInfo, string code) + { + string userId = userInfo.Id.ToString(); + DateTime datetime = DateTime.Now; + + var queryable = client.Queryable() + .LeftJoin((rule, r) => rule.Id == r.DelegateRuleId); + var exp = Expressionable.Create() + .And((rule, r) => rule.ToUserId == userId && rule.Type == 1 && r.SchemeInfoId == code) + .And((rule, r) => rule.BeginDate <= datetime && rule.EndDate >= @datetime) + .ToExpression(); + return await queryable.Where(exp).Select((rule, r) => rule).ToListAsync(); + + } + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/Config/WFDelegate.cs b/OpenAuth.App/BaseApp/WFProcess/Config/WFDelegate.cs new file mode 100644 index 0000000..2e56b1c --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/Config/WFDelegate.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Config +{ + /// + /// 获取等待任务 + /// + /// 流程进程ID + /// 流程单元ID + /// + public delegate Task> GetAwaitTaskListMethod(string processId, string unitId); + /// + /// 获取设置人员 + /// + /// 人员配置信息 + /// 流程发起人 + /// 流程进程实例ID + /// 开始节点 + /// + public delegate Task> GetUserListMethod(List auditorList, WFUserInfo createUser, string processId, WFUnit startNode); + /// + /// 获取系统管理员 + /// + /// + public delegate Task> GetSystemUserListMethod(); + + /// + /// 获取单元上一次的审核人 + /// + /// 流程进程ID + /// 流程单元ID + /// + public delegate Task> GetRreTaskUserListMethod(string processId, string unitId); + + /// + /// 判断会签是否通过 + /// + /// 流程进程ID + /// 流程单元ID + /// + public delegate Task IsCountersignAgreeMethod(string processId, string unitId); + + /// + /// 获取上一个流入节点(不是驳回流入的) + /// + /// 流程进程ID + /// 流程单元ID + /// + public delegate Task GetPrevUnitIdMethod(string processId, string unitId); +} diff --git a/OpenAuth.App/BaseApp/WFProcess/Config/WFEngineConfig.cs b/OpenAuth.App/BaseApp/WFProcess/Config/WFEngineConfig.cs new file mode 100644 index 0000000..0f9cc9c --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/Config/WFEngineConfig.cs @@ -0,0 +1,42 @@ +using OpenAuth.App.Config; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Config +{ + public class WFEngineConfig + { + + /// + /// 运行参数 + /// + public WFParams Params { get; set; } + /// + /// 获取等待任务 + /// + public GetAwaitTaskListMethod GetAwaitTaskList { get; set; } + /// + /// 获取审核人 + /// + public GetUserListMethod GetUserList { get; set; } + /// + /// 获取单元上一次的审核人 + /// + public GetRreTaskUserListMethod GetPrevTaskUserList { get; set; } + /// + /// 获取系统管理员 + /// + public GetSystemUserListMethod GetSystemUserList { get; set; } + /// + /// 判断会签是否通过 + /// + public IsCountersignAgreeMethod IsCountersignAgree { get; set; } + /// + /// 获取上一个流入节点(不是驳回流入的) + /// + public GetPrevUnitIdMethod GetPrevUnitId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/Config/WFParams.cs b/OpenAuth.App/BaseApp/WFProcess/Config/WFParams.cs new file mode 100644 index 0000000..9a6651e --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/Config/WFParams.cs @@ -0,0 +1,83 @@ +using OpenAuth.App.Config; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Config +{ + public class WFParams + { + /// + /// 是否已经有流程实例 + /// + public bool HasInstance { get; set; } + /// + /// 是否是子流程 + /// + public bool IsChild { get; set; } + /// + /// 父流程的发起子流程的节点Id + /// + public string ParentNodeId { get; set; } + /// + /// 父级流程任务主键 + /// + public string ParentTaskId { get; set; } + /// + /// 父级流程实例主键 + /// + public string ParentProcessId { get; set; } + /// + /// 流程模板 + /// + public string Scheme { get; set; } + /// + /// 流程模板名称 + /// + public string SchemeName { get; set; } + /// + /// 流程模板编码 + /// + public string SchemeCode { get; set; } + /// + /// 流程模板主键 + /// + public string SchemeId { get; set; } + /// + /// 流程实例Id + /// + public string ProcessId { get; set; } + /// + /// 流程标题 + /// + public string Title { get; set; } + /// + /// 审核人信息 + /// + public string Auditers { get; set; } + /// + /// 流程发起用户 + /// + public WFUserInfo CreateUser { get; set; } + /// + /// 当前执行用户 + /// + public WFUserInfo CurrentUser { get; set; } + /// + /// 流程状态 0 默认运行状态 1 重新发起 2 运行结束 + /// + public int State { get; set; } + /// + /// 流程是否开始审核 1 是 0 不是 + /// + public int IsStart { get; set; } + /// + /// 下一个节点审核人 + /// + public Dictionary NextUsers { get; set; } + + + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/Config/WFUserInfo.cs b/OpenAuth.App/BaseApp/WFProcess/Config/WFUserInfo.cs new file mode 100644 index 0000000..a8804bf --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/Config/WFUserInfo.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Config +{ + public class WFUserInfo + { + /// + /// ID + /// + public string Id { get; set; } + /// + /// 账号 + /// + public string Account { get; set; } + /// + /// 名称 + /// + public string Name { get; set; } + /// + /// 公司 + /// + public string CompanyId { get; set; } + /// + /// 公司名称 + /// + public string CompanyName { get; set; } + /// + /// 部门 + /// + public string DepartmentId { get; set; } + /// + /// 部门名称 + /// + public string DepartmentName { get; set; } + /// + /// 审核顺序 + /// + public int Sort { get; set; } + /// + /// 是否需要审核 + /// + public bool IsAwait { get; set; } + /// + /// 是否没有审核人 + /// + public bool NotHasUser { get; set; } + /// + /// 上一次审批人是否同意(这边的定义为除了驳回的) + /// + public bool IsAgree { get; set; } + + /// + /// 是否第一次审核 + /// + public bool IsNew { get; set; } + + /// + /// 任务状态 1.激活 2.待激活 3.完成 4.关闭 5.加签状态 6.转移给其他人 + /// + public int State { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/IWFEngine.cs b/OpenAuth.App/BaseApp/WFProcess/IWFEngine.cs new file mode 100644 index 0000000..c376b6c --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/IWFEngine.cs @@ -0,0 +1,59 @@ +using OpenAuth.App.Config; +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public interface IWFEngine + { + /// + /// 开始节点 + /// + WFUnit StartNode { get; } + + /// + /// 流程运行参数 + /// + WFEngineConfig Config { get; } + + + /// + /// 流程发起用户 + /// + WFUserInfo CreateUser { get; } + + + /// + /// 流程配置信息 + /// + WorkFlow.WFScheme WFScheme { get; } + + /// + /// 获取流程单元信息 + /// + /// id + /// 流程单元信息 + WFUnit GetNode(string id); + + /// + /// 获取下一节点集合 + /// + /// 开始节点 + /// 执行动作编码 + /// + List GetNextUnits(string startId, string code = ""); + + /// + /// 获取任务 + /// + /// 开始节点 + /// 执行动作编码 + /// 下一个指定节点 + /// + Task> GetTask(string startId, string code = "", string toUnitId = ""); + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/IWorkFlowMethod.cs b/OpenAuth.App/BaseApp/WFProcess/IWorkFlowMethod.cs new file mode 100644 index 0000000..1ae6dce --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/IWorkFlowMethod.cs @@ -0,0 +1,18 @@ +using ce.autofac.extension; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.WorkFlow +{ + public interface IWorkFlowMethod : IBLL + { + /// + /// 流程绑定方法需要继承的接口 + /// + /// + Task Execute(WfMethodParameter parameter); + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/NodeTypeEnum.cs b/OpenAuth.App/BaseApp/WFProcess/NodeTypeEnum.cs new file mode 100644 index 0000000..2a891ce --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/NodeTypeEnum.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public enum NodeTypeEnum + { + [Description("bpmn:StartEvent")] + startEvent, + [Description("bpmn:EndEvent")] + endEvent, + [Description("bpmn:Task")] + userTask, + [Description("bpmn:ParallelGateway")] + gatewayAnd, + [Description("bpmn:ExclusiveGateway")] + gatewayXor, + [Description("bpmn:InclusiveGateway")] + gatewayInclusive, + [Description("bpmn:SubProcess")] + subprocess, + [Description("bpmn:SequenceFlow")] + myline + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/Request/WFProcessDto.cs b/OpenAuth.App/BaseApp/WFProcess/Request/WFProcessDto.cs new file mode 100644 index 0000000..897ab84 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/Request/WFProcessDto.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class WFProcessDto + { + /// + /// 流程进程实例 + /// + public string ProcessId { get; set; } + /// + /// 流程模板编码 + /// + public string SchemeCode { get; set; } + /// + /// 流程标题 + /// + public string Title { get; set; } + /// + /// 流程实例补充信息(一般开发用) + /// + public string InstanceInfo { get; set; } + /// + /// 流程发起人ID + /// + public string UserId { get; set; } + + /// + /// 流程转移审核人 + /// + public string ToUserId { get; set; } + /// + /// 下一节点审核人 + /// + public Dictionary NextUsers { get; set; } + /// + /// 审批意见 + /// + public string Des { get; set; } + /// + /// 审核操作码 + /// + public string Code { get; set; } + /// + /// 审核操作名称 + /// + public string Name { get; set; } + /// + /// 盖章ID + /// + public string StampImg { get; set; } + /// + /// 盖章密码 + /// + public string StampPassWord { get; set; } + /// + /// 下一个审核节点 + /// + public string NextId { get; set; } + /// + /// 是否是子流程进程1是0不是 + /// + public int IsChild { get; set; } + /// + /// 父流程的发起子流程的节点Id + /// + public string ParentNodeId { get; set; } + /// + /// 流程进程父进程任务主键 + /// + public string ParentTaskId { get; set; } + /// + /// 流程进程父进程主键 + /// + public string ParentProcessId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/Request/WFProcessPointDto.cs b/OpenAuth.App/BaseApp/WFProcess/Request/WFProcessPointDto.cs new file mode 100644 index 0000000..30aedea --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/Request/WFProcessPointDto.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class WFProcessPointDto + { + public List List { get; set; } + } + + public class WFProcessPoint + { + /// + /// 流程节点 + /// + public string UnitId { get; set; } + /// + /// 指派的审核人 + /// + public string UserIds { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/Request/WFProcessSearchDto.cs b/OpenAuth.App/BaseApp/WFProcess/Request/WFProcessSearchDto.cs new file mode 100644 index 0000000..35c1bae --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/Request/WFProcessSearchDto.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class WFProcessSearchDto + { + /// + /// 查询关键字 + /// + public string Keyword { get; set; } + + /// + /// 开始日期 + /// + public DateTime? StartDate { get; set; } + + /// + /// 结束流程 + /// + public DateTime? EndDate { get; set; } + + /// + /// 流程模板编码 + /// + public string Code { get; set; } + + /// + /// 类型 1 完成 2 未完成 3 作废 + /// + public int Type { get; set; } + + /// + /// 案件编号 + /// + public string CaseNo { get; set; } + + /// + /// 案件类型 + /// + public string TypeId { get; set; } + + /// + /// 案件名称 + /// + public string CaseName { get; set; } + + /// + /// 是否退回 + /// + public int? IsDrawback { get; set; } + + /// + /// 是否违法 + /// + public int? IsIllegal { get; set; } + + /// + /// 是否核销 + /// + public int? IsVerification { get; set; } + + /// + /// 案件描述 + /// + public string CaseDescription { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/WFProcess/Response/BPMNWFTaskDto.cs b/OpenAuth.App/BaseApp/WFProcess/Response/BPMNWFTaskDto.cs new file mode 100644 index 0000000..4541e16 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/Response/BPMNWFTaskDto.cs @@ -0,0 +1,48 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Response +{ + public class BPMNWFTaskDto + { + public string FlowContent { get; set; } + public FlowUnit FlowViewer { get; set; } + + public WFTask Task { get; set; } + /// + /// 流程进程 + /// + public WFProcess Process { get; set; } + /// + /// 流程模板信息 + /// + public WFScheme Scheme { get; set; } + /// + /// 审核日志 + /// + public IEnumerable Logs { get; set; } + /// + /// 任务列表 + /// + public IEnumerable Tasks { get; set; } + } + + + public class FlowUnit + { + //完成节点id集合 + public List FinishedTaskSet { get; set; } + // 完成线条节点id集合 + public List FinishedSequenceFlowSet { get; set; } + // 当前节点id集合 + public List UnfinishedTaskSet { get; set; } + // 拒绝节点id集合(暂无示例) + public List RejectedTaskSet { get; set; } + } + + +} diff --git a/OpenAuth.App/BaseApp/WFProcess/WFAuditor.cs b/OpenAuth.App/BaseApp/WFProcess/WFAuditor.cs new file mode 100644 index 0000000..f153b3b --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/WFAuditor.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class WFAuditor + { + /// + /// 设置Id 1.上一级 2.上二级 3.上三级 4.上四级 5.上五级 6.下一级 7.下二级 8.下三级 9.下四级 10.下五级 + /// + public string Id { get; set; } + /// + /// 审核人员类型 1.岗位 2.角色 3.用户 4.上下级 5.节点执行人 6.数据库表字段 7.执行sql + /// + public string Type { get; set; } + /// + /// 名称 + /// + public string Name { get; set; } + /// + /// 条件 1.同一个部门 2.同一个公司 3.发起人上级 4.发起人下级 + /// + public string Condition { get; set; } + + /// + /// 数据库编码 + /// + public string DbCode { get; set; } + /// + /// 对应表 + /// + public string Table { get; set; } + /// + /// 关联字段 + /// + public string Rfield { get; set; } + /// + /// 审核人字段 + /// + public string AuditorField { get; set; } + + public string Sql { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/WFCondition.cs b/OpenAuth.App/BaseApp/WFProcess/WFCondition.cs new file mode 100644 index 0000000..842a0b7 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/WFCondition.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class WFCondition + { + /// + /// 流程条件编码 + /// + public string Code { get; set; } + /// + /// 条件名称 + /// + public string Name { get; set; } + /// + /// 类型 1比较字段 2 sql语句 + /// + public string Type { get; set; } + /// + /// 数据库 + /// + public string DbCode { get; set; } + /// + /// 数据库表 + /// + public string Table { get; set; } + /// + /// 流程关联字段 + /// + public string Rfield { get; set; } + /// + /// 比较字段 + /// + public string Cfield { get; set; } + /// + /// 比较类型 1等于 2不等于 3大于 4大于等于 5小于 6小于等于 7包含 8不包含 9包含于 10不包含于 + /// + public string CompareType { get; set; } + /// + /// 比较值 + /// + public string Value { get; set; } + /// + /// sql语句 + /// + public string Sql { get; set; } + + + + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/WFEngine.cs b/OpenAuth.App/BaseApp/WFProcess/WFEngine.cs new file mode 100644 index 0000000..002b44c --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/WFEngine.cs @@ -0,0 +1,1106 @@ +using Infrastructure; +using Infrastructure.Extensions; +using Newtonsoft.Json; +using OpenAuth.App.Config; +using OpenAuth.Repository.Domain; +using SqlSugar; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class WFEngine : IWFEngine + { + ISqlSugarClient client; + //private RepositoryFactory dbFactory { get; set; } + /// + /// 流程配置信息 + /// + private WFEngineConfig _config { get; set; } + /// + /// 流程模板 + /// + private WorkFlow.WFScheme _wfScheme { get; set; } + /// + /// 流程单元对应字典 + /// + private Dictionary _dicUnit { get; set; } + /// + /// 开始节点 + /// + private WFUnit _startNode { get; set; } + /// + /// 线条集合 + /// + private List _lines { get; set; } + #region 构造函数 + /// + /// 构造方法 + /// + /// 流程参数 + public WFEngine(WFEngineConfig config, ISqlSugarClient sqlSugarClient) + { + // 初始化模板数据 + _config = config; + _wfScheme = ToObject(_config.Params.Scheme); + //_wfScheme = Newtonsoft.Json.JsonConvert.DeserializeObject(_config.Params.Scheme); + //_wfScheme = ExtensionsJson.ToObject(_config.Params.Scheme); + + _dicUnit = new Dictionary(); + _lines = new List(); + + foreach (var unit in _wfScheme.WfData) + { + if (!_dicUnit.ContainsKey(unit.Id)) + { + _dicUnit.Add(unit.Id, unit); + } + else + { + continue; + } + + if (unit.Type == NodeTypeEnum.startEvent.GetDescription()) + { + _startNode = unit; + } + else if (unit.Type == NodeTypeEnum.myline.GetDescription()) + { + _lines.Add(unit); + } + } + client = sqlSugarClient; + //dbFactory = new RepositoryFactory(); + } + #endregion + + public T ToObject(string Json) + { + return (T)((Json == null) ? ((object)default(T)) : ((object)JsonConvert.DeserializeObject(Json))); + } + /// + /// 流程运行参数 + /// + public WFEngineConfig Config => _config; + /// + /// 开始节点 + /// + public WFUnit StartNode => _startNode; + + /// + /// 流程发起用户 + /// + public WFUserInfo CreateUser => _config.Params.CreateUser; + /// + /// 流程发起用户 + /// + public WFUserInfo CurrentUser => _config.Params.CurrentUser; + + /// + /// 流程配置信息 + /// + public WorkFlow.WFScheme WFScheme => _wfScheme; + + /// + /// 获取流程单元信息 + /// + /// id + /// 流程单元信息 + public WFUnit GetNode(string id) + { + if (_dicUnit.ContainsKey(id)) + { + return _dicUnit[id]; + } + else + { + return null; + } + } + + /// + /// 获取下一节点集合 + /// + /// 开始节点 + /// 执行动作编码 + /// + public List GetNextUnits(string startId, string code = "") + { + List nextUnits = new List(); + + // 找到与当前节点相连的线条 + foreach (var line in _lines) + { + if (line.From == startId) + { + // 获取连接到开始节点的线条 + bool isOk = false; + if (string.IsNullOrEmpty(line.LineConditions)) + { + isOk = true; + } + else if (!string.IsNullOrEmpty(code)) + { + var codeList = line.LineConditions.Split(','); + foreach (string _code in codeList) + { + if (_code == code) + { + isOk = true; + break; + } + } + } + else + { //没有执行码就是全部执行 + isOk = true; + } + + + // 获取到流入节点 + if (isOk) + { + if (_dicUnit.ContainsKey(line.To) && nextUnits.Find(t => t.Id == line.To) == null) + { + nextUnits.Add(_dicUnit[line.To]); + } + } + } + } + return nextUnits; + } + /// + /// 获取下一节点集合 + /// + /// 开始节点 + /// 条件编码 + /// + public List GetNextUnits(string startId, List codeList) + { + List nextUnits = new List(); + + // 找到与当前节点相连的线条 + foreach (var line in _lines) + { + if (line.From == startId) + { + // 获取连接到开始节点的线条 + bool isOk = false; + if (codeList.Count > 0 && !string.IsNullOrEmpty(line.LineConditions)) + { + var codeList2 = line.LineConditions.Split(','); + foreach (string _code in codeList2) + { + if (codeList.FindIndex(t => t == _code) != -1) + { + isOk = true; + break; + } + } + } + + // 获取到流入节点 + if (isOk) + { + if (_dicUnit.ContainsKey(line.To) && nextUnits.Find(t => t.Id == line.To) == null) + { + nextUnits.Add(_dicUnit[line.To]); + } + } + } + } + return nextUnits; + } + + /// + /// 获取下一节点集合(流转条件为空的情况) + /// + /// 开始节点 + /// + public List GetNextUnitsNoSet(string startId) + { + List nextUnits = new List(); + + // 找到与当前节点相连的线条 + foreach (var line in _lines) + { + if (line.From == startId) + { + // 获取到流入节点 + if (string.IsNullOrEmpty(line.LineConditions)) + { + if (_dicUnit.ContainsKey(line.To) && nextUnits.Find(t => t.Id == line.To) == null) + { + nextUnits.Add(_dicUnit[line.To]); + } + } + } + } + return nextUnits; + } + /// + /// 获取上一单元ID列表 + /// + /// 当前节点Id + /// + public List GetPreUnitIds(string myUnitId) + { + List list = new List(); + // 找到与当前节点相连的线条 + foreach (var line in _lines) + { + if (line.To == myUnitId && list.Find(t => t == line.From) == null) + { + list.Add(line.From); + } + } + return list; + } + /// + /// 获取任务 + /// + /// 开始节点 + /// 执行动作编码 + /// 下一个指定节点 + /// + public async Task> GetTask(string startId, string code = "", string toUnitId = "") + { + bool isIsReject = code == "disagree"; + var nextUnits = GetNextUnits(startId, code); + + if (!string.IsNullOrEmpty(toUnitId)) + { + nextUnits = nextUnits.FindAll(t => t.Type == "bpmn:ScriptTask");// 只保留脚本节点 + nextUnits.Add(GetNode(toUnitId)); + } + + // 如果无法获取下一个审核任务且是驳回操作,就返回到之前流转过来的任务(除去通过驳回流转过来的)(需要过滤掉脚本节点) + if (nextUnits.FindAll(t => t.Type != "bpmn:ScriptTask").Count == 0 && isIsReject) + { + // 获取当前节点的 + var prevUnitId = await Config.GetPrevUnitId(Config.Params.ProcessId, startId); + if (!string.IsNullOrEmpty(prevUnitId)) + { + nextUnits.Add(GetNode(prevUnitId)); + } + } + + var list = await GetTask(nextUnits, isIsReject, startId); + foreach (var item in list) + { + item.PrevUnitId = startId; + } + return list; + } + + + + /// + /// 获取任务 + /// + /// 下一个节点集合 + /// 是否驳回 + /// 开始节点 + /// + public async Task> GetTask(List nextUnits, bool isReject, string startId) + { + WFUnit startUnit = _dicUnit[startId]; + + if (startUnit.Type == NodeTypeEnum.startEvent.GetDescription() && string.IsNullOrEmpty(startUnit.Name)) + { + startUnit.Name = "开始节点"; + } + + List taskList = new List(); + foreach (var unit in nextUnits) + { + switch (unit.Type) + { + //case "startEvent":// 开始节点 + case "bpmn:StartEvent":// 开始节点 + taskList.Add(GetStartTask(unit, isReject, startId, startUnit.Name)); + break; + //case "gatewayAnd": + case "bpmn:ParallelGateway": + // 并行网关会等待所有分支汇入才往下执行,所有出口分支都会被执行 + // 判断是否所有分支都被执行了 + // 1.或去此节点所有上节点 + // 2.生成一个等待任务 + // 3.获取所有该节点当前等待任务 + // 4.判断是否完成获取下一节点 + var preIdList = GetPreUnitIds(unit.Id); + if (preIdList.Count <= 1) + { + taskList.AddRange(await GetTask(unit.Id)); + } + else + { + var awaitTaskList = await Config.GetAwaitTaskList(Config.Params.ProcessId, unit.Id); + var awaitTaskList2 = awaitTaskList.FindAll(t => t.PrevUnitId != startId); // 排除当前等待任务的所有等待任务 + if (awaitTaskList2.Count + 1 >= preIdList.Count) + { + // 如果所有支路都被执行了就生成一个取消所有等待任务的命令 + taskList.Add(GetDeleteAwaitTask(unit, isReject, startId, startUnit.Name)); + taskList.AddRange(await GetTask(unit.Id)); + } + else + { + taskList.Add(GetAwaitTask(unit, isReject, startId, startUnit.Name)); + } + } + break; + //case "gatewayXor": + case "bpmn:ExclusiveGateway": + // 排他网关不会等待所有分支汇入才往下执行,只要有分支汇入就会往下执行,出口分支只会执行一条(条件为true,如果多条出口分支条件为true也执行一条) + // 1.获取当前节点的true条件,如果成立条件为0,就执行人默认没有条件的线条 + // 2.获取下一个节点 + var conditionCodes = await GetConditionIds(unit.Conditions); + var nextUnits2 = GetNextUnits(unit.Id, conditionCodes); + if (nextUnits2.Count == 0) + { + nextUnits2 = GetNextUnitsNoSet(unit.Id); + } + if (nextUnits2.Count == 0) + { + throw new Exception(string.Format("无法获取下一节点【{0}】", unit.Id)); + } + else + { + var nextUnits3 = new List(); + nextUnits3.Add(nextUnits2[0]); + taskList.AddRange(await GetTask(nextUnits3, isReject, unit.Id)); + } + break; + //case "gatewayInclusive": + case "bpmn:InclusiveGateway": + // 包容网关会等待所有分支汇入才往下执行,出口分支能执行多条(条件为true) + bool isNext = false; + var preIdList2 = GetPreUnitIds(unit.Id); + if (preIdList2.Count <= 1) + { + isNext = true; + } + else + { + + var awaitTaskList = await Config.GetAwaitTaskList(Config.Params.ProcessId, unit.Id); + var awaitTaskList2 = awaitTaskList.FindAll(t => t.PrevUnitId != startId); // 排除当前等待任务的所有等待任务 + if (awaitTaskList2.Count + 1 >= preIdList2.Count) + { + // 如果所有支路都被执行了就生成一个取消所有等待任务的命令 + taskList.Add(GetDeleteAwaitTask(unit, isReject, startId, startUnit.Name)); + isNext = true; + } + else + { + taskList.Add(GetAwaitTask(unit, isReject, startId, startUnit.Name)); + } + } + + if (isNext) + { + var conditionCodes2 = await GetConditionIds(unit.Conditions); + var nextUnits3 = GetNextUnits(unit.Id, conditionCodes2); + nextUnits3.AddRange(GetNextUnitsNoSet(unit.Id)); + taskList.AddRange(await GetTask(nextUnits3, isReject, unit.Id)); + } + break; + //case "userTask":// 审批节点 + case "bpmn:Task":// 审批节点 + // 1.获取节点上一次的请求人 + var preAuditUsers = await Config.GetPrevTaskUserList(Config.Params.ProcessId, unit.Id); + if (preAuditUsers.FindIndex(t => t.State == 1) != -1) + { + // 如果此节点被激活不需要审核 + break; + } + + + var auditUsers = new List(); + if (preAuditUsers.Count == 0) + { + // 表示此节点未被处理过 + // 获取审核人 + if (Config.Params.NextUsers != null && Config.Params.NextUsers.ContainsKey(unit.Id)) + { + var auditUserList = new List(); + var strAuditUser = Config.Params.NextUsers[unit.Id]; + var strAuditUserList = strAuditUser.Split(","); + foreach (var id in strAuditUserList) + { + auditUserList.Add(new WFAuditor() + { + Type = "3", + Id = id + }); + } + + auditUsers = await Config.GetUserList(auditUserList, CreateUser, Config.Params.ProcessId, _startNode); + } + else + { + auditUsers = await Config.GetUserList(unit.AuditUsers, CreateUser, Config.Params.ProcessId, _startNode); + } + + // 添加传阅任务,节点第一次执行的时候触发 + var lookUsers = await Config.GetUserList(unit.LookUsers, CreateUser, Config.Params.ProcessId, _startNode); + taskList.AddRange(GetLookUserTaskList(unit, lookUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString())); + } + else + { + // 添加一条任务用于更新之前任务状态(将之前的任务设置成不是最近的一次任务) + taskList.Add(GetUpdateTask(unit)); + } + + // 表示找不到审核人 + if (preAuditUsers.Count == 0 && auditUsers.Count == 0) + { + switch (unit.NoAuditor) + { + case "1": + taskList.AddRange(GetUserTaskList(unit, await Config.GetSystemUserList(), isReject, startId, startUnit.Name, Guid.NewGuid().ToString())); + break; + case "2": + // 流转到下一个节点 + taskList.Add(GetSkipTask(unit, isReject, startId, startUnit.Name)); + taskList.AddRange(await GetTask(unit.Id)); + break; + case "3": + throw new Exception(string.Format("【{0}{1}】找不到审核人,无法提交", unit.Name, unit.Id)); + } + } + + // 1.需要先判断是否是会签 + if (unit.IsCountersign) + { + // 之前有人处理过 + if (preAuditUsers.Count > 0) + { + // 驳回处理,重新开启审核 + if (isReject) + { + taskList.AddRange(GetCountersignTask(unit, preAuditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString(), unit.CountersignType)); + } + else + // 1.判断之前的会签策略是否通过 + if (await Config.IsCountersignAgree(Config.Params.ProcessId, unit.Id)) + { + // 判断自动同意规则,会签状态下只有3有效 + if (unit.AutoAgree.IndexOf("3") != -1) + { + taskList.AddRange(await GetTask(unit.Id));// 自动审核,流转到下一节点 + } + else + { + taskList.AddRange(GetCountersignTask(unit, preAuditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString(), unit.CountersignType)); + } + } + else + { + taskList.AddRange(GetCountersignTask(unit, preAuditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString(), unit.CountersignType, unit.CountersignAgian)); + } + } + // 第一次处理 + else + { + taskList.AddRange(GetCountersignTask(unit, auditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString(), unit.CountersignType)); + } + } + else + { + // 之前有人处理过 + if (preAuditUsers.Count > 0) + { + if (IsAtuoAgree(preAuditUsers, unit.AutoAgree.Split(','), isReject)) + { + taskList.AddRange(await GetTask(unit.Id, "agree")); + } + else + { + // 判断是否有完成任务的人 + if (preAuditUsers.FindIndex(t => t.State == 3) != -1) + { + taskList.AddRange(GetUserTaskList(unit, preAuditUsers.FindAll(t => t.State == 3), isReject, startId, startUnit.Name, Guid.NewGuid().ToString())); + } + else + { + taskList.AddRange(GetUserTaskList(unit, preAuditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString())); + } + } + } + else + { + if (IsAtuoAgree(auditUsers, unit.AutoAgree.Split(','), isReject)) + { + taskList.Add(GetAutoSkipTask(unit, isReject, startId, startUnit.Name));// 作为日志记录 + taskList.AddRange(await GetTask(unit.Id, "agree")); + } + else + { + taskList.AddRange(GetUserTaskList(unit, auditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString())); + } + } + } + break; + case "bpmn:ScriptTask":// 脚本节点 + taskList.Add(GetScriptTaskList(unit, isReject, startId, startUnit.Name, Guid.NewGuid().ToString())); + taskList.AddRange(await GetTask(unit.Id)); + break; + //case "subprocess":// 暂时不支持 + case "bpmn:SubProcess": + taskList.Add(GetSubprocessTask(unit, startId, startUnit.Name)); + break; + //case "endEvent":// 结束节点 + case "bpmn:EndEvent":// 结束节点 + taskList.Add(GetEndTask(unit, startId, startUnit.Name)); + break; + } + } + + return taskList; + } + + + #region 私有方法 + /// + /// 获取开始任务 + /// + /// + /// + /// + /// + /// + private WorkFlow.WFTask GetStartTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = "重新创建", + Token = Guid.NewGuid().ToString(), + Type = 4, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + IsReject = IsReject, + MessageType = unit.MessageType, + User = _config.Params.CreateUser + }; + return task; + } + + private WorkFlow.WFTask GetEndTask(WFUnit unit, string preUnitId, string preUnitName) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = "流程结束", + Token = Guid.NewGuid().ToString(), + Type = 100, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + }; + return task; + } + /// + /// 获取一个等待任务 + /// + /// + /// + /// + /// + /// + private WorkFlow.WFTask GetAwaitTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = "等待其它支路完成", + Type = 21, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + IsReject = IsReject + }; + + return task; + } + + /// + /// 获取一个更新任务 + /// + /// + /// + private WorkFlow.WFTask GetUpdateTask(WFUnit unit) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Type = 26, + }; + + return task; + } + + /// + /// 获取一个找不到审核人直接跳过任务 + /// + /// + /// + /// + /// + /// + private WorkFlow.WFTask GetSkipTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = "当前任务找不到审核人直接跳过", + Type = 23, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + IsReject = IsReject + }; + + return task; + } + + /// + /// 获取一个找不到审核人直接跳过任务 + /// + /// + /// + /// + /// + /// + private WorkFlow.WFTask GetAutoSkipTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = "自动审核规则跳过", + Type = 24, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + IsReject = IsReject + }; + + return task; + } + + + /// + /// 获取一个取消等待任务 + /// + /// + /// + /// + /// + /// + private WorkFlow.WFTask GetDeleteAwaitTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = "取消等待任务", + Type = 22, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + IsReject = IsReject + }; + + return task; + } + /// + /// 获取审批任务 + /// + /// + /// + /// + /// + /// + /// + /// + private List GetUserTaskList(WFUnit unit, List userList, bool isReject, string preUnitId, string preUnitName, string token) + { + List list = new List(); + int type = 1; + if (unit!=null&&unit.IsSingleTask) + { + type = 7; + } + foreach (var user in userList) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = unit.Name, + Type = type, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + IsReject = isReject, + Token = token, + MessageType = unit.MessageType, + + // 超时设置 + IsOvertimeMessage = unit.IsOvertimeMessage, + OvertimeMessageStart = unit.OvertimeMessageStart, + OvertimeMessageInterval = unit.OvertimeMessageInterval, + OvertimeGo = unit.OvertimeGo, + OvertimeMessageType = unit.OvertimeMessageType, + + IsBatchAudit = unit.IsBatchAudit, + // 处理人 + User = user + + }; + if (string.IsNullOrEmpty(task.Name)) + { + task.Name = "审核处理"; + } + + list.Add(task); + } + + + return list; + } + + + /// + /// 获取传阅任务 + /// + /// + /// + /// + /// + /// + /// + /// + private List GetLookUserTaskList(WFUnit unit, List userList, bool isReject, string preUnitId, string preUnitName, string token) + { + List list = new List(); + foreach (var user in userList) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = unit.Name, + Type = 2, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + IsReject = isReject, + Token = token, + MessageType = unit.MessageType, + + // 处理人 + User = user + + }; + if (string.IsNullOrEmpty(task.Name)) + { + task.Name = "查看"; + } + + list.Add(task); + } + + + return list; + } + + /// + /// 获取会签审批任务 + /// + /// + /// + /// + /// + /// + /// + /// 审核方式 1.并行 2.串行 + /// 再次审核 1.已同意不需要审核 2.已同意需要审核 + /// + private List GetCountersignTask(WFUnit unit, List userList, bool isReject, string preUnitId, string preUnitName, string token, string countersignType, string countersignAgian = "2") + { + List list = new List(); + int num = 1; + foreach (var user in userList) + { + if (countersignAgian == "1" && user.IsAgree) + { + continue; + } + + user.IsAwait = countersignType == "1" ? false : true; + user.Sort = num; + if (num == 1) + { + user.IsAwait = false; + } + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = unit.Name, + Type = 5, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + IsReject = isReject, + Token = token, + MessageType = unit.MessageType, + + // 超时设置 + IsOvertimeMessage = unit.IsOvertimeMessage, + OvertimeMessageStart = unit.OvertimeMessageStart, + OvertimeMessageInterval = unit.OvertimeMessageInterval, + OvertimeGo = unit.OvertimeGo, + OvertimeMessageType = unit.OvertimeMessageType, + + IsBatchAudit = unit.IsBatchAudit, + // 处理人 + User = user, + + + }; + if (string.IsNullOrEmpty(task.Name)) + { + task.Name = "审核处理"; + } + + list.Add(task); + + num++; + } + + + return list; + } + + /// + /// 获取脚本执行任务 + /// + /// + /// + /// + /// + /// + /// + private WorkFlow.WFTask GetScriptTaskList(WFUnit unit, bool isReject, string preUnitId, string preUnitName, string token) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + UnitId = unit.Id, + Name = unit.Name, + Type = 10, + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + IsReject = isReject, + Token = token, + + ExecuteType = unit.ExecuteType, + SqlDb = unit.SqlDb, + SqlStr = unit.SqlStr, + SqlStrRevoke = unit.SqlStrRevoke, + ApiUrl = unit.ApiUrl, + ApiUrlRevoke = unit.ApiUrlRevoke, + Ioc = unit.Ioc, + IocRevoke = unit.IocRevoke, + + + }; + if (string.IsNullOrEmpty(task.Name)) + { + task.Name = "脚本执行"; + } + + + return task; + } + + + /// + /// 获取成立的条件ID + /// + /// 条件列表 + /// + private async Task> GetConditionIds(List conditions) + { + List list = new List(); + foreach (var condition in conditions) + { + //获取数据id + var process = await client.Queryable().FirstAsync(a => a.Id == _config.Params.ProcessId); + WFInstanceInfo instanceInfo = null; + if (process != null) + { + // instanceInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(process.InstanceInfo); + instanceInfo = process.InstanceInfo; + } + + if (condition.Type == "1")// 字段比较 + { + string sql = string.Format("select \"{0}\" from \"{1}\" where \"{2}\" = @processId ", condition.Cfield, condition.Table, condition.Rfield, condition.Rfield); + //var dt = await dbFactory.BaseRepository(condition.DbCode).FindTable(sql, new { processId = _config.Params.ProcessId }); + var pars = client.Ado.GetParameters(new { processId = instanceInfo.pkeyValue }); + var dt = await client.Ado.GetDataTableAsync(sql, pars); + if (dt.Rows.Count > 0) + { + var value = dt.Rows[0][condition.Cfield.ToLower()].ToString(); + + switch (condition.CompareType) + { + case "1": + if (value == condition.Value) + { + list.Add(condition.Code); + } + break; + case "2": + if (value != condition.Value) + { + list.Add(condition.Code); + } + break; + case "3": + if (Convert.ToDecimal(value) > Convert.ToDecimal(condition.Value)) + { + list.Add(condition.Code); + } + break; + case "4": + if (Convert.ToDecimal(value) >= Convert.ToDecimal(condition.Value)) + { + list.Add(condition.Code); + } + break; + case "5": + if (Convert.ToDecimal(value) < Convert.ToDecimal(condition.Value)) + { + list.Add(condition.Code); + } + break; + case "6": + if (Convert.ToDecimal(value) <= Convert.ToDecimal(condition.Value)) + { + list.Add(condition.Code); + } + break; + case "7": + if (value.IndexOf(condition.Value) != -1) + { + list.Add(condition.Code); + } + break; + case "8": + if (value.IndexOf(condition.Value) == -1) + { + list.Add(condition.Code); + } + break; + case "9": + if (condition.Value.IndexOf(value) != -1) + { + list.Add(condition.Code); + } + break; + case "10": + if (condition.Value.IndexOf(value) == -1) + { + list.Add(condition.Code); + } + break; + } + } + + } + else + {// sql语句 + //var dt = await dbFactory.BaseRepository(condition.DbCode).FindTable(condition.Sql, new { processId = _config.Params.ProcessId, userId = CreateUser.Id, userAccount = CreateUser.Account, companyId = CreateUser.CompanyId, departmentId = CreateUser.DepartmentId }); + //var pars = client.Ado.GetParameters(new { processId = _config.Params.ProcessId, userId = CreateUser.Id, userAccount = CreateUser.Account, companyId = CreateUser.CompanyId, departmentId = CreateUser.DepartmentId }); + var pars = client.Ado.GetParameters(new { processId = instanceInfo.pkeyValue, userId = CreateUser.Id, userAccount = CreateUser.Account, companyId = CreateUser.CompanyId, departmentId = CreateUser.DepartmentId }); + var dt = await client.Ado.GetDataTableAsync(condition.Sql, pars); + + if (dt.Rows.Count > 0) + { + list.Add(condition.Code); + } + } + } + + return list; + } + /// + /// 判断是否自动同意 + /// + /// 审核处理人 + /// 自动同意策略1.处理人就是提交人 2.处理人和上一步的处理人相同 3.处理人审批过 + /// 是否是驳回 + /// + private bool IsAtuoAgree(List auditUsers, string[] atuoAgrees, bool isReject) + { + if (isReject) + { + return false; + } + + bool res = false; + if (auditUsers.Count == 0 || atuoAgrees.Length == 0) + { + return res; + } + + foreach (var item in atuoAgrees) + { + switch (item) + { + case "1": + if (auditUsers.FindIndex(t => t.Id == CreateUser.Id) != -1) + { + res = true; + } + break; + case "2": + if (auditUsers.FindIndex(t => t.Id == CurrentUser.Id) != -1) + { + res = true; + } + break; + case "3": + if (auditUsers.FindIndex(t => t.IsAgree) != -1 && !isReject) + { + res = true; + } + break; + } + } + return res; + } + + + /// + /// 获取子流程任务 + /// + /// + /// + /// + /// + private WorkFlow.WFTask GetSubprocessTask(WFUnit unit, string preUnitId, string preUnitName) + { + WorkFlow.WFTask task = new WorkFlow.WFTask() + { + Type = 3, + UnitId = unit.Id, + Name = "子流程", + Token = Guid.NewGuid().ToString(), + PrevUnitId = preUnitId, + PrevUnitName = preUnitName, + ChildSchemeInfoId = unit.WfschemeId, + User = _config.Params.CreateUser + }; + return task; + } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/WFProcessApp.cs b/OpenAuth.App/BaseApp/WFProcess/WFProcessApp.cs new file mode 100644 index 0000000..e0e2253 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/WFProcessApp.cs @@ -0,0 +1,3161 @@ +using ce.autofac.extension; +using Infrastructure; +using Infrastructure.Extensions; +using Infrastructure.Helpers; +using Microsoft.Extensions.Configuration; +using OpenAuth.App.Base; +using OpenAuth.App.BasicQueryService; +using OpenAuth.App.Config; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.Repository; +using OpenAuth.Repository.Core; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System.Data; +using System.Linq; +using Newtonsoft.Json; +using OpenAuth.App.BaseApp.Jobs; +using System.Text; +using DocumentFormat.OpenXml.Spreadsheet; +using Infrastructure.Utilities; +using OpenAuth.App.BaseApp.Base; +using System.Diagnostics; +using NPOI.Util; + +namespace OpenAuth.App +{ + public partial class WFProcessApp : SqlSugarBaseApp + { + ISqlSugarClient client; + UserManager userManager; + PositionManager positionManager; + IConfiguration _configuration; + OpenJobApp _job; + public WFProcessApp(SqlSugar.ISugarUnitOfWork unitWork, + SqlSugar.ISimpleClient repository, + IAuth auth, + UserManager userManager, + OpenJobApp job, + PositionManager positionManager, + IConfiguration _configuration + ) : base(unitWork, repository, auth) + { + client = base.Repository.AsSugarClient(); + this.userManager = userManager; + this.positionManager = positionManager; + this._configuration = _configuration; + _job = job; + } + + #region 获取数据 + /// + /// 获取流程列表 + /// + /// 分页参数 + /// 查询参数 + /// + public async Task>> GetPageList(PageReq pageReq, WFProcessSearchDto searchParams) + { + RefAsync totalCount = 0; + + var exp = Expressionable.Create() + .AndIF(!string.IsNullOrEmpty(searchParams.Keyword), t => t.Title.Contains(searchParams.Keyword) || t.SchemeName.Contains(searchParams.Keyword)) + .AndIF(!string.IsNullOrEmpty(searchParams.Code), t => t.SchemeCode == searchParams.Code) + .AndIF(searchParams.StartDate != null && searchParams.EndDate != null, t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate); + + if (searchParams.Type == 3) + { + exp = exp.And(t => t.EnabledMark == 3); + } + else + { + exp = exp.And(t => t.EnabledMark == 1); + + if (searchParams.Type == 1) + { + exp = exp.And(t => t.IsFinished == 1); + } + else + { + exp = exp.And(t => t.IsFinished == 0); + } + } + + var list = await client.Queryable() + .Where(exp.ToExpression()) + .OrderByDescending(t => t.CreateDate) + .ToPageListAsync(pageReq.page, pageReq.limit, totalCount); + + return new PageInfo> + { + Items = list, + Total = totalCount + }; + } + /// + /// 获取我的流程 + /// + /// 分页参数 + /// 查询参数 + /// 1正常2草稿3作废 + /// + public async Task>> GetMyPageList(PageReq pageReq, WFProcessSearchDto searchParams, int type) + { + RefAsync totalCount = 0; + + var userId = _auth.GetUserId(); + var expression = Expressionable.Create(); + expression = expression.And(t => t.CreateUserId == userId || t.UserId == userId); + + if (type == 2) + { + expression = expression.And(t => t.EnabledMark == 2); + } + else + { + expression = expression.And(t => t.EnabledMark != 2); + } + + if (!string.IsNullOrEmpty(searchParams.Keyword)) + { + expression = expression.And(t => t.Title.Contains(searchParams.Keyword) || t.SchemeName.Contains(searchParams.Keyword)); + } + if (!string.IsNullOrEmpty(searchParams.Code)) + { + expression = expression.And(t => t.SchemeCode == searchParams.Code); + } + if (searchParams.StartDate != null && searchParams.EndDate != null) + { + expression = expression.And(t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate); + } + + var list = await client.Queryable() + .Where(expression.ToExpression()) + .OrderByDescending(t => t.CreateDate) + .ToPageListAsync(pageReq.page, pageReq.limit, totalCount); + + return new PageInfo> + { + Items = list, + Total = totalCount + }; + } + /// + /// 获取流程进程实体 + /// + /// 主键 + /// + public async Task GetEntity(string keyValue) + { + return await base.Repository.GetByIdAsync(keyValue); + } + #endregion + + #region 保存更新删除 + /// + /// 删除流程进程实体 + /// + /// 流程进程主键 + public async Task DeleteEntity(string processId) + { + return await base.Repository.DeleteByIdAsync(processId); + } + #endregion + + #region 流程API + /// + /// 保存草稿 + /// + /// 流程进程主键 + /// 流程模板编码 + /// 创建人 + /// 父级流程进程主键 + /// 父级流程节点Id + /// 父级任务id + /// 是否为子流程 + /// 流程标题 + /// + public async Task> SaveDraft(string processId, string schemeCode, string userId, string instanceInfo, string parentProcessId, string parentNodeId, string parentTaskId, int isChild, string title = "") + { + var flag = false; + + var currentUser = _auth.GetCurrentUser().User; + + // 判断当前流程进程是否有保存过 + var processEntity = await GetEntity(processId); + if (processEntity == null) + { + // 创建草稿,已经存在不做处理 + var schemeInfo = await client.Queryable().FirstAsync(a => a.Code == schemeCode); + WFProcess wfProcessEntity = new WFProcess() + { + Id = processId, + SchemeCode = schemeCode, + SchemeId = schemeInfo.SchemeId, + SchemeName = schemeInfo.Name, + Title = title, + InstanceInfo = JsonConvert.DeserializeObject(instanceInfo), + EnabledMark = 2, + IsAgain = 0, + IsFinished = 0, + IsChild = isChild, + IsStart = 0, + ParentNodeId = parentNodeId, + ParentProcessId = parentProcessId, + ParentTaskId = parentTaskId, + CreateUserId = currentUser.Id.ToString(), + CreateUserName = currentUser.Name, + CreateUserAccount = currentUser.Account, + UserId = currentUser.Id.ToString() + }; + + if (string.IsNullOrEmpty(title)) + { + wfProcessEntity.Title = currentUser.Name + "-" + schemeInfo.Name; + } + + wfProcessEntity.CreateDate = DateTime.Now; + wfProcessEntity.UserId = currentUser.Id.ToString(); + flag = await base.Repository.InsertAsync(wfProcessEntity); + } + else if (!string.IsNullOrEmpty(title) && processEntity.Title != title) + { + processEntity.Title = title; + flag = await base.Repository.UpdateAsync(processEntity); + } + else + { + flag = true; + } + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + /// + /// 保存草稿-新版用户查询 + /// + /// 流程进程主键 + /// 流程模板编码 + /// 创建人 + /// 父级流程进程主键 + /// 父级流程节点Id + /// 父级任务id + /// 是否为子流程 + /// 流程标题 + /// + public async Task> SaveDraftWithUser(string processId, string schemeCode, string userName, string instanceInfo, string parentProcessId, string parentNodeId, string parentTaskId, int isChild, string title = "") + { + var flag = false; + var currentUser = await client.Queryable().FirstAsync(r => r.Name == userName) + ?? new SysUser + { + Id = -1, + Account = Define.SYSTEM_USERNAME, + Name = "超级管理员", + }; + + // 判断当前流程进程是否有保存过 + var processEntity = await GetEntity(processId); + if (processEntity == null) + { + // 创建草稿,已经存在不做处理 + var schemeInfo = await client.Queryable().FirstAsync(a => a.Code == schemeCode); + WFProcess wfProcessEntity = new WFProcess() + { + Id = processId, + SchemeCode = schemeCode, + SchemeId = schemeInfo.SchemeId, + SchemeName = schemeInfo.Name, + Title = title, + InstanceInfo = JsonConvert.DeserializeObject(instanceInfo), + EnabledMark = 2, + IsAgain = 0, + IsFinished = 0, + IsChild = isChild, + IsStart = 0, + ParentNodeId = parentNodeId, + ParentProcessId = parentProcessId, + ParentTaskId = parentTaskId, + CreateUserId = currentUser?.Id.ToString(), + CreateUserName = currentUser?.Name, + CreateUserAccount = currentUser?.Account, + UserId = currentUser?.Id.ToString() + }; + + if (string.IsNullOrEmpty(title)) + { + wfProcessEntity.Title = currentUser.Name + "-" + schemeInfo.Name; + } + + wfProcessEntity.CreateDate = DateTime.Now; + wfProcessEntity.UserId = currentUser.Id.ToString(); + flag = await base.Repository.InsertAsync(wfProcessEntity); + } + else if (!string.IsNullOrEmpty(title) && processEntity.Title != title) + { + processEntity.Title = title; + flag = await base.Repository.UpdateAsync(processEntity); + } + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 删除草稿 + /// + /// 流程进程主键 + public async Task> DeleteDraft(string processId) + { + var flag = false; + var response = new Response(); + + var iWFEngine = await Bootstraper(string.Empty, processId, null); + + var scriptResult = await ExecuteScript(processId, "deleteDraft", iWFEngine.CreateUser, + iWFEngine.WFScheme.DeleteDraftType, + iWFEngine.WFScheme.DeleteDraftDbCode, + iWFEngine.WFScheme.DeleteDraftDbSQL, + iWFEngine.WFScheme.DeleteDraftUrl, + iWFEngine.WFScheme.DeleteDraftIOCName); + + if (scriptResult) + { + flag = await DeleteEntity(processId); + if (flag) + { + response.Result = true; + response.Message = "success"; + } + else + { + response.Result = false; + response.Message = "脚本执行成功,但流程信息删除失败"; + } + } + else + { + response.Result = false; + response.Message = "error"; + } + return response; + } + /// + /// 创建流程 + /// + /// 流程进程主键 + /// 流程模板编码 + /// 创建人 + /// 下一个节点审核人 + /// 流程标题 + /// + public async Task> Create(string processId, string schemeCode, string userId, Dictionary nextUsers, string InstanceInfo, string title = "") + { + var flag = false; + var userInfo = await GetUserInfo(userId); + var iWFEngine = await Bootstraper(schemeCode, processId, userInfo, nextUsers); + // 下一部需要执行的任务 + var taskList = await iWFEngine.GetTask(iWFEngine.StartNode.Id); + //获取当前流程信息 + var process = await GetEntity(processId); + // 处理任务并更新数据 + List myTaskList; + + using (var uwo = UnitWork.CreateContext()) + { + + var processEntity = GetWFProcessEntity(iWFEngine.Config.Params, title); + processEntity.InstanceInfo = JsonConvert.DeserializeObject(InstanceInfo); + if (string.IsNullOrEmpty(processEntity.Title)) + { + processEntity.Title = userInfo.Name + "-" + processEntity.SchemeName; + } + processEntity.CreateDate = DateTime.Now; + + if (taskList.FindIndex(t => t.Type == 100) != -1) + { + processEntity.IsFinished = 1; + if (process != null && process.IsChild == 1) + { + WFTask ts = new WFTask(); + await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, "", ts, ""); + } + } + + if (process != null && process.IsChild == 1) + { + var taskEntity = await client.Queryable().Where(a => a.Id == process.ParentTaskId).FirstAsync(); + if (taskEntity != null) + { + taskEntity.State = 3; + if (taskEntity.Type == 7) + { + var currentUser = _auth.GetCurrentUser().User; + taskEntity.UserId = currentUser.Id.ToString(); + taskEntity.UserName = currentUser.Name; + } + await uwo.WFTask.UpdateAsync(taskEntity); + } + } + + if (!string.IsNullOrEmpty(schemeCode)) + { + await uwo.WFProcess.InsertAsync(processEntity); + } + else + { + await uwo.WFProcess.UpdateAsync(processEntity); + } + + myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, "create", "create"); + foreach (var item in myTaskList) + { + if (item.Type == 7) + { + await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); + } + item.ProcessTitle = processEntity.Title; + await Add(item); + } + + WFTaskLog wfTaskLogEntity = new WFTaskLog() + { + OperationCode = "create", + OperationName = "提交流程", + TaskType = 0, + IsLast = 1, + Des = "提交流程", + ProcessId = processId, + UnitId = iWFEngine.StartNode.Id, + UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name + }; + await AddLog(wfTaskLogEntity); + + flag = uwo.Commit(); + } + + var respone = new Response(); + + if (flag) + { + var scriptResults = new List(); + // 脚本执行 + var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); + foreach (var item in scriptTaskList) + { + var result = await ExecuteScript(item, "create", processId, "", "",iWFEngine.CreateUser, iWFEngine, null,""); + scriptResults.Add(result); + } + + if (scriptResults.Contains(false)) + { + respone.Result = false; + respone.Message = "流程信息存储成功,但脚本执行失败"; + } + else + { + respone.Result = true; + respone.Message = "success"; + } + } + else + { + respone.Result = false; + respone.Message = "error"; + } + return respone; + } + /// + /// 创建流程 + /// + /// 流程进程主键 + /// 流程模板编码 + /// 创建人 + /// 下一个节点审核人 + /// 流程标题 + /// + public async Task> CreateWithUser(string processId, string schemeCode, string userName, Dictionary nextUsers, string InstanceInfo, string title = "") + { + var flag = false; + //var userInfo = await client.Queryable().FirstAsync(r => r.Name == userName); + var userInfo = await client.Queryable().FirstAsync(r => r.Name == userName) + ?? new SysUser + { + Id = -1, + Account = Define.SYSTEM_USERNAME, + Name = "超级管理员", + }; + var iWFEngine = await BootstraperWithUser(schemeCode, processId, userInfo, nextUsers); + // 下一部需要执行的任务 + var taskList = await iWFEngine.GetTask(iWFEngine.StartNode.Id); + //获取当前流程信息 + var process = await GetEntity(processId); + // 处理任务并更新数据 + List myTaskList; + + using (var uwo = UnitWork.CreateContext()) + { + + var processEntity = GetWFProcessEntity(iWFEngine.Config.Params, title); + processEntity.InstanceInfo = JsonConvert.DeserializeObject(InstanceInfo); + if (string.IsNullOrEmpty(processEntity.Title)) + { + processEntity.Title = userInfo.Name + "-" + processEntity.SchemeName; + } + processEntity.CreateDate = DateTime.Now; + + if (taskList.FindIndex(t => t.Type == 100) != -1) + { + processEntity.IsFinished = 1; + if (process != null && process.IsChild == 1) + { + WFTask ts = new WFTask(); + await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, "", ts, ""); + } + } + + if (process != null && process.IsChild == 1) + { + var taskEntity = await client.Queryable().Where(a => a.Id == process.ParentTaskId).FirstAsync(); + if (taskEntity != null) + { + taskEntity.State = 3; + if (taskEntity.Type == 7) + { + var currentUser = _auth.GetCurrentUser().User; + taskEntity.UserId = currentUser.Id.ToString(); + taskEntity.UserName = currentUser.Name; + } + await uwo.WFTask.UpdateAsync(taskEntity); + } + } + + if (!string.IsNullOrEmpty(schemeCode)) + { + await uwo.WFProcess.InsertAsync(processEntity); + } + else + { + await uwo.WFProcess.UpdateAsync(processEntity); + } + + myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, "create", "create"); + foreach (var item in myTaskList) + { + if (item.Type == 7) + { + await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); + } + item.ProcessTitle = processEntity.Title; + await Add(item); + } + + WFTaskLog wfTaskLogEntity = new WFTaskLog() + { + OperationCode = "create", + OperationName = "提交流程", + TaskType = 0, + IsLast = 1, + Des = "提交流程", + ProcessId = processId, + UnitId = iWFEngine.StartNode.Id, + UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name + }; + await AddLog(wfTaskLogEntity); + + flag = uwo.Commit(); + } + + var respone = new Response(); + + if (flag) + { + var scriptResults = new List(); + // 脚本执行 + var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); + foreach (var item in scriptTaskList) + { + var result = await ExecuteScript(item, "create", processId, "", "",iWFEngine.CreateUser, iWFEngine, null, ""); + scriptResults.Add(result); + } + + if (scriptResults.Contains(false)) + { + respone.Result = false; + respone.Message = "流程信息存储成功,但脚本执行失败"; + } + else + { + respone.Result = true; + respone.Message = "success"; + } + } + else + { + respone.Result = false; + respone.Message = "error"; + } + return respone; + } + + /// + /// 重新创建流程 + /// + /// 流程实例主键 + /// 备注 + /// + public async Task> CreateAgain(string processId, string des) + { + var flag = false; + + var iWFEngine = await Bootstraper("", processId, null, null); + + var unList = (List)await GetUnFinishTaskList(processId); + var taskEntity = unList.Find(t => t.State == 1 && t.UnitId == iWFEngine.StartNode.Id); + + if (taskEntity == null) + { + throw (new Exception("找不到重新提交流程任务!")); + } + + // 下一部需要执行的任务 + var taskList = await iWFEngine.GetTask(iWFEngine.StartNode.Id); + + // 处理任务并更新数据 + + List myTaskList; + + using (var uwo = UnitWork.CreateContext()) + { + await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess() { IsCancel = 1, IsAgain = 0 }, a => a.Id == processId); + await uwo.WFTask.UpdateSetColumnsTrueAsync(a => new WFTask() { State = 3 }, a => a.Id == taskEntity.Id); + // 更新上一个流转过来的任务,提示他无法被撤销 + await CloseTaskLogCancel(taskEntity.ProcessId, taskEntity.PrevTaskId); + + myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, taskEntity.Token, taskEntity.Id); + foreach (var item in myTaskList) + { + if (item.Type == 7) + { + await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); + } + await Add(item); + } + + await CreateTaskLog(taskEntity, "", "重新提交", des, ""); + + //await _imMsgIBLL.VirtualDeleteByContentId(taskEntity.Token); // 更新消息 + + flag = uwo.Commit(); + } + + + var respone = new Response(); + + if (flag) + { + var scriptResults = new List(); + // 脚本执行 + var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); + foreach (var item in scriptTaskList) + { + var result = await ExecuteScript(item, "createAgain", processId, "", "",iWFEngine.CreateUser, iWFEngine, null, ""); + scriptResults.Add(result); + } + + if (scriptResults.Contains(false)) + { + respone.Result = false; + respone.Message = "流程信息存储成功,但脚本执行失败"; + } + else + { + respone.Result = true; + respone.Message = "success"; + } + } + else + { + respone.Result = false; + respone.Message = "error"; + } + return respone; + } + + /// + /// 撤销流程(只有在该流程未被处理的情况下) + /// + /// 流程进程主键 + public async Task RevokeFlow(string processId) + { + var iWFEngine = await Bootstraper(string.Empty, processId, null, null); + + if (iWFEngine.Config.Params.IsStart != 1) + { + // 获取脚本任务 + var scriptList = (List)await GetList(processId, 10, "create"); + foreach (var item in scriptList) + { + await ExecuteRevokeScript(item.UnitId, item.UnitName, processId, iWFEngine.CreateUser, iWFEngine); + } + + using (var uwo = UnitWork.CreateContext()) + { + await uwo.WFTask.DeleteAsync(a => a.ProcessId == processId); + await uwo.WFTaskLog.DeleteAsync(a => a.ProcessId == processId); + await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess { EnabledMark = 2 }, a => a.Id == processId); + + uwo.Commit(); + } + + await ExecuteScript(processId, "RevokeFlow", iWFEngine.CreateUser, + iWFEngine.WFScheme.UndoType, + iWFEngine.WFScheme.UndoDbCode, + iWFEngine.WFScheme.UndoDbSQL, + iWFEngine.WFScheme.UndoUrl, + iWFEngine.WFScheme.UndoIOCName); + + return true; + + } + + return false; + } + + /// + /// 催办流程 + /// + /// 流程进程主键 + public async Task> UrgeFlow(string processId) + { + // var userInfo = await this.CurrentUser(); + var iWFEngine = await Bootstraper(string.Empty, processId, null, null); + // 获取未完成的任务 + var taskList = await GetUnFinishTaskList(processId); + + using (var uwo = UnitWork.CreateContext()) + { + + foreach (var item in taskList) + { + if (item.Type == 1 || item.Type == 3 || item.Type == 5 || item.Type == 6 || item.Type == 7) + { + item.IsUrge = 1; + item.UrgeTime = DateTime.Now; + + + // 发送消息 + var msg = $"【审核】【催办】{item.ProcessTitle},{item.UnitName}"; + var userList = new List(); + // todo 单体任务处理 + userList.Add(item.UserId); + var node = iWFEngine.GetNode(item.UnitId); + //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, item.F_Token); + + await uwo.WFTask.UpdateAsync(item); + } + } + + //await wfProcessSerive.Update(new WFProcessEntity() { F_IsUrge = 1, F_Id = processId }); + + WFTaskLog wfTaskLogEntity = new WFTaskLog() + { + Des = "催办审核", + TaskType = 98, + ProcessId = processId, + UnitId = iWFEngine.StartNode.Id, + UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name + }; + + wfTaskLogEntity.CreateDate = DateTime.Now; + wfTaskLogEntity.UserId = _auth.GetUserId(); + wfTaskLogEntity.UserName = _auth.GetUserNickName(); + wfTaskLogEntity.Id = Guid.NewGuid().ToString(); + await uwo.WFTaskLog.InsertAsync(wfTaskLogEntity); + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + + + /// + /// 审批流程 + /// + /// 流程任务主键 + /// 流程审批操作码agree 同意 disagree 不同意 lrtimeout 超时 + /// 流程审批操名称 + /// 审批意见 + /// 下一节点指定审核人 + /// 盖章图片 + /// 盖章图片密码 + /// 下一个审核节点 + public async Task AuditFlow(string taskId, string code, string name, string des, Dictionary nextUsers, string stampImg, string stampPassWord, string nextId) + { + var taskEntiy = await client.Queryable().Where(a => a.Id == taskId).FirstAsync(); + if (taskEntiy == null) + { + throw (new Exception("找不到对应流程任务!")); + } + else if (taskEntiy.State != 1) + { + if (taskEntiy.State == 3 || taskEntiy.State == 4) + { + throw (new Exception("该任务已完成!")); + } + else + { + throw (new Exception("该任务未被激活!")); + } + } + + //后期改 + stampImg = ""; + //stampImg = await _wFStampIBLL.ToWfImg(stampImg, stampPassWord); + + var iWFEngine = await Bootstraper("", taskEntiy.ProcessId, null, nextUsers); + + // 1.判断任务类型 1 普通任务 5 会签任务 + if (taskEntiy.Type == 1||taskEntiy.Type==7) + { + await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg, nextId); + } + else if (taskEntiy.Type == 5) + { + await AuditNodeByCountersign(iWFEngine, taskEntiy, code, name, des, stampImg); + } + else + { + throw (new Exception("该任务无法审核!")); + } + + //await _imMsgIBLL.VirtualDeleteByContentId(taskEntiy.F_Token); // 更新消息 + + // 发送消息 + var msg = $"【提醒】{iWFEngine.Config.Params.Title},{taskEntiy.UnitName}已被处理"; + var userList = new List(); + userList.Add(iWFEngine.CreateUser.Id); + var node = iWFEngine.StartNode; + //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, iWFEngine.Config.Params.ProcessId); + } + + /// + /// 批量审核(只有同意和不同意) + /// + /// 操作码 + /// 任务id串 + public async Task AuditFlows(string code, List taskIdList) + { + foreach (var taskId in taskIdList) + { + string operationName = code == "agree" ? "同意" : "不同意"; + await AuditFlow(taskId, code, operationName, "批量审核", null, "", "", ""); + } + } + + /// + /// 撤销审核 + /// + /// + /// 流程任务主键 + /// + public async Task> RevokeAudit(string processId, string taskId) + { + var iWFEngine = await Bootstraper(string.Empty, processId, null, null); + WFTask taskEntity; + WFProcess processEntity; + if (string.IsNullOrEmpty(taskId)) + { //撤销重新提交任务 + processEntity = await GetEntity(processId); + if (processEntity.IsCancel != 1) + { + throw (new Exception("当前流程无法撤销!")); + } + + var myTaskList = (List)await GetLastTaskList(processId, iWFEngine.StartNode.Id); + taskEntity = myTaskList[0]; + + processEntity.IsAgain = 1; + processEntity.IsCancel = 0; + } + else + { + taskEntity = await client.Queryable().Where(a => a.Id == taskId).FirstAsync(); + + if (taskEntity.State == 1) + { + throw (new Exception("当前任务无法撤销!")); + } + + var taskLogEntity = await GetLogEntity(taskId); + + if (taskLogEntity == null || taskLogEntity.IsCancel != 1) + { + throw (new Exception("当前任务无法撤销!")); + } + processEntity = new WFProcess() + { + Id = processId + }; + processEntity.IsFinished = 0; + processEntity.IsAgain = 0; + } + + using (var uwo = UnitWork.CreateContext()) + { + // 获取脚本任务 + var scriptList = await GetList(processId, 10, taskEntity.Id); + foreach (var item in scriptList) + { + await ExecuteRevokeScript(item.UnitId, item.UnitName, processId, iWFEngine.CreateUser, iWFEngine); + // 删除脚本任务执行日志 + await DeleteLogByTaskId(item.Id); + } + + + // 删除所有生成的任务 + await Delete(processId, taskEntity.Id); + + // 如果是加签审核的,关闭最早的任务 + if (taskEntity.Type == 6) + { + var myTaskEntiy = await GetTaskEntity(taskEntity.FirstId); // 原始审核任务 + myTaskEntiy.State = 5; + await uwo.WFTask.UpdateAsync(myTaskEntiy); + } + + + // 如果是撤销转移任务 + if (taskEntity.State == 6) + { + // 删除转移任务 + await DeleteByFirstId(taskEntity.Id); + } + + + // 删除所有生成的日志 + await DeleteLog(processId, taskEntity.Id); + + // 更新等待任务状态 + await OpenTask(processId, taskEntity.UnitId, 21, taskEntity.Id); + + taskEntity.State = 1; + await uwo.WFTask.UpdateAsync(taskEntity); + + await uwo.Db.Updateable(processEntity) + .IgnoreColumns(ignoreAllNullColumns: true) + .ExecuteCommandAsync(); + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + } + + /// + /// 流程加签 + /// + /// 流程任务主键 + /// 加签人员 + /// 加签说明 + public async Task> SignFlow(string taskId, string userId, string des) + { + var taskEntiy = await GetTaskEntity(taskId); + if (taskEntiy == null) + { + throw (new Exception("找不到对应流程任务!")); + } + else if (taskEntiy.State != 1) + { + if (taskEntiy.State == 3 || taskEntiy.State == 4) + { + throw (new Exception("该任务已完成!")); + } + else + { + throw (new Exception("该任务未被激活!")); + } + } + + using (var uwo = UnitWork.CreateContext()) + { + + // 更新任务状态 + taskEntiy.State = 5; + await uwo.WFTask.UpdateAsync(taskEntiy); + + // 更新上一个流转过来的任务,提示他无法被撤销 + await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId); + + // 填写日志 + await CreateTaskLog(taskEntiy, "sign", "加签", des, ""); + + if (taskEntiy.Type != 6) + { + taskEntiy.FirstId = taskEntiy.Id; + } + + var userInfo = await uwo.User.GetByIdAsync(userId); + + // 添加加签任务 + taskEntiy.PrevTaskId = taskEntiy.Id; + //taskEntiy.UserCompanyId = userInfo.CompanyId; + //taskEntiy.UserDepartmentId = userInfo.DepartmentId; + taskEntiy.UserId = userInfo.Id.ToString(); + taskEntiy.UserName = userInfo.Name; + taskEntiy.Type = 6; + taskEntiy.State = 1; + await uwo.WFTask.InsertAsync(taskEntiy); + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + + /// + /// 流程加签审核 + /// + /// 流程任务主键 + /// 操作码 + /// 流程审批操名称 + /// 审批意见 + /// + public async Task> SignAudit(string taskId, string code, string name, string des) + { + var taskEntiy = await GetTaskEntity(taskId); + if (taskEntiy == null) + { + throw (new Exception("找不到对应流程任务!")); + } + else if (taskEntiy.State != 1) + { + if (taskEntiy.State == 3 || taskEntiy.State == 4) + { + throw (new Exception("该任务已完成!")); + } + else + { + throw (new Exception("该任务未被激活!")); + } + } + + using (var uwo = UnitWork.CreateContext()) + { + var myTaskEntiy = await GetTaskEntity(taskEntiy.FirstId); // 原始审核任务 + myTaskEntiy.IsLast = 0; + await uwo.WFTask.UpdateAsync(myTaskEntiy); + myTaskEntiy.State = 1; + myTaskEntiy.IsLast = 1; + await Add(myTaskEntiy); + + // 更新任务状态 + taskEntiy.State = 3; + if (taskEntiy.Type == 7) + { + var currentUser = _auth.GetCurrentUser().User; + taskEntiy.UserId = currentUser.Id.ToString(); + taskEntiy.UserName = currentUser.Name; + } + await uwo.WFTask.UpdateAsync(taskEntiy); + + // 填写日志 + await CreateTaskLog(taskEntiy, code, name, des, ""); + + // 更新上一个流转过来的任务,提示他无法被撤销 + await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId); + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + + /// + /// 确认阅读 + /// + /// 流程任务主键 + public async Task> ReadFlow(string taskId) + { + var taskEntiy = await GetTaskEntity(taskId); + if (taskEntiy == null) + { + throw (new Exception("找不到对应流程任务!")); + } + else if (taskEntiy.State == 1) + { + using (var uwo = UnitWork.CreateContext()) + { + taskEntiy.State = 3; + await uwo.WFTask.UpdateAsync(taskEntiy); + + WFTaskLog wfTaskLogEntity = new WFTaskLog() + { + TaskType = taskEntiy.Type, + ProcessId = taskEntiy.ProcessId, + UnitId = taskEntiy.UnitId, + UnitName = taskEntiy.UnitName, + IsAgree = taskEntiy.IsAgree, + OperationCode = "read", + OperationName = "已阅", + Token = taskEntiy.Token, + PrevUnitId = taskEntiy.PrevUnitId, + PrevUnitName = taskEntiy.PrevUnitName, + TaskId = taskEntiy.Id, + IsCancel = 0 + }; + await AddLog(wfTaskLogEntity); + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + } + else + { + return new Response + { + Result = false, + Message = "error" + }; + } + } + + /// + /// 转移流程 + /// + /// 任务id + /// 转移人用户id + /// 说明 + /// + public async Task> TransferUser(string taskId, string userId, string des) + { + var taskEntiy = await GetTaskEntity(taskId); + if (taskEntiy == null) + { + throw (new Exception("找不到对应流程任务!")); + } + else if (taskEntiy.State == 1) + { + using (var uwo = UnitWork.CreateContext()) + { + var userInfo = await uwo.User.GetByIdAsync(userId); + + // 更新任务状态 + taskEntiy.State = 6; + await uwo.WFTask.UpdateAsync(taskEntiy); + + // 更新流程 + WFProcess processEntity = new WFProcess() + { + Id = taskEntiy.ProcessId, + IsStart = 1, + IsCancel = 0, + }; + await uwo.WFProcess.UpdateAsync(processEntity); + + // 填写日志 + await CreateTaskLog(taskEntiy, "transfer", "转移", des, ""); + + // 更新上一个流转过来的任务,提示他无法被撤销 + await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId); + + // 新建任务 + var newTask = taskEntiy; //.ToJson().ToObject(); + newTask.State = 1; + newTask.PrevTaskId = taskEntiy.Id; + //newTask.UserCompanyId = userInfo.F_CompanyId; + //newTask.UserDepartmentId = userInfo.F_DepartmentId; + newTask.UserId = userInfo.Id.ToString(); + newTask.UserName = userInfo.Name; + + await uwo.WFTask.InsertAsync(newTask); + + // 发送消息 + var iWFEngine = await Bootstraper("", taskEntiy.ProcessId, null); + var msg = $"【审核】{taskEntiy.ProcessTitle},{taskEntiy.UnitName}"; + var userList = new List(); + userList.Add(userInfo.Id.ToString()); + var node = iWFEngine.GetNode(taskEntiy.UnitId); + //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, newTask.F_Token); + + var flag = uwo.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + else + { + return new Response + { + Result = false, + Message = "error" + }; + } + } + + /// + /// 获取下一节点审核人 + /// + /// 流程模板编码 + /// 流程进程主键 + /// 流程节点Id + /// 流程操作代码 + /// 创建人 + /// + public async Task>> GetNextAuditors(string code, string processId, string nodeId, string operationCode, string userId) + { + Dictionary> res = new Dictionary>(); + var userInfo = await client.Queryable().Where(a => a.Id.ToString() == userId).FirstAsync(); + var iWFEngine = await Bootstraper(code, processId, userInfo); + + // 下一部需要执行的任务 + var taskList = await iWFEngine.GetTask(nodeId, operationCode); + + foreach (var item in taskList) + { + if ((item.Type == 1 || item.Type == 3 || item.Type == 5||item.Type==7) && item.User.IsNew) + { + if (!res.ContainsKey(item.UnitId)) + { + res.Add(item.UnitId, new List()); + } + res[item.UnitId].Add(item.User); + } + } + + return res; + } + + /// + /// 作废流程 + /// + /// 流程进程主键 + /// + public async Task> DeleteProcess(string processId) + { + var flag = false; + var iWFEngine = await Bootstraper(string.Empty, processId, null); + + using (var uwo = UnitWork.CreateContext()) + { + // 更新流程状态 + WFProcess processEntity = new WFProcess() + { + Id = processId, + + }; + await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess { EnabledMark = 3 }, a => a.Id == processId); + + await uwo.WFTask.UpdateSetColumnsTrueAsync(a => new WFTask { State = 7 }, a => a.ProcessId == processId && a.State == 1); + flag = uwo.Commit(); + } + + var response = new Response(); + + if (flag) + { + var scriptResult = await ExecuteScript(processId, "delete", iWFEngine.CreateUser, + iWFEngine.WFScheme.DeleteType, + iWFEngine.WFScheme.DeleteDbCode, + iWFEngine.WFScheme.DeleteDbSQL, + iWFEngine.WFScheme.DeleteUrl, + iWFEngine.WFScheme.DeleteIOCName); + + if (scriptResult) + { + response.Result = true; + response.Message = "success"; + } + else + { + response.Result = false; + response.Message = "流程状态更新成功,但脚本执行失败"; + } + } + else + { + response.Result = false; + response.Message = "error"; + } + return response; + } + + /// + /// 流程还原 + /// + /// 流程进程主键 + /// + public async Task> RecoverProcess(string processId) + { + var flag = false; + var iWFEngine = await Bootstraper(string.Empty, processId, null); + + using (var uwo = UnitWork.CreateContext()) + { + // 更新流程状态 + WFProcess processEntity = new WFProcess() + { + Id = processId, + + }; + await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess { EnabledMark = 1 }, a => a.Id == processId); + + await uwo.WFTask.UpdateSetColumnsTrueAsync(a => new WFTask { State = 1 }, a => a.ProcessId == processId && a.State == 7); + flag = uwo.Commit(); + } + + var response = new Response(); + + if (flag) + { + + response.Result = true; + response.Message = "success"; + } + else { + response.Result = false; + response.Message = "error"; + } + + return response; + } + + /// + /// 指派流程审核人 + /// + /// 流程进程主键 + /// 流程指派人信息 + /// + public async Task> PointUser(string processId, List pointList) + { + var list = await GetUnFinishTaskList(processId); + Dictionary> map = new Dictionary>(); + foreach (var item in list) + { + if (!map.ContainsKey(item.UnitId)) + { + map.Add(item.UnitId, new List()); + } + map[item.UnitId].Add(item); + } + + var addList = new List(); + var iWFEngine = await Bootstraper("", processId, null); + using (var uwo = UnitWork.CreateContext()) + { + + foreach (var item in pointList) + { + if (map.ContainsKey(item.UnitId)) + { + await CloseTask(processId, map[item.UnitId][0].Token, ""); + var userIdList = item.UserIds.Split(","); + foreach (var userId in userIdList) + { + var addItem = Newtonsoft.Json.JsonConvert.SerializeObject(map[item.UnitId][0]).ToObject(); + addItem.State = 1; + if (addItem.Type == 6) + { + addItem.Type = 1; + } + + var userEntity = _auth.GetCurrentUser().User; + + addItem.UserId = userId; + addItem.UserName = userEntity.Name; + //addItem.UserCompanyId = userEntity.F_CompanyId; + //addItem.UserDepartmentId = userEntity.F_DepartmentId; + + // 发送消息 + var msg = $"【审核】{addItem.ProcessTitle},{addItem.UnitName}"; + var userList = new List(); + userList.Add(userId); + var node = iWFEngine.GetNode(addItem.UnitId); + //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, addItem.F_Token); + + addList.Add(addItem); + } + } + else + { + throw (new Exception("找不到指派任务节点!")); + } + } + + foreach (var item in addList) + { + await Add(item); + } + + var flag = uwo.Commit(); + + return new Response() + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + } + #endregion + + #region + /// + /// 流程模板初始化 + /// + /// 流程模板 + /// 流程实例 + /// 提交人用户信息 + /// 下一个节点审核人 + /// + private async Task Bootstraper(string code, string processId, SysUser userInfo, Dictionary nextUsers = null) + { + + WFEngineConfig wfEngineConfig = new WFEngineConfig(); + WFParams wfParams = new WFParams(); + wfEngineConfig.Params = wfParams; + + var currentUser = _auth.GetCurrentUser().User; + wfParams.CurrentUser = new WFUserInfo() + { + Id = currentUser.Id.ToString(), + Account = currentUser.Account, + Name = currentUser.Name + //CompanyId = currentUser.F_CompanyId, + //DepartmentId = currentUser.F_DepartmentId + }; + if (!string.IsNullOrEmpty(code)) + { + var schemeInfo = await client.Queryable().FirstAsync(a => a.Code == code); + if (schemeInfo != null) + { + var data = await client.Queryable().FirstAsync(a => a.Id == schemeInfo.SchemeId); + if (data != null) + { + wfParams.Scheme = data.Content; + wfParams.SchemeCode = code; + wfParams.SchemeId = schemeInfo.SchemeId; + wfParams.SchemeName = schemeInfo.Name; + wfParams.ProcessId = processId; + wfParams.HasInstance = false; + + wfParams.CreateUser = new WFUserInfo() + { + Id = userInfo.Id.ToString(), + Account = userInfo.Account, + Name = userInfo.Name + //CompanyId = userInfo.F_CompanyId, + //DepartmentId = userInfo.F_DepartmentId + }; + } + else + { + throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code)); + } + } + else + { + throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code)); + } + } + else if (!string.IsNullOrEmpty(processId)) + { + var processEntity = await GetEntity(processId); + if (processEntity != null) + { + var data = await client.Queryable().FirstAsync(a => a.Id == processEntity.SchemeId); + if (data != null) + { + wfParams.Scheme = data.Content; + wfParams.SchemeCode = processEntity.SchemeCode; + wfParams.SchemeId = processEntity.SchemeId; + wfParams.SchemeName = processEntity.SchemeName; + wfParams.IsChild = processEntity.IsChild == 1; + wfParams.ParentProcessId = processEntity.ParentProcessId; + wfParams.ParentTaskId = processEntity.ParentTaskId; + wfParams.ParentNodeId = processEntity.ParentNodeId; + wfParams.ProcessId = processId; + wfParams.HasInstance = true; + wfParams.IsStart = processEntity.IsStart == 1 ? 1 : 0; + wfParams.Title = processEntity.Title; + + wfParams.CreateUser = new WFUserInfo() + { + Id = processEntity.CreateUserId, + Account = processEntity.CreateUserAccount, + Name = processEntity.CreateUserName, + CompanyId = processEntity.CreateUserCompanyId, + DepartmentId = processEntity.CreateUserDepartmentId + }; + } + else + { + throw new Exception(string.Format("无法获取流程模板【{0}】", processEntity.SchemeId)); + } + } + else if (string.IsNullOrEmpty(wfParams.Scheme)) + { + throw new Exception(string.Format("无法获取实例数据【{0}】", processId)); + } + } + + + wfParams.NextUsers = nextUsers; + + + // 注册委托方法 + wfEngineConfig.GetAwaitTaskList = GetAwaitTaskList; + wfEngineConfig.GetUserList = GetUserList; + wfEngineConfig.GetSystemUserList = GetSystemUserList; + wfEngineConfig.GetPrevTaskUserList = GetPrevTaskUserList; + wfEngineConfig.IsCountersignAgree = IsCountersignAgree; + wfEngineConfig.GetPrevUnitId = GetPrevUnitId; + + + IWFEngine iwfEngine = new WFEngine(wfEngineConfig, client); + + return iwfEngine; + } + + /// + /// 流程模板初始化 + /// + /// 流程模板 + /// 流程实例 + /// 提交人用户信息 + /// 下一个节点审核人 + /// + private async Task BootstraperWithUser(string code, string processId, SysUser userInfo, Dictionary nextUsers = null) + { + + WFEngineConfig wfEngineConfig = new WFEngineConfig(); + WFParams wfParams = new WFParams(); + wfEngineConfig.Params = wfParams; + + var currentUser = userInfo; + wfParams.CurrentUser = new WFUserInfo() + { + Id = currentUser.Id.ToString(), + Account = currentUser.Account, + Name = currentUser.Name + //CompanyId = currentUser.F_CompanyId, + //DepartmentId = currentUser.F_DepartmentId + }; + if (!string.IsNullOrEmpty(code)) + { + var schemeInfo = await client.Queryable().FirstAsync(a => a.Code == code); + if (schemeInfo != null) + { + var data = await client.Queryable().FirstAsync(a => a.Id == schemeInfo.SchemeId); + if (data != null) + { + wfParams.Scheme = data.Content; + wfParams.SchemeCode = code; + wfParams.SchemeId = schemeInfo.SchemeId; + wfParams.SchemeName = schemeInfo.Name; + wfParams.ProcessId = processId; + wfParams.HasInstance = false; + + wfParams.CreateUser = new WFUserInfo() + { + Id = userInfo.Id.ToString(), + Account = userInfo.Account, + Name = userInfo.Name + //CompanyId = userInfo.F_CompanyId, + //DepartmentId = userInfo.F_DepartmentId + }; + } + else + { + throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code)); + } + } + else + { + throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code)); + } + } + else if (!string.IsNullOrEmpty(processId)) + { + var processEntity = await GetEntity(processId); + if (processEntity != null) + { + var data = await client.Queryable().FirstAsync(a => a.Id == processEntity.SchemeId); + if (data != null) + { + wfParams.Scheme = data.Content; + wfParams.SchemeCode = processEntity.SchemeCode; + wfParams.SchemeId = processEntity.SchemeId; + wfParams.SchemeName = processEntity.SchemeName; + wfParams.IsChild = processEntity.IsChild == 1; + wfParams.ParentProcessId = processEntity.ParentProcessId; + wfParams.ParentTaskId = processEntity.ParentTaskId; + wfParams.ParentNodeId = processEntity.ParentNodeId; + wfParams.ProcessId = processId; + wfParams.HasInstance = true; + wfParams.IsStart = processEntity.IsStart == 1 ? 1 : 0; + wfParams.Title = processEntity.Title; + + wfParams.CreateUser = new WFUserInfo() + { + Id = processEntity.CreateUserId, + Account = processEntity.CreateUserAccount, + Name = processEntity.CreateUserName, + CompanyId = processEntity.CreateUserCompanyId, + DepartmentId = processEntity.CreateUserDepartmentId + }; + } + else + { + throw new Exception(string.Format("无法获取流程模板【{0}】", processEntity.SchemeId)); + } + } + else if (string.IsNullOrEmpty(wfParams.Scheme)) + { + throw new Exception(string.Format("无法获取实例数据【{0}】", processId)); + } + } + + + wfParams.NextUsers = nextUsers; + + + // 注册委托方法 + wfEngineConfig.GetAwaitTaskList = GetAwaitTaskList; + wfEngineConfig.GetUserList = GetUserList; + wfEngineConfig.GetSystemUserList = GetSystemUserList; + wfEngineConfig.GetPrevTaskUserList = GetPrevTaskUserList; + wfEngineConfig.IsCountersignAgree = IsCountersignAgree; + wfEngineConfig.GetPrevUnitId = GetPrevUnitId; + + + IWFEngine iwfEngine = new WFEngine(wfEngineConfig, client); + + return iwfEngine; + } + + /// + /// 获取等待任务 + /// + /// 流程进程ID + /// 流程单元ID + /// + private async Task> GetAwaitTaskList(string processId, string unitId) + { + List res = new List(); + var list = await client.Queryable().Where(t => t.ProcessId == processId && t.UnitId == unitId && t.Type == 21 && t.State == 1).ToListAsync(); + + foreach (var item in list) + { + res.Add(GetWFTask(item)); + } + return res; + } + /// + /// 获取设置人员 + /// + /// 人员配置信息 + /// 流程发起人 + /// 流程进程实例ID + /// 开始节点 + /// + private async Task> GetUserList(List auditorList, WFUserInfo createUser, string processId, WFUnit startNode) + { + var res = new List(); + List userIds = new List(); + foreach (var item in auditorList) + { + switch (item.Type) + { + //岗位 + case "1": + var rlist = await userManager.UserIdsByPosition("", item.Id); + foreach (var ritem in rlist) + { + userIds.Add(ritem); + } + break; + //角色 + case "2": + var rlist2 = await userManager.UserIdsByRole(item.Id); + List userIds2 = new List(); + foreach (var ritem2 in rlist2) + { + userIds2.Add(ritem2); + } + var userList2 = await GetListByKeyValues(userIds2.ToArray()); + var userOrgs = await userManager.UserOrgsByUserIds(userIds2); + foreach (var userOrg in userOrgs) + { + var user2 = userList2.FirstOrDefault(a => a.Id.ToString() == userOrg.Key); + switch (item.Condition) + { + case "1": + if ((userOrg.Value as List).Contains(createUser.DepartmentId)) + { + res.Add(GetWFUserInfo(user2)); + } + break; + //case "2": + // if (user2.CompanyId == createUser.CompanyId) + // { + // res.Add(GetWFUserInfo(user2)); + // } + // break; + case "3": + //// 获取当前用户的岗位 + var postList1 = await userManager.PositonsByUser(createUser.Id);// 发起人岗位 + var postList2 = await userManager.PositonsByUser(user2.Id.ToString());// 节点审核人岗位 + //if (await _postIBLL.IsUp(postList1, postList2)) + if (await positionManager.IsUp(postList1, postList2)) + { + res.Add(GetWFUserInfo(user2)); + } + break; + case "4": + // 获取当前用户的岗位 + var postList3 = await userManager.PositonsByUser(createUser.Id);// 发起人岗位 + var postList4 = await userManager.PositonsByUser(user2.Id.ToString());// 节点审核人岗位 + if (await positionManager.IsDown(postList3, postList4)) + { + res.Add(GetWFUserInfo(user2)); + } + break; + default: + res.Add(GetWFUserInfo(user2)); + break; + } + } + break; + //用户 + case "3": + userIds.Add(item.Id); + break; + //上下级 + case "4": + var postIds = await userManager.PositonsByUser(createUser.Id);// 发起人岗位 + int level = Convert.ToInt32(item.Id); + List postList; + if (level < 6) + { + postList = (await positionManager.GetUpIdList(postIds, level)).ToList(); + } + else + { + level = level - 5; + postList = (await positionManager.GetDownIdList(postIds, level)).ToList(); + } + var userRelationList4 = await userManager.UserIdsByPositions(postList); + userIds.AddRange(userRelationList4); + break; + //节点执行人 + case "5": + if (item.Id == startNode.Id) + { + res.Add(createUser); + } + else + { + var taskList = await GetLastFinishTaskList(item.Id, processId); + foreach (var task in taskList) + { + userIds.Add(task.UserId); + } + } + + break; + //数据库表字段 + case "6": + using (var db = this.CodeClient(item.DbCode, _configuration)) + { + DataTable dt = await db.Ado.GetDataTableAsync(string.Format("select {0} from {1} where {2} = @processId ", item.AuditorField, item.Table, item.Rfield), new { processId }); + foreach (DataRow row in dt.Rows) + { + var userIdString = row[0].ToString(); + if (!string.IsNullOrEmpty(userIdString)) + { + var userIdList = userIdString.Split(","); + foreach (var userIdItem in userIdList) + { + userIds.Add(userIdItem); + } + } + } + break; + } + + //数据库表字段 + case "7": + using (var db = this.CodeClient(item.DbCode, _configuration)) + { + //获取数据id + var process = await client.Queryable().FirstAsync(a => a.Id == processId); + WFInstanceInfo instanceInfo = null; + if (process != null) + { + // instanceInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(process.InstanceInfo); + instanceInfo = process.InstanceInfo; + } + DataTable dt = await db.Ado.GetDataTableAsync(string.Format(item.Sql), new { pkeyValue = instanceInfo.pkeyValue }); + foreach (DataRow row in dt.Rows) + { + var userIdString = row[0].ToString(); + if (!string.IsNullOrEmpty(userIdString)) + { + var userIdList = userIdString.Split(","); + foreach (var userIdItem in userIdList) + { + userIds.Add(userIdItem); + } + } + } + break; + } + } + } + var userList = await GetListByKeyValues(userIds.ToArray()); + foreach (var user in userList) + { + res.Add(GetWFUserInfo(user)); + } + return res; + } + /// + /// 获取单元上一次的审核人 + /// + /// 流程进程ID + /// 流程单元ID + /// + private async Task> GetPrevTaskUserList(string processId, string unitId) + { + var res = new List(); + var list = await GetLastTaskList(processId, unitId); + foreach (var item in list) + { + if (!string.IsNullOrEmpty(item.UserId)) + { + res.Add(new WFUserInfo() + { + Id = item.UserId, + Name = item.UserName, + CompanyId = item.UserCompanyId, + DepartmentId = item.UserDepartmentId, + IsAgree = item.IsAgree == 1, + //Sort = item, + State = (int)item.State + }); + } + } + return res; + } + /// + /// 获取系统管理员 + /// + /// + private async Task> GetSystemUserList() + { + var res = new List(); + + var user = new SysUser + { + Id = -1, + Account = Define.SYSTEM_USERNAME, + Name = "超级管理员" + }; + res.Add(GetWFUserInfo(user)); + + return res; + } + /// + /// 判断会签是否通过 + /// + /// 流程进程ID + /// 流程单元ID + /// + private async Task IsCountersignAgree(string processId, string unitId) + { + var list = (List)await GetLogList(processId, unitId); + if (list.Count == 0) + { + return false; + } + return list[0].IsAgree == 1; + } + /// + /// 获取上一个流入节点(不是驳回流入的) + /// + /// + /// + /// + private async Task GetPrevUnitId(string processId, string unitId) + { + var data = await GetLastNotRejectTask(processId, unitId); + if (data != null) + { + return data.PrevUnitId; + } + else + { + return string.Empty; + } + } + /// + /// 获取流程任务数据 + /// + /// + /// + private WorkFlow.WFTask GetWFTask(WFTask wfTaskEntity) + { + var res = new WorkFlow.WFTask() + { + UnitId = wfTaskEntity.UnitId, + Name = wfTaskEntity.UnitName, + PrevUnitId = wfTaskEntity.PrevUnitId, + PrevUnitName = wfTaskEntity.PrevUnitName, + Token = wfTaskEntity.Token, + Type = (int)wfTaskEntity.Type + }; + return res; + } + /// + /// 获取用户 + /// + /// + /// + private WFUserInfo GetWFUserInfo(SysUser userEntity) + { + var res = new WFUserInfo() + { + Id = userEntity.Id.ToString(), + Name = userEntity.Name, + Account = userEntity.Account, + //DepartmentId = userEntity.F_DepartmentId, + //CompanyId = userEntity.F_CompanyId, + IsNew = true + }; + return res; + } + /// + /// 获取流程实例 + /// + /// 流程运行参数 + /// 标题 + /// + private WFProcess GetWFProcessEntity(WFParams myParams, string title) + { + WFProcess wfProcessEntity = new WFProcess() + { + Id = myParams.ProcessId, + SchemeCode = myParams.SchemeCode, + SchemeId = myParams.SchemeId, + SchemeName = myParams.SchemeName, + Title = title, + EnabledMark = 1, + IsAgain = 0, + IsFinished = 0, + IsChild = myParams.IsChild ? 1 : 0, + IsStart = 0, + IsCancel = 1, + ParentNodeId = myParams.ParentNodeId, + ParentProcessId = myParams.ParentProcessId, + ParentTaskId = myParams.ParentTaskId, + CreateUserId = myParams.CreateUser.Id, + CreateUserName = myParams.CreateUser.Name, + CreateUserAccount = myParams.CreateUser.Account, + CreateUserCompanyId = myParams.CreateUser.CompanyId, + CreateUserDepartmentId = myParams.CreateUser.DepartmentId, + UserId = _auth.GetUserId() + }; + + return wfProcessEntity; + + } + + /// + /// 处理任务 + /// + /// 任务列表 + /// + /// 流程进程实例 + /// 任务Token + /// 任务id + /// + private async Task> ExecuteWFTaskEntity(List list, IWFEngine iWFEngine, string processId, string prevToken, string taskId = "") + { + var res = new List(); + + //单任务审核 + var tlist = list.Where(r => r.Type == 7).ToList(); + if (tlist.Count > 0) + { + var group = tlist.GroupBy(r => r.UnitId).ToList(); + foreach (var item in group) + { + var taskuser = new List(); + var users = tlist.Where(r => r.UnitId == item.Key).ToList(); + var userTask = new WFTask + { + Id = Guid.NewGuid().ToString(), + Type = users[0].Type, + ProcessId = processId, + Token = users[0].Token, + UnitId = users[0].UnitId, + UnitName = users[0].Name, + PrevUnitId = users[0].PrevUnitId, + PrevUnitName = users[0].PrevUnitName, + PrevToken = prevToken, + PrevTaskId = taskId, + UserId = users[0].User.Id, + UserName = users[0].User.Name, + UserDepartmentId = users[0].User.DepartmentId, + UserCompanyId = users[0].User.CompanyId, + State = users[0].User.IsAwait ? 2 : 1, + Sort = users[0].User.Sort, + IsReject = users[0].IsReject ? 1 : 0, + ChildProcessId = users[0].ChildSchemeInfoId, + + TimeoutInterval = users[0].OvertimeMessageInterval, + TimeoutStrategy = users[0].OvertimeMessageType, + + IsBatchAudit = users[0].IsBatchAudit ? 1 : 0, + ProcessUserId = iWFEngine.CreateUser.Id, + ProcessUserName = iWFEngine.CreateUser.Name, + ProcessCode = iWFEngine.Config.Params.SchemeCode, + ProcessTitle = iWFEngine.Config.Params.Title, + IsRetract=0 + }; + if (users[0].IsOvertimeMessage) + { + if (users[0].OvertimeGo > 0) + { + userTask.TimeoutAction = DateTime.Now.AddHours(users[0].OvertimeGo); + } + if (users[0].OvertimeMessageStart > 0) + { + userTask.TimeoutNotice = DateTime.Now.AddHours(users[0].OvertimeMessageStart); + } + } + foreach (var ts in users) + { + WFTaskUser tu = new WFTaskUser(); + tu.UserId = ts.User.Id; + tu.TaskId = userTask.Id; + taskuser.Add(tu); + } + userTask.WFTaskUser = taskuser; + res.Add(userTask); + } + } + foreach (var item in list) + { + if (!string.IsNullOrEmpty(item.MessageType)) + { + // 发送消息 + var taskType = ""; + switch (item.Type) + { + case 1: + case 5: + case 7: + taskType = "审核"; + break; + case 2: + taskType = "查阅"; + break; + case 3: + taskType = "提交"; + break; + case 4: + taskType = "重新提交"; + break; + } + if (!string.IsNullOrEmpty(taskType)) + { + var msg = $"【{taskType}】{iWFEngine.Config.Params.Title},{item.Name}"; + var userList = new List(); + userList.Add(item.User.Id); + //await _imMsgIBLL.SendMsg("IMWF", userList, msg, item.MessageType, item.Token); + } + } + + string childSchemeInfoCode = ""; + if (item.Type == 3) + { + var schemeInfo = await this.Repository.ChangeRepository>().GetByIdAsync(item.ChildSchemeInfoId); + if (schemeInfo != null) + { + childSchemeInfoCode = schemeInfo.Code; + } + } + + switch (item.Type) + { + case 1: + case 2: + case 3: + case 4: + case 5: + var userTask = new WFTask + { + Type = item.Type, + ProcessId = processId, + Token = item.Token, + UnitId = item.UnitId, + UnitName = item.Name, + PrevUnitId = item.PrevUnitId, + PrevUnitName = item.PrevUnitName, + PrevToken = prevToken, + PrevTaskId = taskId, + UserId = item.User.Id, + UserName = item.User.Name, + UserDepartmentId = item.User.DepartmentId, + UserCompanyId = item.User.CompanyId, + State = item.User.IsAwait ? 2 : 1, + Sort = item.User.Sort, + IsReject = item.IsReject ? 1 : 0, + ChildProcessId = item.ChildSchemeInfoId, + ChildSchemeInfoCode = childSchemeInfoCode, + + TimeoutInterval = item.OvertimeMessageInterval, + TimeoutStrategy = item.OvertimeMessageType, + + IsBatchAudit = item.IsBatchAudit ? 1 : 0, + ProcessUserId = iWFEngine.CreateUser.Id, + ProcessUserName = iWFEngine.CreateUser.Name, + ProcessCode = iWFEngine.Config.Params.SchemeCode, + ProcessTitle = iWFEngine.Config.Params.Title, + IsRetract=0 + }; + if (item.IsOvertimeMessage) + { + if (item.OvertimeGo > 0) + { + userTask.TimeoutAction = DateTime.Now.AddHours(item.OvertimeGo); + } + if (item.OvertimeMessageStart > 0) + { + userTask.TimeoutNotice = DateTime.Now.AddHours(item.OvertimeMessageStart); + } + } + + res.Add(userTask); + break; + case 10: + // 执行脚本 + res.Add(new WFTask + { + Type = item.Type, + ProcessId = processId, + Token = item.Token, + UnitId = item.UnitId, + UnitName = item.Name, + PrevUnitId = item.PrevUnitId, + PrevUnitName = item.PrevUnitName, + PrevToken = prevToken + }); + break; + case 21: + res.Add(new WFTask + { + Type = item.Type, + ProcessId = processId, + Token = item.Token, + UnitId = item.UnitId, + UnitName = item.Name, + PrevUnitId = item.PrevUnitId, + PrevUnitName = item.PrevUnitName, + PrevToken = prevToken, + State = 1, + }); + break; + case 22: + await CloseTask(processId, item.UnitId, 21, taskId); + break; + case 23: + case 24: + WFTaskLog wfTaskLogEntity = new WFTaskLog() + { + Des = "系统任务", + TaskType = item.Type, + Token = item.Token, + ProcessId = processId, + UnitId = item.UnitId, + UnitName = item.Name, + PrevUnitId = item.PrevUnitId, + PrevUnitName = item.PrevUnitName + }; + await AddLog(wfTaskLogEntity); + break; + case 26: + // 更新任务状态 + await Update(processId, item.UnitId); + break; + } + } + return res; + } + + public void AddOpenJob(WFTask task, DateTime outtime, DateTime overtime) + { + try + { + AddOrUpdateOpenJobReq req = new AddOrUpdateOpenJobReq(); + req.JobName = $"超时通知 {task.Id}"; + req.JobType = 0; + req.JobCallParams = "{\"TaskId\":\"" + task.Id + "\"}"; + req.JobCall = "OpenAuth.App.BaseApp.Jobs.TaskTimeoutJob"; + req.Status = 1; + req.Cron = GetCorn(outtime); + req.Remark = $"{task.ProcessUserId}--{task.UnitName}"; + _job.AddStart(req); + + AddOrUpdateOpenJobReq req1 = new AddOrUpdateOpenJobReq(); + req1.JobName = $"严重超时通知 {task.Id}"; + req1.JobType = 0; + req1.JobCallParams = "{\"TaskId\":\"" + task.Id + "\"}"; + req1.JobCall = "OpenAuth.App.BaseApp.Jobs.TaskOverTimeJob"; + req1.Status = 1; + req1.Cron = GetCorn(overtime); + req1.Remark = $"{task.ProcessUserId}--{task.UnitName}"; + _job.AddStart(req1); + } + catch + { + return; + } + } + + + public string GetCorn(DateTime time) + { + StringBuilder sb = new StringBuilder(); + sb.Append(time.Second.ToString()); + sb.Append(" "); + sb.Append(time.Minute.ToString()); + sb.Append(" "); + sb.Append(time.Hour.ToString()); + sb.Append(" "); + sb.Append(time.Day.ToString()); + sb.Append(" "); + sb.Append(time.Month.ToString()); + sb.Append(" "); + sb.Append("?"); + sb.Append(" "); + sb.Append(time.Year.ToString()); + return sb.ToString(); + } + /// + /// 执行脚本 + /// + /// 脚本任务 + /// + /// + /// + /// + /// + /// + /// + private async Task ExecuteScript(WFTask task, string code, string processId, string prevTaskId,string nextid, WFUserInfo createUser, IWFEngine iWFEngine, WFTask preTask,string des) + { + SysUser userInfo; + if (preTask == null) + { + userInfo = new SysUser() + { + Id = long.Parse(createUser.Id), + Account = createUser.Account, + //CompanyId = createUser.CompanyId, + //F_DepartmentId = createUser.DepartmentId + }; + } + else + { + //userInfo = await this.CurrentUser(preTask.F_UserId); + userInfo = _auth.GetCurrentUser().User; + } + string nextnode = ""; + if (!string.IsNullOrEmpty(nextid)) + { + nextnode = iWFEngine.GetNode(nextid).Name; + } + + var process = await client.Queryable().FirstAsync(a => a.Id == processId); + + WFInstanceInfo instanceInfo = null; + if (process != null) + { + // instanceInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(process.InstanceInfo); + instanceInfo = process.InstanceInfo; + } + + var param = new + { + processId, + userId = createUser.Id, + userAccount = createUser.Account, + companyId = createUser.CompanyId, + departmentId = createUser.DepartmentId, + userName2 = userInfo.Name, + userId2 = userInfo.Id.ToString(), + userAccount2 = userInfo.Account, + //companyId2 = userInfo.F_CompanyId, + //departmentId2 = userInfo.F_DepartmentId, + code, + nodeName=nextnode, + pkeyValue = instanceInfo == null ? "" : instanceInfo.pkeyValue, + des=des + }; + try + { + var node = iWFEngine.GetNode(task.UnitId); + switch (node.ExecuteType) + { + case "1": + if (!string.IsNullOrEmpty(node.SqlDb) && !string.IsNullOrEmpty(node.SqlStr)) + { + await client.Ado.ExecuteCommandAsync(node.SqlStr, param); + } + break; + case "2": + if (!string.IsNullOrEmpty(node.Ioc) && IocManager.Instance.IsRegistered(node.Ioc)) + { + WorkFlow.IWorkFlowMethod iWorkFlowMethod = IocManager.Instance.GetService(node.Ioc); + WorkFlow.WfMethodParameter wfMethodParameter = new WorkFlow.WfMethodParameter() + { + ProcessId = processId, + UnitName = task.UnitName, + TaskId = prevTaskId, + Code = code, + UserId = createUser.Id, + UserAccount = createUser.Account, + CompanyId = createUser.CompanyId, + DepartmentId = createUser.DepartmentId + }; + await iWorkFlowMethod.Execute(wfMethodParameter); + } + break; + case "3": + if (!string.IsNullOrEmpty(node.ApiUrl)) + { + await HttpMethods.Post(node.ApiUrl, Json.ToJson(param)); + } + break; + + } + + /*脚本执行成功*/ + WFTaskLog wfTaskLogEntity = new WFTaskLog() + { + Des = "脚本执行成功", + TaskType = 99, + ProcessId = processId, + TaskId = task.Id, + UnitId = task.UnitId, + UnitName = task.UnitName + }; + await AddLog(wfTaskLogEntity); + return true; + } + catch (Exception ex) + { + WFTaskLog wfTaskLogEntity = new WFTaskLog() + { + Des = string.Format("脚本执行异常:{0}", ex.Message), + TaskType = 99, + ProcessId = processId, + TaskId = task.Id, + UnitId = task.UnitId, + UnitName = task.UnitName + }; + await AddLog(wfTaskLogEntity); + return false; + } + } + + + /// + /// 执行脚本 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + private async Task ExecuteScript(string processId, string code, WFUserInfo createUser, string executeType, string sqlDb, string sqlStr, string apiUrl, string iocName) + { + var param = new + { + processId, + userId = createUser.Id, + userAccount = createUser.Account, + companyId = createUser.CompanyId, + departmentId = createUser.DepartmentId, + code + }; + + try + { + switch (executeType) + { + case "1": + if (!string.IsNullOrEmpty(sqlDb) && !string.IsNullOrEmpty(sqlStr)) + { + //await wfProcessSerive.BaseRepository(sqlDb).ExecuteSql(sqlStr, param); + await client.Ado.ExecuteCommandAsync(sqlStr, param); + } + break; + case "2": + if (!string.IsNullOrEmpty(iocName) && IocManager.Instance.IsRegistered(iocName)) + { + WorkFlow.IWorkFlowMethod iWorkFlowMethod = IocManager.Instance.GetService(iocName); + WorkFlow.WfMethodParameter wfMethodParameter = new WorkFlow.WfMethodParameter() + { + ProcessId = processId, + Code = code, + UserId = createUser.Id, + UserAccount = createUser.Account, + CompanyId = createUser.CompanyId, + DepartmentId = createUser.DepartmentId + }; + await iWorkFlowMethod.Execute(wfMethodParameter); + } + break; + case "3": + if (!string.IsNullOrEmpty(apiUrl)) + { + await HttpMethods.Post(apiUrl, Json.ToJson(param)); + } + break; + } + return true; + } + catch (Exception ex) + { + return false; + } + } + + + /// + /// 执行脚本(撤销) + /// + /// + /// + /// + /// + /// + /// + private async Task ExecuteRevokeScript(string unitId, string unitName, string processId, WFUserInfo createUser, IWFEngine iWFEngine) + { + var param = new + { + processId, + userId = createUser.Id, + userAccount = createUser.Account, + companyId = createUser.CompanyId, + departmentId = createUser.DepartmentId, + code = "revoke", + }; + try + { + var node = iWFEngine.GetNode(unitId); + switch (node.ExecuteType) + { + case "1": + if (!string.IsNullOrEmpty(node.SqlDb) && !string.IsNullOrEmpty(node.SqlStrRevoke)) + { + //await wfProcessSerive.BaseRepository(node.SqlDb).ExecuteSql(node.SqlStrRevoke, param); + await client.Ado.ExecuteCommandAsync(node.SqlStrRevoke, param); + } + break; + case "2": + if (!string.IsNullOrEmpty(node.IocRevoke) && IocManager.Instance.IsRegistered(node.IocRevoke)) + { + WorkFlow.IWorkFlowMethod iWorkFlowMethod = IocManager.Instance.GetService(node.IocRevoke); + WorkFlow.WfMethodParameter wfMethodParameter = new WorkFlow.WfMethodParameter() + { + ProcessId = processId, + UnitName = unitName, + Code = "revoke", + UserId = createUser.Id, + UserAccount = createUser.Account, + CompanyId = createUser.CompanyId, + DepartmentId = createUser.DepartmentId + }; + await iWorkFlowMethod.Execute(wfMethodParameter); + } + break; + case "3": + if (!string.IsNullOrEmpty(node.ApiUrlRevoke)) + { + await HttpMethods.Post(node.ApiUrlRevoke, Json.ToJson(param)); + } + break; + + } + } + catch (Exception ex) + { + WFTaskLog wfTaskLogEntity = new WFTaskLog() + { + Des = string.Format("脚本执行异常:{0}", ex.Message), + TaskType = 99, + ProcessId = processId, + UnitId = unitId, + UnitName = $"{unitName}-撤销" + }; + await AddLog(wfTaskLogEntity); + + } + + } + + /// + /// 普通审核 + /// + /// + /// + /// + /// + /// 下一个节点 + /// + /// + /// + private async Task AuditNode(IWFEngine iWFEngine, WFTask taskEntity, string code, string name, string des, string stampImg, string nextId = "") + { + // 下一部需要执行的任务 + var taskList = await iWFEngine.GetTask(taskEntity.UnitId, code, nextId); + if (taskList.FindAll(t => t.Type != 10).Count == 0) + { + throw (new Exception("找不到下一个流转节点!")); + } + + List myTaskList; + // 处理任务并更新数据 + using (var uwo = UnitWork.CreateContext()) + { + var process = await uwo.WFProcess.GetByIdAsync(taskEntity.ProcessId); + await uwo.Db.Updateable() + .SetColumns(p => new WFProcess { IsStart = 1, IsCancel = 0 }) + .SetColumnsIF(taskList.FindIndex(t => t.Type == 100) != -1, p => p.IsFinished == 1) + .SetColumnsIF(taskList.FindIndex(t => t.Type == 4) != -1, p => p.IsAgain == 1) + .Where(p => p.Id == taskEntity.ProcessId) + .ExecuteCommandAsync(); + if (taskList.FindIndex(t => t.Type == 100) != -1) + { + if (process.IsChild == 1) + { + await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, code, taskEntity, nextId); + } + } + + // 更新任务状态 + taskEntity.IsAgree = code == "disagree" ? 0 : 1; + taskEntity.State = 3; + if (taskEntity.Type == 7) + { + var currentUser = _auth.GetCurrentUser().User; + taskEntity.UserId = currentUser.Id.ToString(); + taskEntity.UserName = currentUser.Name; + } + await uwo.WFTask.UpdateAsync(taskEntity); + + // 更新上一个流转过来的任务,提示他无法被撤销 + await CloseTaskLogCancel(taskEntity.ProcessId, taskEntity.PrevTaskId); + + // 关闭同一个节点,其他人的任务 + await CloseTask(taskEntity.ProcessId, taskEntity.Token, taskEntity.Id); + + myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, taskEntity.ProcessId, taskEntity.Token, taskEntity.Id); + foreach (var item in myTaskList) + { + if (item.Type == 7) + { + await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); + } + await Add(item); + } + + await CreateTaskLog(taskEntity, code, name, des, stampImg); + + uwo.Commit(); + } + + + // 脚本执行 + var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); + foreach (var item in scriptTaskList) + { + await ExecuteScript(item, code, taskEntity.ProcessId, taskEntity.Id, nextId, iWFEngine.CreateUser, iWFEngine, taskEntity,des); + } + } + + + /// + /// 子流程结束,获取父流程下一任务 + /// + /// 父流程id + /// 父流程的节点id + /// 上一任务code(类似agress,degress) + /// 任务 + /// 下一节点 + /// + private async Task ChildrenEndTask(string processId, string unitId, string code, WFTask taskEntity, string nextId = "") + { + var process = await GetEntity(processId); + var iWFEngine = await Bootstraper("", processId, null, null); + // 下一部需要执行的任务 + var taskList = await iWFEngine.GetTask(unitId, code, nextId); + if (taskList.FindAll(t => t.Type != 10).Count == 0) + { + throw (new Exception("找不到下一个流转节点!")); + } + + // 处理任务并更新数据 + //wfProcessSerive.BeginTrans(); + List myTaskList; + using (var uwo = UnitWork.CreateContext()) + { + try + { + // 更新流程状态 + await uwo.Db.Updateable() + .SetColumns(p => new WFProcess { IsStart = 1, IsCancel = 0 }) + .SetColumnsIF(taskList.FindIndex(t => t.Type == 100) != -1, p => p.IsFinished == 1) + .SetColumnsIF(taskList.FindIndex(t => t.Type == 4) != -1, p => p.IsAgain == 1) + .Where(p => p.Id == processId) + .ExecuteCommandAsync(); + + if (taskList.FindIndex(t => t.Type == 100) != -1) + { + if (process.IsChild == 1) + { + await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, code, taskEntity, nextId); + } + } + + myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, taskEntity.Token, taskEntity.Id); + foreach (var item in myTaskList) + { + if (item.Type == 7) + { + await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); + } + await Add(item); + } + } + catch + { + throw; + } + uwo.Commit(); + } + // 脚本执行 + var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); + foreach (var item in scriptTaskList) + { + await ExecuteScript(item, code, processId, taskEntity.Id, nextId, iWFEngine.CreateUser, iWFEngine, taskEntity,""); + } + } + + + private async Task AuditNodeByCountersign(IWFEngine iWFEngine, WFTask taskEntiy, string code, string name, string des, string stampImg) + { + taskEntiy.IsAgree = code == "disagree" ? 0 : 1; + var node = iWFEngine.GetNode(taskEntiy.UnitId); + var list = (List)await GetLastTaskList(taskEntiy.ProcessId, taskEntiy.UnitId); + var myIndex = list.FindIndex(t => t.Id == taskEntiy.Id); + if (myIndex == -1) + { + throw (new Exception("会签任务记录异常无法审核!")); + } + + if (taskEntiy.IsAgree == 0) + { + if (node.CountersignType == "1") + { + // 并行 + if (node.IsCountersignAll) + { + // 等待 + if (list.FindIndex(t => t.Id != taskEntiy.Id && t.State == 1) != -1) + { + // 表示还有人没有审核 + // 表示还有任务没有完成 + using (var uwo = UnitWork.CreateContext()) + { + WFProcess processEntity = new WFProcess() + { + Id = taskEntiy.ProcessId, + IsStart = 1, + IsCancel = 0, + }; + await uwo.WFProcess.UpdateAsync(processEntity); + taskEntiy.State = 3; + await uwo.WFTask.UpdateAsync(taskEntiy); + await CreateTaskLog(taskEntiy, code, name, des, stampImg); + + uwo.Commit(); + } + } + else + { + var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId); + var fnum = list.FindAll(t => t.State == 3 && t.IsAgree == 0).Count + 1; + if ((num - fnum) * 100 / num >= node.CountersignAllType) + { + await AuditNode(iWFEngine, taskEntiy, "agree", "同意", des, stampImg); + } + else + { + await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg); + } + } + } + else + { + // 不等待,每次都需要计算通过率 + var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId); + var fnum = list.FindAll(t => t.State == 3 && t.IsAgree == 0).Count + 1; + if ((num - fnum) * 100 / num >= node.CountersignAllType)// 表示还有通过的希望 + { + using (var uwo = UnitWork.CreateContext()) + { + WFProcess processEntity = new WFProcess() + { + Id = taskEntiy.ProcessId, + IsStart = 1, + IsCancel = 0, + }; + await uwo.WFProcess.UpdateAsync(processEntity); + taskEntiy.State = 3; + await uwo.WFTask.UpdateAsync(taskEntiy); + await CreateTaskLog(taskEntiy, code, name, des, stampImg); + + uwo.Commit(); + } + } + else + { + await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg); + } + } + } + else + { + // 串行 + await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg); + } + } + else + { + if (node.CountersignType == "1") + { + // 并行 + + // 如果不等待,不同意直接跳转 + if (node.IsCountersignAll) + { + if (list.FindIndex(t => t.Id != taskEntiy.Id && t.State == 1) != -1) // 表示还有人没有处理完 + { + // 表示还有任务没有完成 + using (var uwo = UnitWork.CreateContext()) + { + WFProcess processEntity = new WFProcess() + { + Id = taskEntiy.ProcessId, + IsStart = 1, + IsCancel = 0, + }; + await uwo.WFProcess.UpdateAsync(processEntity); + taskEntiy.State = 3; + await uwo.WFTask.UpdateAsync(taskEntiy); + await CreateTaskLog(taskEntiy, code, name, des, stampImg); + uwo.Commit(); + } + } + else + { + var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId); + var fnum = list.FindAll(t => t.State == 3 && t.IsAgree == 0).Count; + if ((num - fnum) * 100 / num >= node.CountersignAllType) + { + await AuditNode(iWFEngine, taskEntiy, "agree", "同意", des, stampImg); + } + else + { + await AuditNode(iWFEngine, taskEntiy, "disagree", "不同意", des, stampImg); + } + } + } + else + { + var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId); + var snum = list.FindAll(t => t.State == 3 && t.IsAgree == 1).Count; + if (snum * 100 / num >= node.CountersignAllType) + { + await AuditNode(iWFEngine, taskEntiy, "agree", "同意", des, stampImg); + } + else + { + using (var uwo = UnitWork.CreateContext()) + { + WFProcess processEntity = new WFProcess() + { + Id = taskEntiy.ProcessId, + IsStart = 1, + IsCancel = 0, + }; + await uwo.WFProcess.UpdateAsync(processEntity); + taskEntiy.State = 3; + await uwo.WFTask.UpdateAsync(taskEntiy); + await CreateTaskLog(taskEntiy, code, name, des, stampImg); + + uwo.Commit(); + } + } + } + } + else + { + // 串行 + if (myIndex == list.Count - 1) // 表示最后一个人审核完成,然后往下执行 + { + await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg); + } + else + { + // 表示还有任务没有完成 + using (var uwo = UnitWork.CreateContext()) + { + WFProcess processEntity = new WFProcess() + { + Id = taskEntiy.ProcessId, + IsStart = 1, + IsCancel = 0, + }; + await uwo.WFProcess.UpdateAsync(processEntity); + taskEntiy.State = 3; + await uwo.WFTask.UpdateAsync(taskEntiy); + await CreateTaskLog(taskEntiy, code, name, des, stampImg); + + + if (node.CountersignType == "2") + { + // 串行,更新上一个任务的撤销操作,开启下一个任务 + if (myIndex == 0) + { + await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId); + } + else + { + await CloseTaskLogCancel(list[myIndex - 1].Id); + } + await uwo.WFTask.UpdateAsync(new WFTask { Id = list[myIndex + 1].Id, State = 1 }); + } + var flag = uwo.Commit(); + } + } + } + } + } + + /// + /// 创建日志 + /// + /// + /// + /// + /// + /// + /// + private async Task CreateTaskLog(WFTask taskEntiy, string code, string name, string des, string stampImg) + { + + WFTaskLog wfTaskLogEntity = new WFTaskLog() + { + Des = $"【{name}】{des}", + TaskType = taskEntiy.Type, + ProcessId = taskEntiy.ProcessId, + UnitId = taskEntiy.UnitId, + UnitName = taskEntiy.UnitName, + IsAgree = taskEntiy.IsAgree, + OperationCode = code, + OperationName = name, + Token = taskEntiy.Token, + PrevUnitId = taskEntiy.PrevUnitId, + PrevUnitName = taskEntiy.PrevUnitName, + TaskId = taskEntiy.Id, + StampImg = stampImg, + IsCancel = 1, + IsLast = 1 + + }; + + await UpdateLog(taskEntiy.ProcessId, taskEntiy.UnitId); + await AddLog(wfTaskLogEntity); + } + #endregion + + + public async Task> Supervise(string processId,int supervise = 1) + { + // todo 实现督办 + + var iWFEngine = await Bootstraper(string.Empty, processId, null, null); + // 获取未完成的任务 + var taskList = await GetUnFinishTaskList(processId); + using (var uwo = UnitWork.CreateContext()) + { + + foreach (var item in taskList) + { + if (item.Type == 1 || item.Type == 3 || item.Type == 5 || item.Type == 6 || item.Type == 7) + { + + // 督办时间督办标志 + item.IsSupervise = supervise; + item.SuperviseTime = DateTime.Now; + item.SuperviseId = _auth.GetCurrentUser().User.Id; + // 发送消息 + var msg = $"【审核】【督办】{item.ProcessTitle},{item.UnitName}"; + var userList = new List(); + // todo 单体任务处理 + userList.Add(item.UserId); + var node = iWFEngine.GetNode(item.UnitId); + //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, item.F_Token); + + await uwo.WFTask.UpdateAsync(item); + } + } + + //await wfProcessSerive.Update(new WFProcessEntity() { F_IsUrge = 1, F_Id = processId }); + + var wfTaskLogEntity = new WFTaskLog + { + Des = "督办审核", + TaskType = 98, + ProcessId = processId, + UnitId = iWFEngine.StartNode.Id, + UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name, + CreateDate = DateTime.Now, + UserId = _auth.GetUserId(), + UserName = _auth.GetUserNickName(), + Id = Guid.NewGuid().ToString() + }; + + await uwo.WFTaskLog.InsertAsync(wfTaskLogEntity); + + var flag = uwo.Commit(); + return new Response + { + Result = flag, + Message = flag ? "success" : "error" + }; + } + + } + + + + #region 撤回 + /// + /// 撤回流程 + /// + /// 流程任务主键 + /// 流程审批操作码agree 同意 disagree 不同意 lrtimeout 超时 + /// 流程审批操名称 + /// 审批意见 + /// 下一节点指定审核人 + /// 盖章图片 + /// 盖章图片密码 + /// 下一个审核节点 + public async Task RetractFlow(string taskId, string code, string name, string des, Dictionary nextUsers, string stampImg, string stampPassWord, string nextId) + { + var taskEntiy = await client.Queryable().Where(a => a.Id == taskId).FirstAsync(); + if (taskEntiy == null) + { + throw (new Exception("找不到对应流程任务!")); + } + else if (taskEntiy.State != 3&& taskEntiy.State != 4) + { + throw (new Exception("该任务未完成!")); + } + + //后期改 + stampImg = ""; + //stampImg = await _wFStampIBLL.ToWfImg(stampImg, stampPassWord); + + var iWFEngine = await Bootstraper("", taskEntiy.ProcessId, null, nextUsers); + + // 1.判断任务类型 1 普通任务 5 会签任务 + if (taskEntiy.Type == 1 || taskEntiy.Type == 7) + { + await RetractNode(iWFEngine, taskEntiy, code, name, des, stampImg, nextId); + } + else + { + throw (new Exception("该任务无法审核!")); + } + + //await _imMsgIBLL.VirtualDeleteByContentId(taskEntiy.F_Token); // 更新消息 + + // 发送消息 + var msg = $"【提醒】{iWFEngine.Config.Params.Title},{taskEntiy.UnitName}已被撤回"; + var userList = new List(); + userList.Add(iWFEngine.CreateUser.Id); + var node = iWFEngine.StartNode; + //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, iWFEngine.Config.Params.ProcessId); + } + + /// + /// 撤回 + /// + /// + /// + /// + /// + /// 下一个节点 + /// + /// + /// + private async Task RetractNode(IWFEngine iWFEngine, WFTask taskEntity, string code, string name, string des, string stampImg, string nextId = "") + { + // 下一部需要执行的任务 + var taskList = await iWFEngine.GetTask(taskEntity.UnitId, code, nextId); + + List myTaskList; + //修改原有任务的IsLast状态 + await client.Updateable() + .SetColumns(t => new WFTask() { IsLast = 0 }) + .Where(t => t.Id==taskEntity.Id) + .ExecuteCommandAsync(); + + //删除该节点之后生成的所有任务 + var dellist=client.Queryable().Where(r=>r.CreateDate>taskEntity.CreateDate&&r.ProcessId==taskEntity.ProcessId).ToList(); + await client.Deleteable(dellist).ExecuteCommandAsync(); + // 处理任务并更新数据 + using (var uwo = UnitWork.CreateContext()) + { + var process = await uwo.WFProcess.GetByIdAsync(taskEntity.ProcessId); + await uwo.Db.Updateable() + .SetColumns(p => new WFProcess { IsStart = 1, IsCancel = 0 }) + .SetColumns(p=>p.IsFinished==0) + .SetColumnsIF(taskList.FindIndex(t => t.Type == 100) != -1, p => p.IsFinished == 1) + .SetColumnsIF(taskList.FindIndex(t => t.Type == 4) != -1, p => p.IsAgain == 1) + .Where(p => p.Id == taskEntity.ProcessId) + .ExecuteCommandAsync(); + if (taskList.FindIndex(t => t.Type == 100) != -1) + { + if (process.IsChild == 1) + { + await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, code, taskEntity, nextId); + } + } + + var newTask = new WFTask + { + Id = Guid.NewGuid().ToString(), + Type = taskEntity.Type, + ProcessId = taskEntity.ProcessId, + Token = Guid.NewGuid().ToString(), + UnitId = taskEntity.UnitId, + UnitName = taskEntity.UnitName, + PrevUnitId = taskEntity.PrevUnitId, + PrevUnitName = taskEntity.PrevUnitName, + PrevToken = taskEntity.Token, + PrevTaskId = taskEntity.Id, + UserId = taskEntity.UserId, + UserName = taskEntity.UserName, + UserDepartmentId = taskEntity.UserDepartmentId, + UserCompanyId = taskEntity.UserCompanyId, + State = 1, + Sort = taskEntity.Sort, + IsReject = 0, + ChildProcessId = taskEntity.ChildProcessId, + ChildSchemeInfoCode = taskEntity.ChildSchemeInfoCode, + + TimeoutInterval = taskEntity.TimeoutInterval, + TimeoutStrategy = taskEntity.TimeoutStrategy, + + IsBatchAudit = taskEntity.IsBatchAudit, + ProcessUserId = iWFEngine.CreateUser.Id, + ProcessUserName = iWFEngine.CreateUser.Name, + ProcessCode = iWFEngine.Config.Params.SchemeCode, + ProcessTitle = iWFEngine.Config.Params.Title, + CreateDate = DateTime.Now, + CreateUserId = _auth.GetUserId(), + CreateUserName = _auth.GetUserName(), + IsLast=1, + IsRetract=1 + }; + await uwo.WFTask.InsertAsync(newTask); + + // 更新上一个流转过来的任务,提示他无法被撤销 + await CloseTaskLogCancel(taskEntity.ProcessId, taskEntity.PrevTaskId); + + // 关闭同一个节点,其他人的任务 + await CloseTask(taskEntity.ProcessId, taskEntity.Token, taskEntity.Id); + + myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, taskEntity.ProcessId, taskEntity.Token, taskEntity.Id); + foreach (var item in myTaskList) + { + if (item.Type == 7) + { + await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); + } + await Add(item); + } + + await CreateTaskLog(taskEntity, code, name, des, stampImg); + + uwo.Commit(); + } + + + // 脚本执行 + var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); + foreach (var item in scriptTaskList) + { + await ExecuteScript(item, code, taskEntity.ProcessId, taskEntity.Id, nextId, iWFEngine.CreateUser, iWFEngine, taskEntity, des); + } + } + + + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/WFProcessApp1.cs b/OpenAuth.App/BaseApp/WFProcess/WFProcessApp1.cs new file mode 100644 index 0000000..9f9e52a --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/WFProcessApp1.cs @@ -0,0 +1,239 @@ +using Infrastructure; +using Infrastructure.Extensions; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public partial class WFProcessApp + { + #region 任务 + + public async Task> GetListByKeyValues(string[] keyValues) + { + return await client.Queryable().Where(t => keyValues.Contains(t.Id.ToString())).ToListAsync(); + //return await client.Queryable().Where(t => t.DeleteMark == 0 && keyValues.Contains(t.Id.ToString())); + } + + public async Task CloseTask(string processId, string token, string taskId) + { + var expression = Expressionable.Create() + .And(t => t.ProcessId == processId && t.Token == token) + .AndIF(!string.IsNullOrEmpty(taskId), t => t.Id != taskId).ToExpression(); + + + + + await client.Updateable().SetColumns(a => new WFTask() { State = 4 }) + .Where(expression) + .ExecuteCommandAsync(); + } + + public async Task CloseTaskLogCancel(string processId, string taskId) + { + await client.Updateable() + .SetColumns(a => new WFTaskLog { IsCancel = 0 }) + .Where(a => a.ProcessId == processId && a.TaskId == taskId).ExecuteCommandAsync(); + } + + public async Task CloseTaskLogCancel(string taskId) + { + await client.Updateable() + .SetColumns(a => new WFTaskLog { IsCancel = 0 }) + .Where(a => a.TaskId == taskId).ExecuteCommandAsync(); + } + + public async Task GetTaskUserMaxNum(string processId, string unitId) + { + StringBuilder strSql = new StringBuilder(); + strSql.Append(" select conut(1) from wf_task t where ProcessId = @processId AND UnitId =@unitId AND (Type = 1 OR Type = 3 OR Type = 5) {LEARUN_SASSID} group by Token order by conut(1) "); + + var pars = client.Ado.GetParameters(new { processId, unitId }); + var data = await client.Ado.GetDataTableAsync(strSql.ToString(), pars); + + if (data.Rows.Count > 0) + { + return (data.Rows[0][0]).ToInt(); + } + else + { + return 0; + } + } + + public Task> GetLastFinishTaskList(string processId, string unitId) + { + return client.Queryable().Where(t => t.ProcessId == processId && t.UnitId == unitId && (t.Type == 1||t.Type==7) && t.IsLast == 1 && t.State == 3).ToListAsync(); + } + + public async Task> GetLastTaskList(string processId, string unitId) + { + return await client.Queryable() + .Where(t => t.ProcessId == processId && t.UnitId == unitId && t.IsLast == 1 && (t.Type == 1 || t.Type == 3 || t.Type == 4 || t.Type == 5||t.Type==7)) + .OrderBy(t => t.Sort) + .ToListAsync(); + } + + + + public async Task GetLastNotRejectTask(string processId, string unitId) + { + return await client.Queryable() + .Where(t => t.ProcessId == processId + && t.UnitId == unitId + && t.IsReject != 1 + && t.IsRetract!=1 + && (t.Type == 1 || t.Type == 3 || t.Type == 5||t.Type==7)) + .OrderByDescending(t => t.CreateDate) + .FirstAsync(); + } + + //public async Task CloseTask(string processId, string token, string taskId) + //{ + + // await client.Updateable() + // .SetColumns(t => new WFTask() { State = 4 }) + // .Where(t => t.ProcessId == processId && t.Token == token) + // .WhereIF(!string.IsNullOrEmpty(taskId), t => t.Id != taskId) + // .ExecuteCommandAsync(); + //} + + public async Task CloseTask(string processId, string unitId, int type, string taskId) + { + await client.Updateable() + .SetColumns(t => new WFTask() { State = 4, UpdateTaskId = taskId }) + .Where(t => t.ProcessId == processId && t.UnitId == unitId && t.Type == type) + .ExecuteCommandAsync(); + } + + public async Task Update(string processId, string unitId) + { + await client.Updateable() + .SetColumns(t => new WFTask() { IsLast = 0 }) + .Where(t => t.ProcessId == processId && t.UnitId == unitId) + .ExecuteCommandAsync(); + } + + public async Task Add(WFTask wfTaskEntity) + { + wfTaskEntity.CreateDate = DateTime.Now; + wfTaskEntity.CreateUserId = _auth.GetUserId(); + wfTaskEntity.CreateUserName = _auth.GetUserName(); + wfTaskEntity.Id= string.IsNullOrEmpty(wfTaskEntity.Id)?Guid.NewGuid().ToString(): wfTaskEntity.Id; + wfTaskEntity.IsLast = 1; + var flag= await client.Insertable(wfTaskEntity).ExecuteCommandAsync(); + //if (flag!=0&&wfTaskEntity.TimeoutNotice!=null&&wfTaskEntity.TimeoutInterval!=0) + //{ + // DateTime outtime=(DateTime)wfTaskEntity.TimeoutNotice; + // DateTime overtime = outtime.AddHours((int)wfTaskEntity.TimeoutInterval); + // AddOpenJob(wfTaskEntity, outtime, overtime); + //} + } + + public async Task> GetUnFinishTaskList(string processId) + { + return await client.Queryable().Where(t => t.ProcessId == processId && t.State == 1 && (t.Type == 1 || t.Type == 2 || t.Type == 3 || t.Type == 4 || t.Type == 5 || t.Type == 6||t.Type==7)).ToListAsync(); + } + + public async Task> GetList(string processId, int type, string prevTaskId) + { + return await client.Queryable().Where(t => t.ProcessId == processId && t.Type == type && t.PrevTaskId == prevTaskId).ToListAsync(); + } + + public async Task GetTaskEntity(string keyValue) + { + return await client.Queryable() + .Where(a => a.Id == keyValue).FirstAsync(); + } + + public async Task Delete(string processId, string prevTaskId) + { + await client.Deleteable().Where(t => t.ProcessId == processId && t.PrevTaskId == prevTaskId).ExecuteCommandAsync(); + } + + public async Task DeleteByFirstId(string id) + { + await client.Deleteable().Where(t => t.FirstId == id).ExecuteCommandAsync(); + } + + public async Task OpenTask(string processId, string unitId, int type, string taskId) + { + await client.Updateable().SetColumns(a => new WFTask { State = 1, UpdateTaskId = taskId }) + .Where(t => t.ProcessId == processId && t.UnitId == unitId && t.Type == type) + .ExecuteCommandAsync(); + } + #endregion + + #region 日志 + + public async Task AddLog(WFTaskLog wfTaskLogEntity) + { + wfTaskLogEntity.CreateDate = DateTime.Now; + wfTaskLogEntity.UserId = _auth.GetUserId(); + wfTaskLogEntity.UserName = _auth.GetUserNickName(); + wfTaskLogEntity.Id = Guid.NewGuid().ToString(); + await client.Insertable(wfTaskLogEntity).ExecuteCommandAsync(); + } + public async Task> GetLogList(string processId, string unitId) + { + return await client.Queryable() + .Where(t => t.ProcessId == processId && t.UnitId == unitId) + .OrderByDescending(t => t.CreateDate) + .ToListAsync(); + } + + public async Task UpdateLog(string processId, string unitId) + { + var userId = _auth.GetUserId(); + + await this.client.Updateable() + .SetColumns(t => new WFTaskLog { IsLast = 0 }) + .Where(t => t.ProcessId == processId && t.UnitId == unitId && t.IsLast == 1 && t.UserId == userId) + .ExecuteCommandAsync(); + } + + public async Task GetLogEntity(string taskId) + { + return await client.Queryable().Where(t => t.TaskId == taskId).FirstAsync(); + } + + public async Task DeleteLog(string processId, string taskId) + { + await client.Deleteable().Where(t => t.ProcessId == processId && t.TaskId == taskId && t.IsLast == 1).ExecuteCommandAsync(); + } + + public async Task DeleteLogByTaskId(string taskId) + { + await client.Deleteable().Where(t => t.TaskId == taskId).ExecuteCommandAsync(); + } + + public async Task Delete(string processId) + { + await client.Deleteable().Where(t => t.ProcessId == processId).ExecuteCommandAsync(); + } + #endregion + + public async Task GetUserInfo(string userId) + { + if (userId == "-1") + { + return new SysUser + { + Account = Define.SYSTEM_USERNAME, + Name = "超级管理员", + Id = -1 + }; + } + else + { + return await client.Queryable().FirstAsync(a => a.Id.ToString() == userId); + } + + } + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/WFScheme.cs b/OpenAuth.App/BaseApp/WFProcess/WFScheme.cs new file mode 100644 index 0000000..8644a06 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/WFScheme.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.WorkFlow +{ + public class WFScheme + { + /// + /// 流程图数据 + /// + public List WfData { get; set; } + /// + /// 撤销执行 动作类型 1执行SQL 2.NET方法 3第三方接口 + /// + public string UndoType { get; set; } + /// + /// 撤销执行 数据库编码 + /// + public string UndoDbCode { get; set; } + /// + /// 撤销执行 SQL语句 + /// + public string UndoDbSQL { get; set; } + /// + /// 撤销执行 .NET注入类名 + /// + public string UndoIOCName { get; set; } + /// + /// 撤销执行 接口地址 + /// + public string UndoUrl { get; set; } + + + /// + /// 作废操作 动作类型 1执行SQL 2.NET方法 3第三方接口 + /// + public string DeleteType { get; set; } + /// + /// 作废操作 数据库编码 + /// + public string DeleteDbCode { get; set; } + /// + /// 作废操作 SQL语句 + /// + public string DeleteDbSQL { get; set; } + /// + /// 作废操作 .NET注入类名 + /// + public string DeleteIOCName { get; set; } + /// + /// 作废操作 接口地址 + /// + public string DeleteUrl { get; set; } + + /// + /// 删除草稿 动作类型 1执行SQL 2.NET方法 3第三方接口 + /// + public string DeleteDraftType { get; set; } + /// + /// 删除草稿 数据库编码 + /// + public string DeleteDraftDbCode { get; set; } + /// + /// 删除草稿 SQL语句 + /// + public string DeleteDraftDbSQL { get; set; } + /// + /// 删除草稿 .NET注入类名 + /// + public string DeleteDraftIOCName { get; set; } + /// + /// 删除草稿 接口地址 + /// + public string DeleteDraftUrl { get; set; } + + + + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/WFTask.cs b/OpenAuth.App/BaseApp/WFProcess/WFTask.cs new file mode 100644 index 0000000..a4c3e41 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/WFTask.cs @@ -0,0 +1,113 @@ +using OpenAuth.App.Config; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.WorkFlow +{ + public class WFTask + { + /// + /// 流程单元ID + /// + public string UnitId { get; set; } + /// + /// 任务名称 + /// + public string Name { get; set; } + /// + /// 任务令牌 + /// + public string Token { get; set; } + /// + /// 任务类型 1.审核任务 2传阅任务 3.子流程 4.重新创建 5.会签任务 10.脚本任务 21.等待任务(系统自己完成)22.取消等待任务 23.找不到审核人直接跳过 24.自动审核规则跳过 25.会签任务记录 26 更新任务状态 100 结束任务 + /// + public int Type { get; set; } + /// + /// 上一个流程单元ID + /// + public string PrevUnitId { get; set; } + /// + /// 上一个流程单元名称 + /// + public string PrevUnitName { get; set; } + /// + /// 是否是驳回任务 + /// + public bool IsReject { get; set; } + /// + /// 是否允许批量审核 + /// + public bool IsBatchAudit { get; set; } + + /// + /// 通知策略 1.短信 2.邮箱 3.微信 4.IM + /// + public string MessageType { get; set; } + + /// + /// 是否超时通知 + /// + public bool IsOvertimeMessage { get; set; } + /// + /// 第一次通知 单位(时) + /// + public int OvertimeMessageStart { get; set; } + /// + /// 间隔通知 单位(时) + /// + public int OvertimeMessageInterval { get; set; } + /// + /// 超时流转时间 单位(时) + /// + public int OvertimeGo { get; set; } + /// + /// 超时通知策略 1.短信 2.邮箱 3.微信 4.IM + /// + public string OvertimeMessageType { get; set; } + + /// + /// 脚本执行类型 1SQL 2接口 3IOC + /// + public string ExecuteType { get; set; } + /// + /// 执行SQL数据库编码 + /// + public string SqlDb { get; set; } + /// + /// 执行SQL语句 + /// + public string SqlStr { get; set; } + /// + /// 撤回的时候执行SQL语句 + /// + public string SqlStrRevoke { get; set; } + /// + /// 调用接口 + /// + public string ApiUrl { get; set; } + /// + /// 撤回的时候调用接口 + /// + public string ApiUrlRevoke { get; set; } + /// + /// 注入类名 + /// + public string Ioc { get; set; } + /// + /// 撤回的时候注入类名 + /// + public string IocRevoke { get; set; } + + /// + /// 处理人信息 + /// + public WFUserInfo User { get; set; } + /// + /// 子流程的流程模板id + /// + public string ChildSchemeInfoId { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/WFUnit.cs b/OpenAuth.App/BaseApp/WFProcess/WFUnit.cs new file mode 100644 index 0000000..5aca1ed --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/WFUnit.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App +{ + public class WFUnit + { + #region 节点原始属性 + /// + /// 流程单元类型 + /// 线条 myline + /// 开始节点 startEvent + /// 结束节点 endEvent + /// 并行网关 gatewayAnd 并行网关会等待所有分支汇入才往下执行,所有出口分支都会被执行 + /// 排他网关 gatewayXor 排他网关不会等待所有分支汇入才往下执行,只要有分支汇入就会往下执行,出口分支只会执行一条(条件为true,如果多条出口分支条件为true也执行一条) + /// 包容网关 gatewayInclusive 包容网关会等待所有分支汇入才往下执行,出口分支能执行多条(条件为true) + /// 审核节点 userTask + /// 脚本节点 scriptTask + /// 子流程节点 subprocess + /// + public string Type { get; set; } + /// + /// 流程单元id + /// + public string Id { get; set; } + /// + /// 节点名称 + /// + public string Name { get; set; } + /// + /// 流出节点ID + /// + public string From { get; set; } + /// + /// 流入节点ID + /// + public string To { get; set; } + #endregion + /// + /// 通知策略 1.短信 2.邮箱 3.微信 4.IM + /// + public string MessageType { get; set; } + /// + /// 条件节点执行条件 + /// + public List Conditions { get; set; } + /// + /// 是否允许加签 + /// + public bool IsAddSign { get; set; } + /// + /// 是否允许单任务 + /// + public bool IsSingleTask { get; set; } + /// + /// 是否允许批量审核 + /// + public bool IsBatchAudit { get; set; } + /// + /// 自动同意规则 1.处理人就是提交人 2.处理人和上一步的处理人相同 3.处理人审批过 + /// + public string AutoAgree { get; set; } + /// + /// 无对应处理人 1.超级管理员处理 2.跳过此步骤 3.不能提交 + /// + public string NoAuditor { get; set; } + /// + /// 驳回策略 1.驳回节点固定 2.能驳回到任何执行过节点 + /// + public string RejectType { get; set; } + /// + /// 审核人 + /// + public List AuditUsers { get; set; } + /// + /// 传阅人 + /// + public List LookUsers { get; set; } + /// + /// 是否会签 + /// + public bool IsCountersign { get; set; } + /// + /// 是否等待所有人审核完 + /// + public bool IsCountersignAll { get; set; } + /// + /// 通过百分比 + /// + public int CountersignAllType { get; set; } + /// + /// 审核方式 1.并行 2.串行 + /// + public string CountersignType { get; set; } + /// + /// 再次审核 1.已同意不需要审核 2.已同意需要审核 + /// + public string CountersignAgian { get; set; } + + /// + /// 是否超时通知 + /// + public bool IsOvertimeMessage { get; set; } + /// + /// 第一次通知 单位(时) + /// + public int OvertimeMessageStart { get; set; } + /// + /// 间隔通知 单位(时) + /// + public int OvertimeMessageInterval { get; set; } + /// + /// 超时流转时间 单位(时) + /// + public int OvertimeGo { get; set; } + + /// + /// 超时通知策略 1.短信 2.邮箱 3.微信 4.IM + /// + public string OvertimeMessageType { get; set; } + /// + /// 脚本执行类型 1SQL 2接口 3IOC + /// + public string ExecuteType { get; set; } + /// + /// 执行SQL数据库编码 + /// + public string SqlDb { get; set; } + /// + /// 执行SQL语句 + /// + public string SqlStr { get; set; } + /// + /// 撤回的时候执行SQL语句 + /// + public string SqlStrRevoke { get; set; } + /// + /// 调用接口 + /// + public string ApiUrl { get; set; } + /// + /// 撤回的时候调用接口 + /// + public string ApiUrlRevoke { get; set; } + /// + /// 注入类名 + /// + public string Ioc { get; set; } + /// + /// 撤回的时候注入类名 + /// + public string IocRevoke { get; set; } + /// + /// 是否异步 + /// + public bool IsAsync { get; set; } + /// + /// 流程模板ID + /// + public string WfschemeId { get; set; } + /// + /// 线条流转条件 + /// + public string LineConditions { get; set; } + + } +} diff --git a/OpenAuth.App/BaseApp/WFProcess/WfMethodParameter.cs b/OpenAuth.App/BaseApp/WFProcess/WfMethodParameter.cs new file mode 100644 index 0000000..b8c92e2 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFProcess/WfMethodParameter.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.WorkFlow +{ + public class WfMethodParameter + { + /// + /// 流程进程Id + /// + public string ProcessId { get; set; } + /// + /// 子流程进程主键 + /// + public string ChildProcessId { get; set; } + /// + /// 当前任务Id + /// + public string TaskId { get; set; } + /// + /// 当前节点名称 + /// + public string UnitName { get; set; } + /// + /// 操作码 + /// + public string Code { get; set; } + /// + /// 当前操作用户 + /// + public string UserId { get; set; } + /// + /// 当前用户账号 + /// + public string UserAccount { get; set; } + /// + /// 当前用户公司 + /// + public string CompanyId { get; set; } + /// + /// 当前用户部门 + /// + public string DepartmentId { get; set; } + + } +} diff --git a/OpenAuth.App/BaseApp/WFSchemeInfo/Response/WFSchemeDto.cs b/OpenAuth.App/BaseApp/WFSchemeInfo/Response/WFSchemeDto.cs new file mode 100644 index 0000000..3332d44 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFSchemeInfo/Response/WFSchemeDto.cs @@ -0,0 +1,25 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Response +{ + public class WFSchemeDto + { + /// + /// 基础信息 + /// + public WFSchemeInfo Schemeinfo { get; set; } + /// + /// 权限信息 + /// + public List SchemeAuthList { get; set; } + /// + /// 模板信息 + /// + public WFScheme Scheme { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFSchemeInfo/WFSchemeApp.cs b/OpenAuth.App/BaseApp/WFSchemeInfo/WFSchemeApp.cs new file mode 100644 index 0000000..53d781b --- /dev/null +++ b/OpenAuth.App/BaseApp/WFSchemeInfo/WFSchemeApp.cs @@ -0,0 +1,57 @@ +using OpenAuth.App.Base; +using OpenAuth.Repository.Domain; +using OpenAuth.Repository; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using OpenAuth.App.Interface; +using Infrastructure; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Request; + +namespace OpenAuth.App +{ + public class WFSchemeApp : SqlSugarBaseApp + { + ISqlSugarClient client; + public WFSchemeApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + client = base.Repository.AsSugarClient(); + } + + + + public async Task>> GetSchemePageList(PageReq pageReq, string schemeInfoId) + { + RefAsync totalCount = 0; + + var list = await client.Queryable() + .Where(a => a.SchemeInfoId == schemeInfoId) + .OrderByDescending(a => a.CreateDate) + .ToPageListAsync(pageReq.page, pageReq.limit, totalCount); + + return new PageInfo> + { + Items = list, + Total = totalCount + }; + } + + + /// + /// 获取模板列表 + /// + /// 流程信息主键 + /// + public async Task> GetSchemeList(string schemeInfoId) + { + return await client.Queryable() + .Where(t => t.SchemeInfoId == schemeInfoId) + .OrderByDescending(t => t.CreateDate) + .ToListAsync(); + } + } +} diff --git a/OpenAuth.App/BaseApp/WFSchemeInfo/WFSchemeInfoApp.cs b/OpenAuth.App/BaseApp/WFSchemeInfo/WFSchemeInfoApp.cs new file mode 100644 index 0000000..b872f97 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFSchemeInfo/WFSchemeInfoApp.cs @@ -0,0 +1,292 @@ +using Infrastructure; +using Infrastructure.Helpers; +using Microsoft.Extensions.Configuration; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App +{ + public class WFSchemeInfoApp : SqlSugarBaseApp + { + ISqlSugarClient client; + private IConfiguration configuration; + + public WFSchemeInfoApp( + ISugarUnitOfWork unitWork, + ISimpleClient repository, + IAuth auth, IConfiguration configuration) : base(unitWork, repository, auth) + { + client = base.Repository.AsSugarClient(); + this.configuration = configuration; + } + + public async Task>> LoadPage(PageReq pageReq, string category, string ids) + { + RefAsync totalCount = 0; + + var idList = new string[0]; + if (!string.IsNullOrEmpty(ids)) + { + idList = ids.Split(','); + } + + var list = await client.Queryable() + .LeftJoin((info, s) => info.SchemeId == s.Id) + .WhereIF(!string.IsNullOrEmpty(pageReq.key), + info => info.Name.Contains(pageReq.key) || info.Code.Contains(pageReq.key)) + .WhereIF(!string.IsNullOrEmpty(category), info => info.Category == category) + .WhereIF(!string.IsNullOrEmpty(ids), info => idList.Contains(info.Id)) + .OrderByDescending((info, s) => s.CreateDate) + .Select((info, s) => new WFSchemeInfo() + { + AuthType = info.AuthType, + Id = info.Id, + Category = info.Category, + Code = info.Code, + Color = info.Color, + Description = info.Description, + EnabledMark = info.EnabledMark, + Icon = info.Icon, + IsInApp = info.IsInApp, + Mark = info.Mark, + Name = info.Name, + SchemeId = info.SchemeId, + + Type = s.Type, + CreateDate = s.CreateDate, + CreateUserId = s.CreateUserId, + CreateUserName = s.CreateUserName + }).ToPageListAsync(pageReq.page, pageReq.limit, totalCount); + + return new PageInfo> + { + Items = list, + Total = totalCount + }; + } + + public async Task> Load() + { + return await base.Repository.GetListAsync(a => a.EnabledMark == 1); + } + + public async Task> GetInfoList() + { + var currentUser = _auth.GetCurrentUser(); + + var userId = currentUser.User.Id.ToString(); + var postIds = currentUser.Positions.Select(a => a.Id.ToString()).ToList(); + var roleIds = currentUser.Roles.Select(a => a.Id.ToString()).ToList(); + + List ids = new List(); + if (!string.IsNullOrEmpty(userId)) + { + ids.Add(userId); + } + + ids.AddRange(postIds); + ids.AddRange(roleIds); + var list = await client.Queryable().Where(t => ids.ToArray().Contains(t.ObjId)).ToListAsync(); + List schemeinfoIds = new List(); + foreach (var item in list) + { + schemeinfoIds.Add(item.SchemeInfoId); + } + + return await client.Queryable() + .LeftJoin((t, s) => t.SchemeId == s.Id) + .Where((t, s) => + t.EnabledMark == 1 && + t.Mark == 1 && + (schemeinfoIds.ToArray().Contains(t.Id) || t.AuthType == 1) && + s.Type == 1).ToListAsync(); + } + + + public async Task GetInfoEntityByCode(string code) + { + return await base.Repository.GetFirstAsync(t => t.Code == code); + } + + + public async Task GetSchemeEntity(string keyValue) + { + return await client.Queryable().FirstAsync(a => a.Id == keyValue); + } + + public async Task> GetAuthList(string schemeInfoId) + { + return await client.Queryable().Where(t => t.SchemeInfoId == schemeInfoId).ToListAsync(); + } + + + /// + /// 获取模板的实体 + /// + /// 主键 + /// + public async Task GetScheme(string keyValue) + { + return await client.Queryable().FirstAsync(a => a.Id == keyValue); + } + + + public async Task> UpdateScheme(string schemeInfoId, string schemeId) + { + WFScheme nWFSchemeEntity = await GetScheme(schemeId); + + var flag = false; + if (nWFSchemeEntity.Type != 1) + { + flag = await base.Repository + .UpdateSetColumnsTrueAsync(a => new WFSchemeInfo() { SchemeId = schemeId, EnabledMark = 0 }, + a => a.Id == schemeInfoId); + } + else + { + flag = await base.Repository + .UpdateSetColumnsTrueAsync(a => new WFSchemeInfo() { SchemeId = schemeId }, + a => a.Id == schemeInfoId); + } + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// + /// + /// 主键吧? + /// + /// + /// + /// + public async Task> SaveEntity(string keyValue, WFSchemeInfo infoEntity, WFScheme schemeEntity, + IEnumerable authList) + { + // 如果存在schemeEntity content 解码 + if (!string.IsNullOrEmpty(schemeEntity.Content)) + { + var code = configuration.GetSection("AppSetting:ASECode").Value; + schemeEntity.Content = + AESHelper.AesDecrypt(schemeEntity.Content, code); //"12345678901234567890123456789012" + } + + if (!string.IsNullOrEmpty(keyValue)) + { + WFScheme oldNWFSchemeEntity = await GetScheme(infoEntity.SchemeId); + if (oldNWFSchemeEntity.Content == schemeEntity.Content && oldNWFSchemeEntity.Type == schemeEntity.Type) + { + schemeEntity = null; + } + } + + using (var uwo = UnitWork.CreateContext()) + { + if (string.IsNullOrEmpty(keyValue)) + { + infoEntity.Id = Guid.NewGuid().ToString(); + infoEntity.EnabledMark = 1; + } + else + { + infoEntity.Id = keyValue; + } + + #region 模板信息 + + if (schemeEntity != null) + { + schemeEntity.SchemeInfoId = infoEntity.Id; + schemeEntity.Id = Guid.NewGuid().ToString(); + schemeEntity.CreateDate = DateTime.Now; + schemeEntity.CreateUserId = _auth.GetUserId(); + schemeEntity.CreateUserName = _auth.GetUserName(); + await uwo.WFScheme.InsertAsync(schemeEntity); + infoEntity.SchemeId = schemeEntity.Id; + } + + #endregion + + #region 模板基础信息 + + if (!string.IsNullOrEmpty(keyValue)) + { + await uwo.WFSchemeInfo.UpdateAsync(infoEntity); + } + else + { + await uwo.WFSchemeInfo.InsertAsync(infoEntity); + } + + #endregion + + #region 流程模板权限信息 + + string schemeInfoId = infoEntity.Id; + await uwo.WFSchemeAuth.DeleteAsync(t => t.SchemeInfoId.Equals(schemeInfoId)); + foreach (var item in authList) + { + item.Id = Guid.NewGuid().ToString(); + item.SchemeInfoId = schemeInfoId; + await uwo.WFSchemeAuth.InsertAsync(item); + } + + #endregion + + var flag = uwo.Commit(); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + } + + /// + /// 更新自定义表单模板状态 + /// + /// 模板信息主键 + /// 状态1启用0禁用 + public async Task> UpdateState(string schemeInfoId, int state) + { + var flag = await base.Repository.UpdateSetColumnsTrueAsync(a => new WFSchemeInfo() { EnabledMark = state }, + a => a.Id == schemeInfoId); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + public async Task> DeleteEntity(string keyValue) + { + using (var uow = base.UnitWork.CreateContext()) + { + await uow.WFSchemeInfo.DeleteAsync(t => t.Id.Equals(keyValue)); + await uow.WFSchemeAuth.DeleteAsync(t => t.SchemeInfoId.Equals(keyValue)); + await uow.WFScheme.DeleteAsync(t => t.SchemeInfoId.Equals(keyValue)); + + var falg = uow.Commit(); + return new Response + { + Result = falg, + Message = (falg == true ? "success" : "error") + }; + } + } + + public WFSchemeInfo SelectBySchemeCode(string schemeCode) + { + return Repository.GetFirst(a => a.Code == schemeCode); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/WFStamp/WFStampApp.cs b/OpenAuth.App/BaseApp/WFStamp/WFStampApp.cs new file mode 100644 index 0000000..f13ef01 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFStamp/WFStampApp.cs @@ -0,0 +1,170 @@ +using Infrastructure; +using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; +using OpenAuth.App.Base; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.App.Response; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenAuth.App.BaseApp.Base; + +namespace OpenAuth.App +{ + public class WFStampApp : SqlSugarBaseApp + { + public WFStampApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) + { + } + + #region 获取数据 + /// + /// 获取签章列表 + /// + /// 用户id + /// + public async Task> GetList(string userId) + { + return await base.Repository.GetListAsync(t => t.UserIds.Contains(userId) && t.EnabledMark == 1); + } + /// + /// 获取管理分页列表 + /// + /// 分页参数 + /// 查询参数 + /// + public async Task>> GetPageList(PageReq pageReq, WFStamp queryParams) + { + RefAsync totalCount = 0; + + var expression = Expressionable.Create() + .AndIF(!string.IsNullOrEmpty(queryParams.StampName), t => t.StampName.Contains(queryParams.StampName)) + .AndIF(queryParams.EnabledMark != null, (t => t.EnabledMark == queryParams.EnabledMark)) + .AndIF(!string.IsNullOrEmpty(queryParams.StampType), t => t.StampType == queryParams.StampType); + + var list = await base.Repository + .GetPageListAsync(expression.ToExpression(), + new PageModel + { + PageIndex = pageReq.page, + PageSize = pageReq.limit, + TotalCount = totalCount + }); + + return new PageInfo> + { + Items = list, + Total = totalCount + }; + } + #endregion + + #region 提交数据 + + /// + /// 保存印章信息(新增/编辑) + /// + /// 主键 + /// 实体 + public async Task> SaveEntity(string keyValue, WFStamp entity) + { + var flag = false; + entity.User = _auth.GetUserId(); + entity.CreateDate = DateTime.Now; + if (string.IsNullOrEmpty(keyValue)) + { + entity.StampId = Guid.NewGuid().ToString(); //产生印章编号 + flag = await base.Repository.InsertAsync(entity); + } + else + { + entity.StampId = keyValue; + flag = await base.Repository.UpdateAsync(entity); + } + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 删除印章信息 + /// + /// 主键 + public async Task> DeleteEntity(string keyVlaue) + { + var flag = await base.Repository.DeleteByIdAsync(keyVlaue);//删除操作 + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + #endregion + + #region 扩展方法 + /// + /// 更新数据状态 + /// + /// 主键 + /// 状态 1启用 0禁用 + public async Task> UpdateState(string keyValue, int state) + { + var flag = await base.Repository + .UpdateSetColumnsTrueAsync( + a => new WFStamp { EnabledMark = state }, + a => a.StampId == keyValue + );//删除操作 + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + public async Task GetEntity(string keyValue) + { + return await base.Repository.GetByIdAsync(keyValue); + } + + /// + /// 密码匹配 + /// + /// 主键 + /// 密码 + /// + public async Task> EqualPassword(string keyValue, string password) + { + var reponse = new Response(); + + WFStamp entity = await GetEntity(keyValue); + if (entity.Password.Equals(password))//加密后进行对比 + { + reponse.Result = true; + reponse.Message = "success"; + } + else + { + reponse.Result = false; + reponse.Message = "error"; + } + return reponse; + } + + /// + /// 签章图片归档并验证密码 + /// + /// 主键 + /// 密码 + /// + public Task ToWfImg(string keyValue, string password) { return null; } + #endregion + } +} diff --git a/OpenAuth.App/BaseApp/WFTask/Request/WFTaskDto.cs b/OpenAuth.App/BaseApp/WFTask/Request/WFTaskDto.cs new file mode 100644 index 0000000..8ab60b5 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFTask/Request/WFTaskDto.cs @@ -0,0 +1,33 @@ +using OpenAuth.Repository.Domain; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Request +{ + public class WFTaskDto + { + /// + /// 当前任务 + /// + public WFTask Task { get; set; } + /// + /// 流程进程 + /// + public WFProcess Process { get; set; } + /// + /// 流程模板信息 + /// + public WFScheme Scheme { get; set; } + /// + /// 审核日志 + /// + public IEnumerable Logs { get; set; } + /// + /// 任务列表 + /// + public IEnumerable Tasks { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFTask/Response/ExtendInfo.cs b/OpenAuth.App/BaseApp/WFTask/Response/ExtendInfo.cs new file mode 100644 index 0000000..2d3a83c --- /dev/null +++ b/OpenAuth.App/BaseApp/WFTask/Response/ExtendInfo.cs @@ -0,0 +1,9 @@ +namespace OpenAuth.App.BaseApp.WFTask.Response; + +public class ExtendInfo +{ + public string Field { get; set; } + public object Value { get; set; } + public string Label { get; set; } + public string FieldName { get; set; } +} \ No newline at end of file diff --git a/OpenAuth.App/BaseApp/WFTask/Response/RetractRes.cs b/OpenAuth.App/BaseApp/WFTask/Response/RetractRes.cs new file mode 100644 index 0000000..f084c20 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFTask/Response/RetractRes.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.BaseApp.WFTask.Response +{ + public class RetractRes + { + public string ProcessId { get; set; } + public DateTime MaxCreatedDate { get; set; } + } +} diff --git a/OpenAuth.App/BaseApp/WFTask/WFTaskApp.cs b/OpenAuth.App/BaseApp/WFTask/WFTaskApp.cs new file mode 100644 index 0000000..1323844 --- /dev/null +++ b/OpenAuth.App/BaseApp/WFTask/WFTaskApp.cs @@ -0,0 +1,935 @@ +using System.Data; +using DocumentFormat.OpenXml.Office2010.Excel; +using Infrastructure; +using Infrastructure.Extensions; +using JetBrains.Annotations; +using Microsoft.Extensions.Configuration; +using Moq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NPOI.SS.Formula.Functions; +using OpenAuth.App.BaseApp.Base; +using OpenAuth.App.BaseApp.WFTask.Response; +using OpenAuth.App.FormScheme; +using OpenAuth.App.FormScheme.Response; +using OpenAuth.App.Interface; +using OpenAuth.App.Request; +using OpenAuth.Repository; +using OpenAuth.Repository.Domain; +using SqlSugar; + +namespace OpenAuth.App.BaseApp.WFTask +{ + public class WFTaskApp : SqlSugarBaseApp + { + ISqlSugarClient client; + private readonly FormSchemeApp _formSchemeApp; + private readonly WFProcessApp _processApp; + private WFSchemeInfoApp _schemeInfoApp; + private readonly IConfiguration _configuration; + + public WFTaskApp(ISugarUnitOfWork unitWork, ISimpleClient repository, + IAuth auth, + FormSchemeApp formSchemeApp, + WFProcessApp processApp, + WFSchemeInfoApp schemeInfoAppApp, + IConfiguration configuration + ) : + base(unitWork, repository, auth) + { + client = base.Repository.AsSugarClient(); + _formSchemeApp = formSchemeApp; + _processApp = processApp; + _schemeInfoApp = schemeInfoAppApp; + _configuration = configuration; + } + + #region 任务 + + /// + /// 获取我的代办任务列表 + /// + /// 分页参数 + /// 查询参数 + /// 是否允许批量审核 + /// + public async Task>> GetMyUncompletedPageList(PageReq pageReq, + WFProcessSearchDto searchParams, string category, bool isBatchAudit = false) + { + RefAsync totalCount = 0; + var userId = _auth.GetUserId(); + + var expression = Expressionable.Create() + //.And(t => t.UserId == userId) + .And(t => t.State == 1) + .And(t => t.Type != 2) + .AndIF(!string.IsNullOrEmpty(searchParams.Keyword), + t => t.ProcessTitle.Contains(searchParams.Keyword) || t.UnitName.Contains(searchParams.Keyword)) + .AndIF(!string.IsNullOrEmpty(searchParams.Code), t => t.ProcessCode == searchParams.Code) + .AndIF(searchParams.StartDate != null && searchParams.EndDate != null, + t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate) + .AndIF(isBatchAudit, t => t.IsBatchAudit == 1); + + var list = await client.Queryable() + .Where(expression.ToExpression()) + .LeftJoin((t, u) => t.Id == u.TaskId && u.UserId == userId) + .Where((t, u) => u.UserId == userId || t.UserId == userId) + .LeftJoin((t, u, p) => t.ProcessId == p.Id) + .LeftJoin((t, u, p, s) => p.SchemeId == s.Id) + .LeftJoin((t, u, p, s, i) => s.SchemeInfoId == i.Id) + .WhereIF(!string.IsNullOrEmpty(category), (t, u, p, s, i) => i.Category == category) + .OrderByDescending((t, u, p, s, i) => t.CreateDate) + .Select((t, u, p, s, i) => new Repository.Domain.WFTask() + { + Id = t.Id.SelectAll(), + SchemeContent = s.Content, + InstanceInfo = p.InstanceInfo + }) + .ToPageListAsync(pageReq.page, pageReq.limit, totalCount); + // 遍历补充信息 + foreach (var wfTask in list) + { + // 获取表单数据 + var unitId = wfTask.UnitId; // 当前节点id + //var process = await _processApp.GetEntity(wfTask.ProcessId); + //var scheme = await _schemeInfoApp.GetSchemeEntity(process.SchemeId); + //var content = (JObject)JsonConvert.DeserializeObject(scheme.Content); + var content = (JObject)JsonConvert.DeserializeObject(wfTask.SchemeContent); + + var wfData = (JArray)content["wfData"]; + // + var instanceInfo = wfTask.InstanceInfo; + var processId = instanceInfo.pkeyValue; + var pkey = instanceInfo.pkey; + foreach (var jToken in wfData) + { + var id = jToken["id"]?.ToString(); + if (id != null && id.Equals(unitId)) + { + var first = jToken; + // fromVersion 为 schemeId + var formVersion = first["formVerison"]?.ToString(); + if (!string.IsNullOrEmpty(formVersion)) + { + var authFields = (JArray)jToken["authFields"]; + var showFields = new Dictionary(); + foreach (var authField in authFields) + { + var label = authField["label"].ToString(); + var field = authField["field"].ToString(); + var fieldName = authField["fieldName"]?.ToString(); + if (authField["upShow"].ToBool().Equals(true)) + { + showFields.Add(field, + new ExtendInfo() { Field = field, Label = label, FieldName = fieldName }); + } + } + + var sql = "select "; + var selectFields = ""; + foreach (var showField in showFields) + { + selectFields += $"\"{showField.Value.FieldName}\"" + " as " + showField.Value.Field + + ","; + } + + selectFields = selectFields.TrimEnd(','); + + var formScheme = await _formSchemeApp.GetScheme(formVersion); + FormSchemeNewModel formSchemeModel = formScheme.Scheme.ToObject(); + FormDbTableInfo mainTable = formSchemeModel.Db.Find(t => t.Type == "main"); + sql += selectFields + $" FROM \"{mainTable.Name}\" t where \"{pkey}\" = @Id"; + + var dataList = await client.Ado.GetDataTableAsync(sql, new { Id = processId }); + + // 实现一个新的查询方法 + // var dataList = await _formSchemeApp.GetFormDataNew(formVersion, "Id", processId); + // var data = dataList.FirstOrDefault().Value; + // 实际只有一行数据 + foreach (DataRow dataRow in dataList.Rows) + { + foreach (var showField in showFields) + { + var field = showField.Key; + var value = dataRow[field]; + showField.Value.Value = value; + } + } + + wfTask.ExtendInfo = showFields.Values; + } + } + } + + wfTask.SchemeContent = null; + wfTask.InstanceInfo = null; + } + + return new PageInfo> + { + Items = list, + Total = totalCount + }; + } + + + /// + /// 获取我的已办任务列表 + /// + /// 分页参数 + /// 查询参数 + /// + public async Task>> GetMyCompletedPageList(PageReq pageReq, + WFProcessSearchDto searchParams, string category) + { + RefAsync totalCount = 0; + var userId = _auth.GetUserId(); + + var queryable = client.Queryable() + .LeftJoin((t, t1) => t.Id == t1.TaskId) + .LeftJoin((t, t1, t2) => t.ProcessId == t2.Id) + .LeftJoin((t, t1, t2, t3) => t2.SchemeId == t3.Id) + .LeftJoin((t, t1, t2, t3, t4) => t3.SchemeInfoId == t4.Id); + var exp = Expressionable.Create() + .And((t, t1) => t1.IsLast == 1) + .And((t, t1) => t.State == 3 || t.State == 5) + .And((t, t1) => t.Type == 1 || t.Type == 3 || t.Type == 5 || t.Type == 6||t.Type==7) + .And((t, t1) => t.UserId == userId || t1.UserId == userId) + .AndIF(!string.IsNullOrEmpty(searchParams.Keyword), + (t, t1) => t.ProcessTitle.Contains(searchParams.Keyword) || + t.UnitName.Contains(searchParams.Keyword)) + .AndIF(!string.IsNullOrEmpty(searchParams.Code), (t, t1) => t.ProcessCode == searchParams.Code) + .AndIF(searchParams.StartDate != null && searchParams.EndDate != null, + (t, t1) => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate) + .ToExpression(); + var list = await queryable.Where(exp) + .WhereIF(!string.IsNullOrEmpty(category), (t, t1, t2, t3, t4) => t4.Category == category).Select( + (t, t1, t2, t3, t4) => new Repository.Domain.WFTask() + { + Id = t.Id, + Type = t.Type, + ProcessTitle = t.ProcessTitle, + ProcessCode = t.ProcessCode, + ProcessId = t.ProcessId, + ChildProcessId = t.ChildProcessId, + ProcessUserId = t.ProcessUserId, + ProcessUserName = t.ProcessUserName, + Token = t.Token, + UnitId = t.UnitId, + UnitName = t.UnitName, + PrevUnitId = t.PrevUnitId, + PrevUnitName = t.PrevUnitName, + PrevToken = t.PrevToken, + UserId = t.UserId, + UserName = t.UserName, + UserDepartmentId = t.UserDepartmentId, + UserCompanyId = t.UserCompanyId, + State = t.State, + IsAgree = t.IsAgree, + IsLast = t.IsLast, + Sort = t.Sort, + TimeoutAction = t.TimeoutAction, + TimeoutNotice = t.TimeoutNotice, + TimeoutInterval = t.TimeoutInterval, + TimeoutStrategy = t.TimeoutStrategy, + CreateUserId = t.CreateUserId, + CreateUserName = t.CreateUserName, + IsUrge = t.IsUrge, + UrgeTime = t.UrgeTime, + FirstId = t.FirstId, + IsBatchAudit = t.IsBatchAudit, + IsReject = t.IsReject, + PrevTaskId = t.PrevTaskId, + UpdateTaskId = t.UpdateTaskId, + + IsCancel = t1.IsCancel, + CreateDate = t1.CreateDate, + OperationName = t1.OperationName, + MakeUserId = t1.UserId, + + IsFinished = t2.IsFinished + }).ToPageListAsync(pageReq.page, pageReq.limit, totalCount); + + return new PageInfo> + { + Items = list, + Total = totalCount + }; + } + + + /// + /// 获取可撤回的任务 + /// + /// 分页参数 + /// 查询参数 + /// + public PageInfo> GetRetractPageList(PageReq pageReq, + WFProcessSearchDto searchParams, string category) + { + int totalCount = 0; + var userId = _auth.GetUserId(); + + var query = client.Queryable() + .Where(t => t.IsLast == 1) + .Where(t => t.State == 3 || t.State == 5) + .Where(t => t.Type == 1 || t.Type == 3 || t.Type == 5 || t.Type == 6 || t.Type == 7) + .Where(t => t.CreateDate != null) + .WhereIF(!string.IsNullOrEmpty(searchParams.Keyword), t => t.ProcessTitle.Contains(searchParams.Keyword) || t.UnitName.Contains(searchParams.Keyword)) + .WhereIF(!string.IsNullOrEmpty(searchParams.Code), t => t.ProcessCode == searchParams.Code) + .WhereIF(searchParams.StartDate != null && searchParams.EndDate != null, t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate) + .Select(t => new + { + index2 = SqlFunc.RowNumber($"{t.CreateDate} desc ", t.ProcessId), + ProcessTitle = t.ProcessTitle, + UnitId = t.UnitId, + Id = t.Id, + ProcessId = t.ProcessId, + UnitName = t.UnitName, + UserId = t.UserId, + UserName = t.UserName, + State = t.State, + CreateDate = t.CreateDate, + Type = t.Type, + ProcessCode = t.ProcessCode + }) + .MergeTable() + .Where(it => it.index2 == 1) + .Where(r => r.UserId == userId) + .OrderByDescending(r => r.CreateDate) + .Select(r => new + { + r.Id, + r.ProcessTitle, + r.ProcessId, + r.UnitId, + r.UnitName, + r.UserId, + r.UserName, + r.State, + r.CreateDate, + r.Type, + r.ProcessCode, + }); + var result = query.ToPageList(pageReq.page, pageReq.limit); + totalCount = query.Count(); + + return new PageInfo> + { + Items = result, + Total = totalCount + }; + } + + /// + /// 获取我的传阅任务列表 + /// + /// 分页参数 + /// 查询参数 + /// + public async Task>> GetMyReadPageList(PageReq pageReq, + WFProcessSearchDto searchParams, + string category) + { + RefAsync totalCount = 0; + var userId = _auth.GetUserId(); + + var expression = Expressionable.Create() + .And(t => t.UserId == userId) + .And(t => t.Type == 2) + .AndIF(!string.IsNullOrEmpty(searchParams.Keyword), + t => t.ProcessTitle.Contains(searchParams.Keyword) || t.UnitName.Contains(searchParams.Keyword)) + .AndIF(!string.IsNullOrEmpty(searchParams.Code), t => t.ProcessCode == searchParams.Code) + .AndIF(searchParams.StartDate != null && searchParams.EndDate != null, + t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate); + + + var list = await client.Queryable() + .Where(expression.ToExpression()) + .LeftJoin((t, p) => t.ProcessId == p.Id) + .LeftJoin((t, p, s) => p.SchemeId == s.Id) + .LeftJoin((t, p, s, i) => s.SchemeInfoId == i.Id) + .WhereIF(!string.IsNullOrEmpty(category), (t, p, s, i) => i.Category == category) + .OrderByDescending((t, p, s, i) => t.CreateDate) + .ToPageListAsync(pageReq.page, pageReq.limit, totalCount); + + return new PageInfo> + { + Items = list, + Total = totalCount + }; + } + + /// + /// 获取我的委托任务列表 + /// + /// 分页参数 + /// 查询参数 + /// + public async Task>> GetMyDelegatePageList(PageReq pageReq, + WFProcessSearchDto searchParams, string category) + { + RefAsync totalCount = 0; + + var pageInfo = new PageInfo>(); + + string userId = _auth.GetUserId(); + DateTime datetime = DateTime.Now; + + var expression = Expressionable.Create(); + var delegateList = await client.Queryable() + .Where(t => t.ToUserId == userId && t.BeginDate >= datetime && t.EndDate <= datetime && t.Type == 0) + .ToListAsync(); + + if (delegateList.Count == 0) + { + pageInfo.Total = 0; + return pageInfo; + } + + + foreach (var item in delegateList) + { + var relationList = await client.Queryable() + .Where(a => a.DelegateRuleId == item.Id).ToListAsync(); + string relation = ""; + foreach (var relationItem in relationList) + { + relation += $"'{relationItem.SchemeInfoId}'"; + } + + expression = expression.Or(t => + t.UserId == item.CreateUserId && relation.Contains("'" + t.ProcessCode + "'")); + } + + var exp = Expressionable.Create() + .And(t => t.UserId != userId) + .And(t => t.State == 1) + .And(t => t.Type != 2) + .AndIF(!string.IsNullOrEmpty(searchParams.Keyword), + t => t.ProcessTitle.Contains(searchParams.Keyword) || t.UnitName.Contains(searchParams.Keyword)) + .AndIF(!string.IsNullOrEmpty(searchParams.Code), t => t.ProcessCode == searchParams.Code) + .AndIF(searchParams.StartDate != null && searchParams.EndDate != null, + t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate); + + exp = exp.And(expression.ToExpression()); + + var list = await client.Queryable() + .Where(expression.ToExpression()) + .LeftJoin((t, p) => t.ProcessId == p.Id) + .LeftJoin((t, p, s) => p.SchemeId == s.Id) + .LeftJoin((t, p, s, i) => s.SchemeInfoId == i.Id) + .WhereIF(!string.IsNullOrEmpty(category), (t, p, s, i) => i.Category == category) + .OrderByDescending((t, p, s, i) => t.CreateDate) + .ToPageListAsync(pageReq.page, pageReq.limit, totalCount); + + return new PageInfo> + { + Items = list, + Total = totalCount + }; + } + + + /// + /// 获取流程任务实体 + /// + /// 密钥 + /// 用户id + /// + public async Task GetEntityByToken(string token, string userId) + { + return await base.Repository.GetFirstAsync(t => t.Token == token && t.UserId == userId && t.State == 1); + } + + /// + /// 获取流程任务实体 + /// + /// 主键 + /// + public Repository.Domain.WFTask GetEntity(string keyValue) + { + return base.Repository.GetFirst(a => a.Id == keyValue); + } + + /// + /// 获取任务关联的用户 + /// + /// 主键 + /// + public List GetUsers(string keyValue) + { + List users = new List(); + var us = client.Queryable().Where(r => r.TaskId == keyValue).ToList(); + if (us.Count > 0) + { + users = us.Select(r => r.UserId).ToList(); + } + + return users; + } + + /// + /// 获取任务列表 + /// + /// 流程实例主键 + /// 任务类型 + /// 上一个任务Id值 + /// + public async Task> GetList(string processId, int type, string prevTaskId) + { + return await base.Repository.GetListAsync(t => + t.ProcessId == processId && t.Type == type && t.PrevTaskId == prevTaskId); + } + + /// + /// 获取任务列表 + /// + /// 流程实例主键 + /// 上一个任务token值 + /// + public async Task> GetList(string processId, string prevToken) + { + return await base.Repository.GetListAsync(t => t.ProcessId == processId && t.PrevToken == prevToken); + } + + /// + /// 获取未完成的任务 + /// + /// 流程进程主键 + /// + public async Task> GetUnFinishTaskList(string processId) + { + return await base.Repository.GetListAsync(t => + t.ProcessId == processId && t.State == 1 && (t.Type == 1 || t.Type == 2 || t.Type == 3 || t.Type == 4 || + t.Type == 5 || t.Type == 6||t.Type==7)); + } + + /// + /// 获取等待任务列表(用于网关判断是否所有支路都执行完毕) + /// + /// 流程实例Id + /// 流程单元节点Id + /// + public async Task> GetAwaitTaskList(string processId, string unitId) + { + return await base.Repository.GetListAsync(t => + t.ProcessId == processId && t.UnitId == unitId && t.Type == 21 && t.State == 1); + } + + /// + /// 获取最近的任务 + /// + /// 流程实例Id + /// 流程单元节点Id + /// + public async Task> GetLastTaskList(string processId, string unitId) + { + return await client.Queryable() + .Where(t => t.ProcessId == processId && t.UnitId == unitId && t.IsLast == 1 && + (t.Type == 1 || t.Type == 3 || t.Type == 4 || t.Type == 5||t.Type==7)) + .OrderBy(t => t.Sort) + .ToListAsync(); + } + + /// + /// 获取最近的不是驳回产生的任务 + /// + /// 流程实例Id + /// 流程单元节点Id + /// + public Task GetLastNotRejectTask(string processId, string unitId) + { + return null; + } + + /// + /// 获取最近的完成任务 + /// + /// 流程实例Id + /// 流程单元节点Id + /// + public async Task> GetLastFinishTaskList(string processId, string unitId) + { + return await base.Repository.GetListAsync(t => + t.ProcessId == processId && t.UnitId == unitId && (t.Type == 1||t.Type==7) && t.IsLast == 1 && t.State == 3); + } + + /// + /// 获取完成任务 + /// + /// 流程实例Id + /// + public async Task> GetFinishTaskList(string processId, List ids) + { + return await base.Repository.GetListAsync(t => t.ProcessId == processId && !ids.Contains(t.Id)); + } + + /// + /// 获取节点任务的最大人数 + /// + /// 流程实例Id + /// 流程单元节点Id + /// + public Task GetTaskUserMaxNum(string processId, string unitId) + { + return null; + } + + /// + /// 保存任务 + /// + /// 任务日志 + public async Task> Add(Repository.Domain.WFTask wfTaskEntity) + { + wfTaskEntity.CreateDate = DateTime.Now; + wfTaskEntity.CreateUserId = _auth.GetUserId(); + wfTaskEntity.CreateUserName = _auth.GetUserName(); + wfTaskEntity.Id = Guid.NewGuid().ToString(); + wfTaskEntity.IsLast = 1; + + var flag = await base.Repository.InsertAsync(wfTaskEntity); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 更新任务状态 + /// + /// + /// + /// + public async Task> Update(string processId, string unitId) + { + var flag = await base.Repository.UpdateSetColumnsTrueAsync(a => new Repository.Domain.WFTask { IsLast = 0 }, + a => a.ProcessId == processId && a.UnitId == unitId); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 更新任务 + /// + /// 任务日志 + public Response Update(Repository.Domain.WFTask wfTaskEntity) + { + var flag = base.Repository.Update(wfTaskEntity); + + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 关闭任务 + /// + /// 流程主键 + /// 任务令牌 + /// 任务id(除去该任务不关闭) + /// + public async Task> CloseTask(string processId, string token, string taskId = "") + { + var expression = Expressionable.Create() + .And(t => t.ProcessId == processId && t.Token == token) + .AndIF(!string.IsNullOrEmpty(taskId), t => t.Id != taskId).ToExpression(); + + var flag = await base.Repository.UpdateSetColumnsTrueAsync(t => new Repository.Domain.WFTask { State = 4 }, + expression); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 关闭任务 + /// + /// 流程进程 + /// 单元节点id + /// 任务类型 + /// 任务id + /// + public async Task> CloseTask(string processId, string unitId, int type, string taskId) + { + var flag = await base.Repository.UpdateSetColumnsTrueAsync( + t => new Repository.Domain.WFTask { State = 4, UpdateTaskId = taskId }, + t => t.ProcessId == processId && t.UnitId == unitId && t.Type == type); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 打开任务 + /// + /// 流程进程 + /// 单元节点id + /// 任务类型 + /// 任务id + /// + public async Task> OpenTask(string processId, string unitId, int type, string taskId) + { + var flag = await base.Repository.UpdateSetColumnsTrueAsync( + t => new Repository.Domain.WFTask { State = 1, UpdateTaskId = taskId }, + t => t.ProcessId == processId && t.UnitId == unitId && t.Type == type); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 删除任务 + /// + /// 流程进程 + /// + public async Task> Delete(string processId) + { + var flag = await base.Repository.DeleteAsync(t => t.ProcessId == processId); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 删除任务 + /// + /// 流程进程 + /// 来源任务ID + /// + public async Task> Delete(string processId, string prevTaskId) + { + var flag = await base.Repository.DeleteAsync(t => t.ProcessId == processId && t.PrevTaskId == prevTaskId); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 删除任务 + /// + /// 任务主键 + /// + public async Task> DeleteByFirstId(string id) + { + var flag = await base.Repository.DeleteAsync(t => t.FirstId == id); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + /// + /// 作废任务 + /// + /// 流程进程 + /// + public async Task> VirtualDelete(string processId) + { + var flag = await base.Repository.UpdateSetColumnsTrueAsync(t => new Repository.Domain.WFTask { State = 7 }, + t => t.ProcessId == processId && t.State == 1); + return new Response + { + Result = flag, + Message = flag == true ? "success" : "error" + }; + } + + #endregion + + #region 日志 + + /// + /// 获取流程进程的任务处理日志 + /// + /// 流程进程主键 + /// + public async Task> GetLogList(string processId) + { + return await client.Queryable().Where(a => a.ProcessId == processId).OrderBy(r => r.CreateDate) + .ToListAsync(); + } + + /// + /// 获取任务日志列表 + /// + /// 流程实例Id + /// 流程单元节点Id + /// + public async Task> GetLogList(string processId, string unitId) + { + return await client.Queryable().Where(a => a.ProcessId == processId && a.UnitId == unitId) + .OrderByDescending(t => t.CreateDate).ToListAsync(); + } + + /// + /// 获取任务日志列表 + /// + /// 任务Id + /// + public async Task GetLogEntity(string taskId) + { + return await client.Queryable().Where(t => t.TaskId == taskId).FirstAsync(); + } + + /// + /// 更新任务日志状态为不是最近处理的 + /// + /// + /// + /// + public async Task> UpdateLog(string processId, string unitId) + { + var userId = _auth.GetUserId(); + var count = await client.Updateable() + .SetColumns(a => new WFTaskLog() { IsLast = 0 }) + .Where(a => a.ProcessId == processId && a.UnitId == unitId && a.IsLast == 1 && a.UserId == userId) + .ExecuteCommandAsync(); + return new Response + { + Result = count > 0, + Message = count > 0 ? "success" : "error" + }; + } + + + /// + /// 关闭任务日志撤销 + /// + /// 流程主键 + /// 任务主键 + /// + public async Task> CloseTaskLogCancel(string processId, string taskId) + { + var count = await client.Updateable() + .SetColumns(a => new WFTaskLog() { IsCancel = 0 }) + .Where(a => a.ProcessId == processId && a.TaskId == taskId) + .ExecuteCommandAsync(); + return new Response + { + Result = count > 0, + Message = count > 0 ? "success" : "error" + }; + } + + /// + /// 关闭任务日志撤销 + /// + /// 流程任务Id + /// + public async Task> CloseTaskLogCancel(string taskId) + { + var count = await client.Updateable() + .SetColumns(a => new WFTaskLog() { IsCancel = 0 }) + .Where(a => a.TaskId == taskId) + .ExecuteCommandAsync(); + return new Response + { + Result = count > 0, + Message = count > 0 ? "success" : "error" + }; + } + + + /// + /// 保存任务日志 + /// + /// 任务日志 + public async Task> AddLog(WFTaskLog wfTaskLogEntity) + { + wfTaskLogEntity.CreateDate = DateTime.Now; + wfTaskLogEntity.UserId = _auth.GetUserId(); + wfTaskLogEntity.UserName = _auth.GetUserNickName(); + wfTaskLogEntity.Id = Guid.NewGuid().ToString(); + var count = await client.Insertable(wfTaskLogEntity).ExecuteCommandAsync(); + return new Response + { + Result = count > 0, + Message = count > 0 ? "success" : "error" + }; + } + + /// + /// 删除任务日志 + /// + /// 流程进程 + /// + public async Task> DeleteLog(string processId) + { + var count = await client.Deleteable() + .Where(a => a.ProcessId == processId) + .ExecuteCommandAsync(); + return new Response + { + Result = count > 0, + Message = count > 0 ? "success" : "error" + }; + } + + /// + /// 删除任务日志 + /// + /// 流程进程 + /// 来源任务密钥 + /// + public async Task> DeleteLog(string processId, string taskId) + { + var count = await client.Deleteable() + .Where(a => a.ProcessId == processId && a.TaskId == taskId && a.IsLast == 1) + .ExecuteCommandAsync(); + return new Response + { + Result = count > 0, + Message = count > 0 ? "success" : "error" + }; + } + + /// + /// 删除任务日志 + /// + /// 任务主键 + /// + public async Task> DeleteLogByTaskId(string taskId) + { + var count = await client.Deleteable() + .Where(a => a.TaskId == taskId) + .ExecuteCommandAsync(); + return new Response + { + Result = count > 0, + Message = count > 0 ? "success" : "error" + }; + } + + #endregion + + + public Repository.Domain.WFTask GetNodeByProcessId(string id) + { + return Repository.GetFirst(a => a.ProcessId == id); + } + + public void OriginalAdd(Repository.Domain.WFTask node) + { + Repository.AsInsertable(node).IgnoreColumnsNull().ExecuteCommand(); + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/Common/CommonData.cs b/OpenAuth.App/Common/CommonData.cs new file mode 100644 index 0000000..970116b --- /dev/null +++ b/OpenAuth.App/Common/CommonData.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenAuth.App.Common +{ + public class CommonData + { + /// + /// 执行cmd命令 + /// + /// + /// + public static void ExeCmdProcess(string strDir, string _path) + { + Process p = new Process(); + p.StartInfo.FileName = "cmd.exe "; + p.StartInfo.UseShellExecute = false; + p.StartInfo.RedirectStandardInput = true; + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.RedirectStandardError = true; + p.StartInfo.CreateNoWindow = false; + + //指定执行程序的目录 + p.StartInfo.WorkingDirectory = _path; + //开始执行 + p.Start(); + //Console.WriteLine("command:" + strInput); + p.StandardInput.WriteLine(strDir.ToString() + "&exit"); + + //执行结果返回 + string output = p.StandardOutput.ReadToEnd(); + + //等待执行完成 + p.WaitForExit(); + + //关闭程序 + p.Close(); + } + + } +} diff --git a/OpenAuth.App/Const/TubanZhuanTi.cs b/OpenAuth.App/Const/TubanZhuanTi.cs new file mode 100644 index 0000000..fb3114a --- /dev/null +++ b/OpenAuth.App/Const/TubanZhuanTi.cs @@ -0,0 +1,15 @@ +namespace OpenAuth.App.Common +{ + public struct TubanZhuanTi { + + public const string weifayongdi = "Subject_WFYD"; + public const string feifacaikuang = "Subject_FFCK"; + public const string zhongdianwenti1 = "Subject_ZDWT1"; + public const string zhongdianwenti2 = "Subject_ZDWT2"; + public const string gdflh = "Subject_GDFLH"; + public const string wfydwp = "Subject_WPWF"; + public const string xcsj = "Subject_XCSJ"; + public const string sthx = "Subject_STHX"; + public const string stxf = "Subject_STXF"; + } +} diff --git a/OpenAuth.App/DbExtension.cs b/OpenAuth.App/DbExtension.cs new file mode 100644 index 0000000..d425ea5 --- /dev/null +++ b/OpenAuth.App/DbExtension.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Linq; +using System.Text; +using Infrastructure; +using SqlSugar; + +namespace OpenAuth.App +{ + public class DbExtension + { + private ISqlSugarClient _context; + + public DbExtension(ISqlSugarClient context) + { + _context = context; + } + + /// + /// 获取数据库一个表的所有属性值及属性描述 + /// + /// 模块名称/表名 + /// + public List GetProperties(Type type) + { + var result = new List(); + + var entity = _context.EntityMaintenance.GetEntityInfo(type); + + foreach (var column in entity.Columns) + { + object[] objs = column.PropertyInfo.GetCustomAttributes(typeof(DescriptionAttribute), true); + var description = objs.Length > 0 ? ((DescriptionAttribute)objs[0]).Description : column.ColumnDescription; + if (string.IsNullOrEmpty(description)) description = column.DbColumnName; + + object[] browsableObjs = column.PropertyInfo.GetCustomAttributes(typeof(BrowsableAttribute), true); + bool browsable = browsableObjs == null || browsableObjs.Length == 0 || + ((BrowsableAttribute)browsableObjs[0]).Browsable; + + result.Add(new KeyDescription + { + Key = column.DbColumnName, + Description = description, + Browsable = browsable, + Type = column.PropertyInfo.PropertyType.Name + }); + } + return result; + } + } +} \ No newline at end of file diff --git a/OpenAuth.App/OpenAuth.App.csproj b/OpenAuth.App/OpenAuth.App.csproj new file mode 100644 index 0000000..5a2ff4b --- /dev/null +++ b/OpenAuth.App/OpenAuth.App.csproj @@ -0,0 +1,54 @@ + + + + net6.0 + enable + + + + bin\Debug\net5.0\OpenAuth.App.xml + 1701;1702;1591;1573;1572;1570 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenAuth.Identity/Config.cs b/OpenAuth.Identity/Config.cs new file mode 100644 index 0000000..1429d1e --- /dev/null +++ b/OpenAuth.Identity/Config.cs @@ -0,0 +1,69 @@ +using System.Collections.Generic; +using System.Security.Claims; +using IdentityModel; +using IdentityServer4; +using IdentityServer4.Models; + +namespace OpenAuth.IdentityServer +{ + public static class Config + { + #region scopes + public static IEnumerable ApiScopes => new List + { + new ApiScope("api1", "My API") + }; + #endregion + + #region clients + /// + /// 客户端信息 + /// + /// + public static IEnumerable GetClients() + { + return new[] + { + new Client + { + ClientId = "weigh", + AllowedGrantTypes = GrantTypes.ClientCredentials, + ClientSecrets = + { + new Secret("jibeikuangchang".Sha256()) + }, + AllowedScopes = { "api1" } + } + }; + } + #endregion + + #region Resources + public static IEnumerable GetIdentityResources() + { + return new IdentityResource[] + { + new IdentityResources.OpenId(), + new IdentityResources.Profile(), + }; + } + #endregion + + #region Api + /// + /// API信息 + /// + /// + public static IEnumerable GetApis() + { + return new[] + { + new ApiResource("openauthapi", "OpenAuth.WebApi") + { + UserClaims = { ClaimTypes.Name, JwtClaimTypes.Name } + } + }; + } + #endregion + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/CustomProfileService.cs b/OpenAuth.Identity/CustomProfileService.cs new file mode 100644 index 0000000..1edd218 --- /dev/null +++ b/OpenAuth.Identity/CustomProfileService.cs @@ -0,0 +1,101 @@ +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using IdentityModel; +using IdentityServer4.Extensions; +using IdentityServer4.Models; +using IdentityServer4.Services; +using IdentityServer4.Test; +using Infrastructure; +using Microsoft.Extensions.Logging; +using OpenAuth.App; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.IdentityServer +{ + public class CustomProfileService : IProfileService + { + /// + /// The logger + /// + protected readonly ILogger Logger; + + protected UserManagerApp UserManager; + + /// + /// Initializes a new instance of the class. + /// + /// The users. + /// The logger. + public CustomProfileService(ILogger logger, UserManagerApp userManager) + { + Logger = logger; + UserManager = userManager; + } + + /// + /// 只要有关用户的身份信息单元被请求(例如在令牌创建期间或通过用户信息终点),就会调用此方法 + /// + /// The context. + /// + public virtual Task GetProfileDataAsync(ProfileDataRequestContext context) + { + context.LogProfileRequest(Logger); + + //判断是否有请求Claim信息 + if (context.RequestedClaimTypes.Any()) + { + var user = GetUserById(long.Parse(context.Subject.GetSubjectId())); + if (user != null) + { + //调用此方法以后内部会进行过滤,只将用户请求的Claim加入到 context.IssuedClaims 集合中 这样我们的请求方便能正常获取到所需Claim + var claims = new[] + { + new Claim(ClaimTypes.Name, user.Account), //请求用户的账号,这个可以保证User.Identity.Name有值 + new Claim(JwtClaimTypes.Name, user.Name), //请求用户的姓名 + }; + //返回apiresource中定义的claims + context.AddRequestedClaims(claims); + } + } + + context.LogIssuedClaims(Logger); + + return Task.CompletedTask; + } + + /// + /// 验证用户是否有效 例如:token创建或者验证 + /// + /// The context. + /// + public virtual Task IsActiveAsync(IsActiveContext context) + { + Logger.LogDebug("IsActive called from: {caller}", context.Caller); + + var user = GetUserById(long.Parse(context.Subject.GetSubjectId())); + context.IsActive = user?.Status == 0; + return Task.CompletedTask; + } + + private SysUser GetUserById(long id) + { + SysUser user; + if (id == -1) + { + user = new SysUser + { + Account = Define.SYSTEM_USERNAME, + Id = -1, + Name = Define.SYSTEM_USERNAME + }; + } + else + { + user = UserManager.Get(id); + } + + return user; + } + } +} diff --git a/OpenAuth.Identity/OpenAuth.IdentityServer.csproj b/OpenAuth.Identity/OpenAuth.IdentityServer.csproj new file mode 100644 index 0000000..4736818 --- /dev/null +++ b/OpenAuth.Identity/OpenAuth.IdentityServer.csproj @@ -0,0 +1,34 @@ + + + + net6.0 + enable + + + + 1701;1702;1591;1573;1572;1570 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenAuth.Identity/Program.cs b/OpenAuth.Identity/Program.cs new file mode 100644 index 0000000..c00d185 --- /dev/null +++ b/OpenAuth.Identity/Program.cs @@ -0,0 +1,43 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System; +using Autofac.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; +using Serilog; +using Serilog.Events; +using Serilog.Sinks.SystemConsole.Themes; + +namespace OpenAuth.IdentityServer +{ + public class Program + { + public static void Main(string[] args) + { + Console.Title = "IdentityServer4"; + + CreateWebHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateWebHostBuilder(string[] args) + { + return Host.CreateDefaultBuilder(args) + .UseServiceProviderFactory(new AutofacServiceProviderFactory()) //将默认ServiceProviderFactory指定为AutofacServiceProviderFactory + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseUrls("http://*:12796").UseStartup(); + }).UseSerilog((context, configuration) => + { + configuration + .MinimumLevel.Debug() + .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .MinimumLevel.Override("System", LogEventLevel.Warning) + .MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information) + .Enrich.FromLogContext() + .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate); + }); + } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Properties/launchSettings.json b/OpenAuth.Identity/Properties/launchSettings.json new file mode 100644 index 0000000..699c7ca --- /dev/null +++ b/OpenAuth.Identity/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "IdentityServer": { + "commandName": "Project", + "launchBrowser": false, + "launchUrl": ".well-known/openid-configuration", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:12796" + } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Account/AccountController.cs b/OpenAuth.Identity/Quickstart/Account/AccountController.cs new file mode 100644 index 0000000..fd21fa2 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/AccountController.cs @@ -0,0 +1,384 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System; +using System.Linq; +using System.Threading.Tasks; +using IdentityModel; +using IdentityServer4.Events; +using IdentityServer4.Extensions; +using IdentityServer4.Models; +using IdentityServer4.Services; +using IdentityServer4.Stores; +using Infrastructure; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using OpenAuth.App; +using OpenAuth.Repository.Domain; + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + /// + /// This sample controller implements a typical login/logout/provision workflow for local and external accounts. + /// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production! + /// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval + /// + [SecurityHeaders] + [AllowAnonymous] + public class AccountController : Controller + { + private readonly UserManagerApp _userManager; + private readonly IIdentityServerInteractionService _interaction; + private readonly IClientStore _clientStore; + private readonly IAuthenticationSchemeProvider _schemeProvider; + private readonly IEventService _events; + + public AccountController( + IIdentityServerInteractionService interaction, + IClientStore clientStore, + IAuthenticationSchemeProvider schemeProvider, + IEventService events, UserManagerApp userManager) + { + + _interaction = interaction; + _clientStore = clientStore; + _schemeProvider = schemeProvider; + _events = events; + _userManager = userManager; + } + + /// + /// Entry point into the login workflow + /// + [HttpGet] + public async Task Login(string returnUrl) + { + // build a model so we know what to show on the login page + var vm = await BuildLoginViewModelAsync(returnUrl); + + if (vm.IsExternalLoginOnly) + { + // we only have one option for logging in and it's an external provider + return RedirectToAction("Challenge", "External", new { provider = vm.ExternalLoginScheme, returnUrl }); + } + + return View(vm); + } + + /// + /// Handle postback from username/password login + /// + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Login(LoginInputModel model, string button) + { + // check if we are in the context of an authorization request + var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); + + // the user clicked the "cancel" button + if (button != "login") + { + if (context != null) + { + // if the user cancels, send a result back into IdentityServer as if they + // denied the consent (even if this client does not require consent). + // this will send back an access denied OIDC error response to the client. + await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); + + // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null + if (await _clientStore.IsPkceClientAsync(context.ClientId)) + { + // if the client is PKCE then we assume it's native, so this change in how to + // return the response is for better UX for the end user. + return View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl }); + } + + return Redirect(model.ReturnUrl); + } + else + { + // since we don't have a valid context, then we just go back to the home page + return Redirect("~/"); + } + } + + if (ModelState.IsValid) + { + SysUser user; + if (model.Username == Define.SYSTEM_USERNAME && model.Password == Define.SYSTEM_USERPWD) + { + user = new SysUser + { + Account = Define.SYSTEM_USERNAME, + Password = Define.SYSTEM_USERPWD, + Id = Define.SYSTEM_USERNAME + }; + } + else + { + user = _userManager.GetByAccount(model.Username); + } + + if (user != null &&(user.Password ==model.Password)) + { + if (user.Status != 0) //判断用户状态 + { + await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid user status")); + ModelState.AddModelError(string.Empty, "user.status must be 0"); + var err = await BuildLoginViewModelAsync(model); + return View(err); + } + + await _events.RaiseAsync(new UserLoginSuccessEvent(user.Account, user.Id, user.Account)); + + // only set explicit expiration here if user chooses "remember me". + // otherwise we rely upon expiration configured in cookie middleware. + AuthenticationProperties props = null; + if (AccountOptions.AllowRememberLogin && model.RememberLogin) + { + props = new AuthenticationProperties + { + IsPersistent = true, + ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) + }; + }; + + // issue authentication cookie with subject ID and username + await HttpContext.SignInAsync(user.Id, user.Account, props); + + if (context != null) + { + if (await _clientStore.IsPkceClientAsync(context.ClientId)) + { + // if the client is PKCE then we assume it's native, so this change in how to + // return the response is for better UX for the end user. + return View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl }); + } + + // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null + return Redirect(model.ReturnUrl); + } + + // request for a local page + if (Url.IsLocalUrl(model.ReturnUrl)) + { + return Redirect(model.ReturnUrl); + } + else if (string.IsNullOrEmpty(model.ReturnUrl)) + { + return Redirect("~/"); + } + else + { + // user might have clicked on a malicious link - should be logged + throw new Exception("invalid return URL"); + } + } + + await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials", clientId:context?.ClientId)); + ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage); + } + + // something went wrong, show form with error + var vm = await BuildLoginViewModelAsync(model); + return View(vm); + } + + + /// + /// Show logout page + /// + [HttpGet] + public async Task Logout(string logoutId) + { + // build a model so the logout page knows what to display + var vm = await BuildLogoutViewModelAsync(logoutId); + + if (vm.ShowLogoutPrompt == false) + { + // if the request for logout was properly authenticated from IdentityServer, then + // we don't need to show the prompt and can just log the user out directly. + return await Logout(vm); + } + + return View(vm); + } + + /// + /// Handle logout page postback + /// + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Logout(LogoutInputModel model) + { + // build a model so the logged out page knows what to display + var vm = await BuildLoggedOutViewModelAsync(model.LogoutId); + + if (User?.Identity.IsAuthenticated == true) + { + // delete local authentication cookie + await HttpContext.SignOutAsync(); + + // raise the logout event + await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName())); + } + + // check if we need to trigger sign-out at an upstream identity provider + if (vm.TriggerExternalSignout) + { + // build a return URL so the upstream provider will redirect back + // to us after the user has logged out. this allows us to then + // complete our single sign-out processing. + string url = Url.Action("Logout", new { logoutId = vm.LogoutId }); + + // this triggers a redirect to the external provider for sign-out + return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme); + } + + return View("LoggedOut", vm); + } + + [HttpGet] + public IActionResult AccessDenied() + { + return View(); + } + + + /*****************************************/ + /* helper APIs for the AccountController */ + /*****************************************/ + private async Task BuildLoginViewModelAsync(string returnUrl) + { + var context = await _interaction.GetAuthorizationContextAsync(returnUrl); + if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null) + { + var local = context.IdP == IdentityServer4.IdentityServerConstants.LocalIdentityProvider; + + // this is meant to short circuit the UI and only trigger the one external IdP + var vm = new LoginViewModel + { + EnableLocalLogin = local, + ReturnUrl = returnUrl, + Username = context?.LoginHint, + }; + + if (!local) + { + vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } }; + } + + return vm; + } + + var schemes = await _schemeProvider.GetAllSchemesAsync(); + + var providers = schemes + .Where(x => x.DisplayName != null || + (x.Name.Equals(AccountOptions.WindowsAuthenticationSchemeName, StringComparison.OrdinalIgnoreCase)) + ) + .Select(x => new ExternalProvider + { + DisplayName = x.DisplayName, + AuthenticationScheme = x.Name + }).ToList(); + + var allowLocal = true; + if (context?.ClientId != null) + { + var client = await _clientStore.FindEnabledClientByIdAsync(context.ClientId); + if (client != null) + { + allowLocal = client.EnableLocalLogin; + + if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any()) + { + providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList(); + } + } + } + + return new LoginViewModel + { + AllowRememberLogin = AccountOptions.AllowRememberLogin, + EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin, + ReturnUrl = returnUrl, + Username = context?.LoginHint, + ExternalProviders = providers.ToArray() + }; + } + + private async Task BuildLoginViewModelAsync(LoginInputModel model) + { + var vm = await BuildLoginViewModelAsync(model.ReturnUrl); + vm.Username = model.Username; + vm.RememberLogin = model.RememberLogin; + return vm; + } + + private async Task BuildLogoutViewModelAsync(string logoutId) + { + var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt }; + + if (User?.Identity.IsAuthenticated != true) + { + // if the user is not authenticated, then just show logged out page + vm.ShowLogoutPrompt = false; + return vm; + } + + var context = await _interaction.GetLogoutContextAsync(logoutId); + if (context?.ShowSignoutPrompt == false) + { + // it's safe to automatically sign-out + vm.ShowLogoutPrompt = false; + return vm; + } + + // show the logout prompt. this prevents attacks where the user + // is automatically signed out by another malicious web page. + return vm; + } + + private async Task BuildLoggedOutViewModelAsync(string logoutId) + { + // get context information (client name, post logout redirect URI and iframe for federated signout) + var logout = await _interaction.GetLogoutContextAsync(logoutId); + + var vm = new LoggedOutViewModel + { + AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut, + PostLogoutRedirectUri = logout?.PostLogoutRedirectUri, + ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName, + SignOutIframeUrl = logout?.SignOutIFrameUrl, + LogoutId = logoutId + }; + + if (User?.Identity.IsAuthenticated == true) + { + var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value; + if (idp != null && idp != IdentityServer4.IdentityServerConstants.LocalIdentityProvider) + { + var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp); + if (providerSupportsSignout) + { + if (vm.LogoutId == null) + { + // if there's no current logout context, we need to create one + // this captures necessary info from the current logged in user + // before we signout and redirect away to the external IdP for signout + vm.LogoutId = await _interaction.CreateLogoutContextAsync(); + } + + vm.ExternalAuthenticationScheme = idp; + } + } + } + + return vm; + } + } +} diff --git a/OpenAuth.Identity/Quickstart/Account/AccountOptions.cs b/OpenAuth.Identity/Quickstart/Account/AccountOptions.cs new file mode 100644 index 0000000..a451ce0 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/AccountOptions.cs @@ -0,0 +1,25 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System; + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + public class AccountOptions + { + public static bool AllowLocalLogin = true; + public static bool AllowRememberLogin = true; + public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30); + + public static bool ShowLogoutPrompt = true; + public static bool AutomaticRedirectAfterSignOut = true; //允许注销后跳转 + + // specify the Windows authentication scheme being used + public static readonly string WindowsAuthenticationSchemeName = Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme; + // if user uses windows auth, should we load the groups from windows + public static bool IncludeWindowsGroups = false; + + public static string InvalidCredentialsErrorMessage = "Invalid username or password"; + } +} diff --git a/OpenAuth.Identity/Quickstart/Account/ExternalController.cs b/OpenAuth.Identity/Quickstart/Account/ExternalController.cs new file mode 100644 index 0000000..e3cd696 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/ExternalController.cs @@ -0,0 +1,251 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Security.Principal; +using System.Threading.Tasks; +using IdentityModel; +using IdentityServer4.Events; +using IdentityServer4.Services; +using IdentityServer4.Stores; +using IdentityServer4.Test; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + [SecurityHeaders] + [AllowAnonymous] + public class ExternalController : Controller + { + private readonly TestUserStore _users; + private readonly IIdentityServerInteractionService _interaction; + private readonly IClientStore _clientStore; + private readonly ILogger _logger; + private readonly IEventService _events; + + public ExternalController( + IIdentityServerInteractionService interaction, + IClientStore clientStore, + IEventService events, + ILogger logger, + TestUserStore users = null) + { + // if the TestUserStore is not in DI, then we'll just use the global users collection + // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity) + _users = users ?? new TestUserStore(TestUsers.Users); + + _interaction = interaction; + _clientStore = clientStore; + _logger = logger; + _events = events; + } + + /// + /// initiate roundtrip to external authentication provider + /// + [HttpGet] + public async Task Challenge(string provider, string returnUrl) + { + if (string.IsNullOrEmpty(returnUrl)) returnUrl = "~/"; + + // validate returnUrl - either it is a valid OIDC URL or back to a local page + if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false) + { + // user might have clicked on a malicious link - should be logged + throw new Exception("invalid return URL"); + } + + if (AccountOptions.WindowsAuthenticationSchemeName == provider) + { + // windows authentication needs special handling + return await ProcessWindowsLoginAsync(returnUrl); + } + else + { + // start challenge and roundtrip the return URL and scheme + var props = new AuthenticationProperties + { + RedirectUri = Url.Action(nameof(Callback)), + Items = + { + { "returnUrl", returnUrl }, + { "scheme", provider }, + } + }; + + return Challenge(props, provider); + } + } + + /// + /// Post processing of external authentication + /// + [HttpGet] + public async Task Callback() + { + // read external identity from the temporary cookie + var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); + if (result?.Succeeded != true) + { + throw new Exception("External authentication error"); + } + + if (_logger.IsEnabled(LogLevel.Debug)) + { + var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}"); + _logger.LogDebug("External claims: {@claims}", externalClaims); + } + + // lookup our user and external provider info + var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result); + if (user == null) + { + // this might be where you might initiate a custom workflow for user registration + // in this sample we don't show how that would be done, as our sample implementation + // simply auto-provisions new external user + user = AutoProvisionUser(provider, providerUserId, claims); + } + + // this allows us to collect any additonal claims or properties + // for the specific prtotocols used and store them in the local auth cookie. + // this is typically used to store data needed for signout from those protocols. + var additionalLocalClaims = new List(); + var localSignInProps = new AuthenticationProperties(); + ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); + ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); + ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); + + // issue authentication cookie for user + await HttpContext.SignInAsync(user.SubjectId, user.Username, provider, localSignInProps, additionalLocalClaims.ToArray()); + + // delete temporary cookie used during external authentication + await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); + + // retrieve return URL + var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; + + // check if external login is in the context of an OIDC request + var context = await _interaction.GetAuthorizationContextAsync(returnUrl); + await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.ClientId)); + + if (context != null) + { + if (await _clientStore.IsPkceClientAsync(context.ClientId)) + { + // if the client is PKCE then we assume it's native, so this change in how to + // return the response is for better UX for the end user. + return View("Redirect", new RedirectViewModel { RedirectUrl = returnUrl }); + } + } + + return Redirect(returnUrl); + } + + private async Task ProcessWindowsLoginAsync(string returnUrl) + { + // see if windows auth has already been requested and succeeded + var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName); + if (result?.Principal is WindowsPrincipal wp) + { + // we will issue the external cookie and then redirect the + // user back to the external callback, in essence, treating windows + // auth the same as any other external authentication mechanism + var props = new AuthenticationProperties() + { + RedirectUri = Url.Action("Callback"), + Items = + { + { "returnUrl", returnUrl }, + { "scheme", AccountOptions.WindowsAuthenticationSchemeName }, + } + }; + + var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName); + id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name)); + id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name)); + + // add the groups as claims -- be careful if the number of groups is too large + if (AccountOptions.IncludeWindowsGroups) + { + var wi = wp.Identity as WindowsIdentity; + var groups = wi.Groups.Translate(typeof(NTAccount)); + var roles = groups.Select(x => new Claim(JwtClaimTypes.Role, x.Value)); + id.AddClaims(roles); + } + + await HttpContext.SignInAsync( + IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme, + new ClaimsPrincipal(id), + props); + return Redirect(props.RedirectUri); + } + else + { + // trigger windows auth + // since windows auth don't support the redirect uri, + // this URL is re-triggered when we call challenge + return Challenge(AccountOptions.WindowsAuthenticationSchemeName); + } + } + + private (TestUser user, string provider, string providerUserId, IEnumerable claims) FindUserFromExternalProvider(AuthenticateResult result) + { + var externalUser = result.Principal; + + // try to determine the unique id of the external user (issued by the provider) + // the most common claim type for that are the sub claim and the NameIdentifier + // depending on the external provider, some other claim type might be used + var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ?? + externalUser.FindFirst(ClaimTypes.NameIdentifier) ?? + throw new Exception("Unknown userid"); + + // remove the user id claim so we don't include it as an extra claim if/when we provision the user + var claims = externalUser.Claims.ToList(); + claims.Remove(userIdClaim); + + var provider = result.Properties.Items["scheme"]; + var providerUserId = userIdClaim.Value; + + // find external user + var user = _users.FindByExternalProvider(provider, providerUserId); + + return (user, provider, providerUserId, claims); + } + + private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable claims) + { + var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList()); + return user; + } + + private void ProcessLoginCallbackForOidc(AuthenticateResult externalResult, List localClaims, AuthenticationProperties localSignInProps) + { + // if the external system sent a session id claim, copy it over + // so we can use it for single sign-out + var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId); + if (sid != null) + { + localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value)); + } + + // if the external provider issued an id_token, we'll keep it for signout + var id_token = externalResult.Properties.GetTokenValue("id_token"); + if (id_token != null) + { + localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = "id_token", Value = id_token } }); + } + } + + private void ProcessLoginCallbackForWsFed(AuthenticateResult externalResult, List localClaims, AuthenticationProperties localSignInProps) + { + } + + private void ProcessLoginCallbackForSaml2p(AuthenticateResult externalResult, List localClaims, AuthenticationProperties localSignInProps) + { + } + } +} diff --git a/OpenAuth.Identity/Quickstart/Account/ExternalProvider.cs b/OpenAuth.Identity/Quickstart/Account/ExternalProvider.cs new file mode 100644 index 0000000..9e8c9f7 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/ExternalProvider.cs @@ -0,0 +1,12 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + public class ExternalProvider + { + public string DisplayName { get; set; } + public string AuthenticationScheme { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Account/LoggedOutViewModel.cs b/OpenAuth.Identity/Quickstart/Account/LoggedOutViewModel.cs new file mode 100644 index 0000000..3eae772 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/LoggedOutViewModel.cs @@ -0,0 +1,19 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + public class LoggedOutViewModel + { + public string PostLogoutRedirectUri { get; set; } + public string ClientName { get; set; } + public string SignOutIframeUrl { get; set; } + + public bool AutomaticRedirectAfterSignOut { get; set; } = false; + + public string LogoutId { get; set; } + public bool TriggerExternalSignout => ExternalAuthenticationScheme != null; + public string ExternalAuthenticationScheme { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Account/LoginInputModel.cs b/OpenAuth.Identity/Quickstart/Account/LoginInputModel.cs new file mode 100644 index 0000000..58fd09c --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/LoginInputModel.cs @@ -0,0 +1,18 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System.ComponentModel.DataAnnotations; + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + public class LoginInputModel + { + [Required] + public string Username { get; set; } + [Required] + public string Password { get; set; } + public bool RememberLogin { get; set; } + public string ReturnUrl { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Account/LoginViewModel.cs b/OpenAuth.Identity/Quickstart/Account/LoginViewModel.cs new file mode 100644 index 0000000..86b273a --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/LoginViewModel.cs @@ -0,0 +1,22 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + public class LoginViewModel : LoginInputModel + { + public bool AllowRememberLogin { get; set; } = true; + public bool EnableLocalLogin { get; set; } = true; + + public IEnumerable ExternalProviders { get; set; } = Enumerable.Empty(); + public IEnumerable VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName)); + + public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1; + public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null; + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Account/LogoutInputModel.cs b/OpenAuth.Identity/Quickstart/Account/LogoutInputModel.cs new file mode 100644 index 0000000..06f745a --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/LogoutInputModel.cs @@ -0,0 +1,11 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + public class LogoutInputModel + { + public string LogoutId { get; set; } + } +} diff --git a/OpenAuth.Identity/Quickstart/Account/LogoutViewModel.cs b/OpenAuth.Identity/Quickstart/Account/LogoutViewModel.cs new file mode 100644 index 0000000..056cdf9 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/LogoutViewModel.cs @@ -0,0 +1,11 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + public class LogoutViewModel : LogoutInputModel + { + public bool ShowLogoutPrompt { get; set; } = true; + } +} diff --git a/OpenAuth.Identity/Quickstart/Account/RedirectViewModel.cs b/OpenAuth.Identity/Quickstart/Account/RedirectViewModel.cs new file mode 100644 index 0000000..6a6da8d --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Account/RedirectViewModel.cs @@ -0,0 +1,12 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + + +namespace OpenAuth.IdentityServer.Quickstart.Account +{ + public class RedirectViewModel + { + public string RedirectUrl { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Consent/ConsentController.cs b/OpenAuth.Identity/Quickstart/Consent/ConsentController.cs new file mode 100644 index 0000000..95343f8 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Consent/ConsentController.cs @@ -0,0 +1,266 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System.Linq; +using System.Threading.Tasks; +using IdentityServer4.Events; +using IdentityServer4.Extensions; +using IdentityServer4.Models; +using IdentityServer4.Services; +using IdentityServer4.Stores; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using OpenAuth.IdentityServer.Quickstart.Account; + +namespace OpenAuth.IdentityServer.Quickstart.Consent +{ + /// + /// This controller processes the consent UI + /// + [SecurityHeaders] + [Authorize] + public class ConsentController : Controller + { + private readonly IIdentityServerInteractionService _interaction; + private readonly IClientStore _clientStore; + private readonly IResourceStore _resourceStore; + private readonly IEventService _events; + private readonly ILogger _logger; + + public ConsentController( + IIdentityServerInteractionService interaction, + IClientStore clientStore, + IResourceStore resourceStore, + IEventService events, + ILogger logger) + { + _interaction = interaction; + _clientStore = clientStore; + _resourceStore = resourceStore; + _events = events; + _logger = logger; + } + + /// + /// Shows the consent screen + /// + /// + /// + [HttpGet] + public async Task Index(string returnUrl) + { + var vm = await BuildViewModelAsync(returnUrl); + if (vm != null) + { + return View("Index", vm); + } + + return View("Error"); + } + + /// + /// Handles the consent screen postback + /// + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Index(ConsentInputModel model) + { + var result = await ProcessConsent(model); + + if (result.IsRedirect) + { + if (await _clientStore.IsPkceClientAsync(result.ClientId)) + { + // if the client is PKCE then we assume it's native, so this change in how to + // return the response is for better UX for the end user. + return View("Redirect", new RedirectViewModel { RedirectUrl = result.RedirectUri }); + } + + return Redirect(result.RedirectUri); + } + + if (result.HasValidationError) + { + ModelState.AddModelError(string.Empty, result.ValidationError); + } + + if (result.ShowView) + { + return View("Index", result.ViewModel); + } + + return View("Error"); + } + + /*****************************************/ + /* helper APIs for the ConsentController */ + /*****************************************/ + private async Task ProcessConsent(ConsentInputModel model) + { + var result = new ProcessConsentResult(); + + // validate return url is still valid + var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); + if (request == null) return result; + + ConsentResponse grantedConsent = null; + + // user clicked 'no' - send back the standard 'access_denied' response + if (model?.Button == "no") + { + grantedConsent = ConsentResponse.Denied; + + // emit event + await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.ClientId, request.ScopesRequested)); + } + // user clicked 'yes' - validate the data + else if (model?.Button == "yes") + { + // if the user consented to some scope, build the response model + if (model.ScopesConsented != null && model.ScopesConsented.Any()) + { + var scopes = model.ScopesConsented; + if (ConsentOptions.EnableOfflineAccess == false) + { + scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess); + } + + grantedConsent = new ConsentResponse + { + RememberConsent = model.RememberConsent, + ScopesConsented = scopes.ToArray() + }; + + // emit event + await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.ClientId, request.ScopesRequested, grantedConsent.ScopesConsented, grantedConsent.RememberConsent)); + } + else + { + result.ValidationError = ConsentOptions.MustChooseOneErrorMessage; + } + } + else + { + result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage; + } + + if (grantedConsent != null) + { + // communicate outcome of consent back to identityserver + await _interaction.GrantConsentAsync(request, grantedConsent); + + // indicate that's it ok to redirect back to authorization endpoint + result.RedirectUri = model.ReturnUrl; + result.ClientId = request.ClientId; + } + else + { + // we need to redisplay the consent UI + result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model); + } + + return result; + } + + private async Task BuildViewModelAsync(string returnUrl, ConsentInputModel model = null) + { + var request = await _interaction.GetAuthorizationContextAsync(returnUrl); + if (request != null) + { + var client = await _clientStore.FindEnabledClientByIdAsync(request.ClientId); + if (client != null) + { + var resources = await _resourceStore.FindEnabledResourcesByScopeAsync(request.ScopesRequested); + if (resources != null && (resources.IdentityResources.Any() || resources.ApiResources.Any())) + { + return CreateConsentViewModel(model, returnUrl, request, client, resources); + } + else + { + _logger.LogError("No scopes matching: {0}", request.ScopesRequested.Aggregate((x, y) => x + ", " + y)); + } + } + else + { + _logger.LogError("Invalid client id: {0}", request.ClientId); + } + } + else + { + _logger.LogError("No consent request matching request: {0}", returnUrl); + } + + return null; + } + + private ConsentViewModel CreateConsentViewModel( + ConsentInputModel model, string returnUrl, + AuthorizationRequest request, + Client client, Resources resources) + { + var vm = new ConsentViewModel + { + RememberConsent = model?.RememberConsent ?? true, + ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty(), + + ReturnUrl = returnUrl, + + ClientName = client.ClientName ?? client.ClientId, + ClientUrl = client.ClientUri, + ClientLogoUrl = client.LogoUri, + AllowRememberConsent = client.AllowRememberConsent + }; + + vm.IdentityScopes = resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray(); + vm.ResourceScopes = resources.ApiResources.SelectMany(x => x.Scopes).Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray(); + if (ConsentOptions.EnableOfflineAccess && resources.OfflineAccess) + { + vm.ResourceScopes = vm.ResourceScopes.Union(new ScopeViewModel[] { + GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null) + }); + } + + return vm; + } + + private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check) + { + return new ScopeViewModel + { + Name = identity.Name, + DisplayName = identity.DisplayName, + Description = identity.Description, + Emphasize = identity.Emphasize, + Required = identity.Required, + Checked = check || identity.Required + }; + } + + public ScopeViewModel CreateScopeViewModel(Scope scope, bool check) + { + return new ScopeViewModel + { + Name = scope.Name, + DisplayName = scope.DisplayName, + Description = scope.Description, + Emphasize = scope.Emphasize, + Required = scope.Required, + Checked = check || scope.Required + }; + } + + private ScopeViewModel GetOfflineAccessScope(bool check) + { + return new ScopeViewModel + { + Name = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess, + DisplayName = ConsentOptions.OfflineAccessDisplayName, + Description = ConsentOptions.OfflineAccessDescription, + Emphasize = true, + Checked = check + }; + } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Consent/ConsentInputModel.cs b/OpenAuth.Identity/Quickstart/Consent/ConsentInputModel.cs new file mode 100644 index 0000000..7aeb4c4 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Consent/ConsentInputModel.cs @@ -0,0 +1,16 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System.Collections.Generic; + +namespace OpenAuth.IdentityServer.Quickstart.Consent +{ + public class ConsentInputModel + { + public string Button { get; set; } + public IEnumerable ScopesConsented { get; set; } + public bool RememberConsent { get; set; } + public string ReturnUrl { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Consent/ConsentOptions.cs b/OpenAuth.Identity/Quickstart/Consent/ConsentOptions.cs new file mode 100644 index 0000000..d472725 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Consent/ConsentOptions.cs @@ -0,0 +1,16 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +namespace OpenAuth.IdentityServer.Quickstart.Consent +{ + public class ConsentOptions + { + public static bool EnableOfflineAccess = true; + public static string OfflineAccessDisplayName = "Offline Access"; + public static string OfflineAccessDescription = "Access to your applications and resources, even when you are offline"; + + public static readonly string MustChooseOneErrorMessage = "You must pick at least one permission"; + public static readonly string InvalidSelectionErrorMessage = "Invalid selection"; + } +} diff --git a/OpenAuth.Identity/Quickstart/Consent/ConsentViewModel.cs b/OpenAuth.Identity/Quickstart/Consent/ConsentViewModel.cs new file mode 100644 index 0000000..77a9044 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Consent/ConsentViewModel.cs @@ -0,0 +1,19 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System.Collections.Generic; + +namespace OpenAuth.IdentityServer.Quickstart.Consent +{ + public class ConsentViewModel : ConsentInputModel + { + public string ClientName { get; set; } + public string ClientUrl { get; set; } + public string ClientLogoUrl { get; set; } + public bool AllowRememberConsent { get; set; } + + public IEnumerable IdentityScopes { get; set; } + public IEnumerable ResourceScopes { get; set; } + } +} diff --git a/OpenAuth.Identity/Quickstart/Consent/ProcessConsentResult.cs b/OpenAuth.Identity/Quickstart/Consent/ProcessConsentResult.cs new file mode 100644 index 0000000..e3b3f00 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Consent/ProcessConsentResult.cs @@ -0,0 +1,19 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +namespace OpenAuth.IdentityServer.Quickstart.Consent +{ + public class ProcessConsentResult + { + public bool IsRedirect => RedirectUri != null; + public string RedirectUri { get; set; } + public string ClientId { get; set; } + + public bool ShowView => ViewModel != null; + public ConsentViewModel ViewModel { get; set; } + + public bool HasValidationError => ValidationError != null; + public string ValidationError { get; set; } + } +} diff --git a/OpenAuth.Identity/Quickstart/Consent/ScopeViewModel.cs b/OpenAuth.Identity/Quickstart/Consent/ScopeViewModel.cs new file mode 100644 index 0000000..a75451a --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Consent/ScopeViewModel.cs @@ -0,0 +1,16 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +namespace OpenAuth.IdentityServer.Quickstart.Consent +{ + public class ScopeViewModel + { + public string Name { get; set; } + public string DisplayName { get; set; } + public string Description { get; set; } + public bool Emphasize { get; set; } + public bool Required { get; set; } + public bool Checked { get; set; } + } +} diff --git a/OpenAuth.Identity/Quickstart/Device/DeviceAuthorizationInputModel.cs b/OpenAuth.Identity/Quickstart/Device/DeviceAuthorizationInputModel.cs new file mode 100644 index 0000000..c78b6a2 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Device/DeviceAuthorizationInputModel.cs @@ -0,0 +1,13 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using OpenAuth.IdentityServer.Quickstart.Consent; + +namespace OpenAuth.IdentityServer.Quickstart.Device +{ + public class DeviceAuthorizationInputModel : ConsentInputModel + { + public string UserCode { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Device/DeviceAuthorizationViewModel.cs b/OpenAuth.Identity/Quickstart/Device/DeviceAuthorizationViewModel.cs new file mode 100644 index 0000000..a1b2bb1 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Device/DeviceAuthorizationViewModel.cs @@ -0,0 +1,14 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using OpenAuth.IdentityServer.Quickstart.Consent; + +namespace OpenAuth.IdentityServer.Quickstart.Device +{ + public class DeviceAuthorizationViewModel : ConsentViewModel + { + public string UserCode { get; set; } + public bool ConfirmUserCode { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Device/DeviceController.cs b/OpenAuth.Identity/Quickstart/Device/DeviceController.cs new file mode 100644 index 0000000..15fe30c --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Device/DeviceController.cs @@ -0,0 +1,243 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System; +using System.Linq; +using System.Threading.Tasks; +using IdentityServer4.Configuration; +using IdentityServer4.Events; +using IdentityServer4.Extensions; +using IdentityServer4.Models; +using IdentityServer4.Services; +using IdentityServer4.Stores; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using OpenAuth.IdentityServer.Quickstart.Consent; + +namespace OpenAuth.IdentityServer.Quickstart.Device +{ + [Authorize] + [SecurityHeaders] + public class DeviceController : Controller + { + private readonly IDeviceFlowInteractionService _interaction; + private readonly IClientStore _clientStore; + private readonly IResourceStore _resourceStore; + private readonly IEventService _events; + private readonly IOptions _options; + private readonly ILogger _logger; + + public DeviceController( + IDeviceFlowInteractionService interaction, + IClientStore clientStore, + IResourceStore resourceStore, + IEventService eventService, + IOptions options, + ILogger logger) + { + _interaction = interaction; + _clientStore = clientStore; + _resourceStore = resourceStore; + _events = eventService; + _options = options; + _logger = logger; + } + + [HttpGet] + public async Task Index() + { + string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter; + string userCode = Request.Query[userCodeParamName]; + if (string.IsNullOrWhiteSpace(userCode)) return View("UserCodeCapture"); + + var vm = await BuildViewModelAsync(userCode); + if (vm == null) return View("Error"); + + vm.ConfirmUserCode = true; + return View("UserCodeConfirmation", vm); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task UserCodeCapture(string userCode) + { + var vm = await BuildViewModelAsync(userCode); + if (vm == null) return View("Error"); + + return View("UserCodeConfirmation", vm); + } + + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Callback(DeviceAuthorizationInputModel model) + { + if (model == null) throw new ArgumentNullException(nameof(model)); + + var result = await ProcessConsent(model); + if (result.HasValidationError) return View("Error"); + + return View("Success"); + } + + private async Task ProcessConsent(DeviceAuthorizationInputModel model) + { + var result = new ProcessConsentResult(); + + var request = await _interaction.GetAuthorizationContextAsync(model.UserCode); + if (request == null) return result; + + ConsentResponse grantedConsent = null; + + // user clicked 'no' - send back the standard 'access_denied' response + if (model.Button == "no") + { + grantedConsent = ConsentResponse.Denied; + + // emit event + await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.ClientId, request.ScopesRequested)); + } + // user clicked 'yes' - validate the data + else if (model.Button == "yes") + { + // if the user consented to some scope, build the response model + if (model.ScopesConsented != null && model.ScopesConsented.Any()) + { + var scopes = model.ScopesConsented; + if (ConsentOptions.EnableOfflineAccess == false) + { + scopes = scopes.Where(x => x != IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess); + } + + grantedConsent = new ConsentResponse + { + RememberConsent = model.RememberConsent, + ScopesConsented = scopes.ToArray() + }; + + // emit event + await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.ClientId, request.ScopesRequested, grantedConsent.ScopesConsented, grantedConsent.RememberConsent)); + } + else + { + result.ValidationError = ConsentOptions.MustChooseOneErrorMessage; + } + } + else + { + result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage; + } + + if (grantedConsent != null) + { + // communicate outcome of consent back to identityserver + await _interaction.HandleRequestAsync(model.UserCode, grantedConsent); + + // indicate that's it ok to redirect back to authorization endpoint + result.RedirectUri = model.ReturnUrl; + result.ClientId = request.ClientId; + } + else + { + // we need to redisplay the consent UI + result.ViewModel = await BuildViewModelAsync(model.UserCode, model); + } + + return result; + } + + private async Task BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null) + { + var request = await _interaction.GetAuthorizationContextAsync(userCode); + if (request != null) + { + var client = await _clientStore.FindEnabledClientByIdAsync(request.ClientId); + if (client != null) + { + var resources = await _resourceStore.FindEnabledResourcesByScopeAsync(request.ScopesRequested); + if (resources != null && (resources.IdentityResources.Any() || resources.ApiResources.Any())) + { + return CreateConsentViewModel(userCode, model, client, resources); + } + else + { + _logger.LogError("No scopes matching: {0}", request.ScopesRequested.Aggregate((x, y) => x + ", " + y)); + } + } + else + { + _logger.LogError("Invalid client id: {0}", request.ClientId); + } + } + + return null; + } + + private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, Client client, Resources resources) + { + var vm = new DeviceAuthorizationViewModel + { + UserCode = userCode, + + RememberConsent = model?.RememberConsent ?? true, + ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty(), + + ClientName = client.ClientName ?? client.ClientId, + ClientUrl = client.ClientUri, + ClientLogoUrl = client.LogoUri, + AllowRememberConsent = client.AllowRememberConsent + }; + + vm.IdentityScopes = resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray(); + vm.ResourceScopes = resources.ApiResources.SelectMany(x => x.Scopes).Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray(); + if (ConsentOptions.EnableOfflineAccess && resources.OfflineAccess) + { + vm.ResourceScopes = vm.ResourceScopes.Union(new[] + { + GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null) + }); + } + + return vm; + } + + private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check) + { + return new ScopeViewModel + { + Name = identity.Name, + DisplayName = identity.DisplayName, + Description = identity.Description, + Emphasize = identity.Emphasize, + Required = identity.Required, + Checked = check || identity.Required + }; + } + + public ScopeViewModel CreateScopeViewModel(Scope scope, bool check) + { + return new ScopeViewModel + { + Name = scope.Name, + DisplayName = scope.DisplayName, + Description = scope.Description, + Emphasize = scope.Emphasize, + Required = scope.Required, + Checked = check || scope.Required + }; + } + private ScopeViewModel GetOfflineAccessScope(bool check) + { + return new ScopeViewModel + { + Name = IdentityServer4.IdentityServerConstants.StandardScopes.OfflineAccess, + DisplayName = ConsentOptions.OfflineAccessDisplayName, + Description = ConsentOptions.OfflineAccessDescription, + Emphasize = true, + Checked = check + }; + } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Diagnostics/DiagnosticsController.cs b/OpenAuth.Identity/Quickstart/Diagnostics/DiagnosticsController.cs new file mode 100644 index 0000000..e4a9c45 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Diagnostics/DiagnosticsController.cs @@ -0,0 +1,29 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace OpenAuth.IdentityServer.Quickstart.Diagnostics +{ + [SecurityHeaders] + [Authorize] + public class DiagnosticsController : Controller + { + public async Task Index() + { + var localAddresses = new string[] { "127.0.0.1", "::1", HttpContext.Connection.LocalIpAddress.ToString() }; + if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString())) + { + return NotFound(); + } + + var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync()); + return View(model); + } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Diagnostics/DiagnosticsViewModel.cs b/OpenAuth.Identity/Quickstart/Diagnostics/DiagnosticsViewModel.cs new file mode 100644 index 0000000..e24c242 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Diagnostics/DiagnosticsViewModel.cs @@ -0,0 +1,32 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System.Collections.Generic; +using System.Text; +using IdentityModel; +using Microsoft.AspNetCore.Authentication; +using Newtonsoft.Json; + +namespace OpenAuth.IdentityServer.Quickstart.Diagnostics +{ + public class DiagnosticsViewModel + { + public DiagnosticsViewModel(AuthenticateResult result) + { + AuthenticateResult = result; + + if (result.Properties.Items.ContainsKey("client_list")) + { + var encoded = result.Properties.Items["client_list"]; + var bytes = Base64Url.Decode(encoded); + var value = Encoding.UTF8.GetString(bytes); + + Clients = JsonConvert.DeserializeObject(value); + } + } + + public AuthenticateResult AuthenticateResult { get; } + public IEnumerable Clients { get; } = new List(); + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Extensions.cs b/OpenAuth.Identity/Quickstart/Extensions.cs new file mode 100644 index 0000000..560e4b9 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Extensions.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; +using IdentityServer4.Stores; + +namespace OpenAuth.IdentityServer.Quickstart +{ + public static class Extensions + { + /// + /// Determines whether the client is configured to use PKCE. + /// + /// The store. + /// The client identifier. + /// + public static async Task IsPkceClientAsync(this IClientStore store, string client_id) + { + if (!string.IsNullOrWhiteSpace(client_id)) + { + var client = await store.FindEnabledClientByIdAsync(client_id); + return client?.RequirePkce == true; + } + + return false; + } + } +} diff --git a/OpenAuth.Identity/Quickstart/Grants/GrantsController.cs b/OpenAuth.Identity/Quickstart/Grants/GrantsController.cs new file mode 100644 index 0000000..c1d2695 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Grants/GrantsController.cs @@ -0,0 +1,96 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using IdentityServer4.Events; +using IdentityServer4.Extensions; +using IdentityServer4.Services; +using IdentityServer4.Stores; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace OpenAuth.IdentityServer.Quickstart.Grants +{ + /// + /// This sample controller allows a user to revoke grants given to clients + /// + [SecurityHeaders] + [Authorize] + public class GrantsController : Controller + { + private readonly IIdentityServerInteractionService _interaction; + private readonly IClientStore _clients; + private readonly IResourceStore _resources; + private readonly IEventService _events; + + public GrantsController(IIdentityServerInteractionService interaction, + IClientStore clients, + IResourceStore resources, + IEventService events) + { + _interaction = interaction; + _clients = clients; + _resources = resources; + _events = events; + } + + /// + /// Show list of grants + /// + [HttpGet] + public async Task Index() + { + return View("Index", await BuildViewModelAsync()); + } + + /// + /// Handle postback to revoke a client + /// + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Revoke(string clientId) + { + await _interaction.RevokeUserConsentAsync(clientId); + await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId)); + + return RedirectToAction("Index"); + } + + private async Task BuildViewModelAsync() + { + var grants = await _interaction.GetAllUserConsentsAsync(); + + var list = new List(); + foreach(var grant in grants) + { + var client = await _clients.FindClientByIdAsync(grant.ClientId); + if (client != null) + { + var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes); + + var item = new GrantViewModel() + { + ClientId = client.ClientId, + ClientName = client.ClientName ?? client.ClientId, + ClientLogoUrl = client.LogoUri, + ClientUrl = client.ClientUri, + Created = grant.CreationTime, + Expires = grant.Expiration, + IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(), + ApiGrantNames = resources.ApiResources.Select(x => x.DisplayName ?? x.Name).ToArray() + }; + + list.Add(item); + } + } + + return new GrantsViewModel + { + Grants = list + }; + } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Grants/GrantsViewModel.cs b/OpenAuth.Identity/Quickstart/Grants/GrantsViewModel.cs new file mode 100644 index 0000000..4281aeb --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Grants/GrantsViewModel.cs @@ -0,0 +1,26 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System; +using System.Collections.Generic; + +namespace OpenAuth.IdentityServer.Quickstart.Grants +{ + public class GrantsViewModel + { + public IEnumerable Grants { get; set; } + } + + public class GrantViewModel + { + public string ClientId { get; set; } + public string ClientName { get; set; } + public string ClientUrl { get; set; } + public string ClientLogoUrl { get; set; } + public DateTime Created { get; set; } + public DateTime? Expires { get; set; } + public IEnumerable IdentityGrantNames { get; set; } + public IEnumerable ApiGrantNames { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Home/ErrorViewModel.cs b/OpenAuth.Identity/Quickstart/Home/ErrorViewModel.cs new file mode 100644 index 0000000..cf06e2c --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Home/ErrorViewModel.cs @@ -0,0 +1,22 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using IdentityServer4.Models; + +namespace OpenAuth.IdentityServer.Quickstart.Home +{ + public class ErrorViewModel + { + public ErrorViewModel() + { + } + + public ErrorViewModel(string error) + { + Error = new ErrorMessage { Error = error }; + } + + public ErrorMessage Error { get; set; } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/Home/HomeController.cs b/OpenAuth.Identity/Quickstart/Home/HomeController.cs new file mode 100644 index 0000000..2f89b2a --- /dev/null +++ b/OpenAuth.Identity/Quickstart/Home/HomeController.cs @@ -0,0 +1,64 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System.Threading.Tasks; +using IdentityServer4.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace OpenAuth.IdentityServer.Quickstart.Home +{ + [SecurityHeaders] + [AllowAnonymous] + public class HomeController : Controller + { + private readonly IIdentityServerInteractionService _interaction; + private readonly IHostEnvironment _environment; + private readonly ILogger _logger; + + public HomeController(IIdentityServerInteractionService interaction, IHostEnvironment environment, ILogger logger) + { + _interaction = interaction; + _environment = environment; + _logger = logger; + } + + public IActionResult Index() + { + if (_environment.IsDevelopment()) + { + // only show in development + return View(); + } + + _logger.LogInformation("Homepage is disabled in production. Returning 404."); + return NotFound(); + } + + /// + /// Shows the error page + /// + public async Task Error(string errorId) + { + var vm = new ErrorViewModel(); + + // retrieve error details from identityserver + var message = await _interaction.GetErrorContextAsync(errorId); + if (message != null) + { + vm.Error = message; + + if (!_environment.IsDevelopment()) + { + // only show in development + message.ErrorDescription = null; + } + } + + return View("Error", vm); + } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Quickstart/SecurityHeadersAttribute.cs b/OpenAuth.Identity/Quickstart/SecurityHeadersAttribute.cs new file mode 100644 index 0000000..9b28dfe --- /dev/null +++ b/OpenAuth.Identity/Quickstart/SecurityHeadersAttribute.cs @@ -0,0 +1,56 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; + +namespace OpenAuth.IdentityServer.Quickstart +{ + public class SecurityHeadersAttribute : ActionFilterAttribute + { + public override void OnResultExecuting(ResultExecutingContext context) + { + var result = context.Result; + if (result is ViewResult) + { + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + // if (!context.HttpContext.Response.Headers.ContainsKey("X-Content-Type-Options")) + // { + // context.HttpContext.Response.Headers.Add("X-Content-Type-Options", "nosniff"); + // } + // + // // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + // if (!context.HttpContext.Response.Headers.ContainsKey("X-Frame-Options")) + // { + // context.HttpContext.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN"); + // } + + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + // var csp = "default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';"; + // also consider adding upgrade-insecure-requests once you have HTTPS in place for production + //csp += "upgrade-insecure-requests;"; + // also an example if you need client images to be displayed from twitter + // csp += "img-src 'self' https://pbs.twimg.com;"; + + // once for standards compliant browsers + // if (!context.HttpContext.Response.Headers.ContainsKey("Content-Security-Policy")) + // { + // context.HttpContext.Response.Headers.Add("Content-Security-Policy", csp); + // } + // // and once again for IE + // if (!context.HttpContext.Response.Headers.ContainsKey("X-Content-Security-Policy")) + // { + // context.HttpContext.Response.Headers.Add("X-Content-Security-Policy", csp); + // } + + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy + // var referrer_policy = "no-referrer"; + // if (!context.HttpContext.Response.Headers.ContainsKey("Referrer-Policy")) + // { + // context.HttpContext.Response.Headers.Add("Referrer-Policy", referrer_policy); + // } + } + } + } +} diff --git a/OpenAuth.Identity/Quickstart/TestUsers.cs b/OpenAuth.Identity/Quickstart/TestUsers.cs new file mode 100644 index 0000000..7735c10 --- /dev/null +++ b/OpenAuth.Identity/Quickstart/TestUsers.cs @@ -0,0 +1,27 @@ +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + + +using System.Collections.Generic; +using System.Security.Claims; +using IdentityModel; +using IdentityServer4.Test; +using Infrastructure; +using OpenAuth.App; + +namespace OpenAuth.IdentityServer.Quickstart +{ + public class TestUsers + { + public static List Users = new List + { + new TestUser{SubjectId = "System", Username = Define.SYSTEM_USERNAME, Password = Define.SYSTEM_USERPWD, + Claims = + { + new Claim(JwtClaimTypes.Name, "System"), + new Claim(JwtClaimTypes.GivenName, "yubao"), + new Claim(JwtClaimTypes.FamilyName, "lee")} + } + }; + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/SameSiteCookiesServiceCollectionExtensions.cs b/OpenAuth.Identity/SameSiteCookiesServiceCollectionExtensions.cs new file mode 100644 index 0000000..752f8c0 --- /dev/null +++ b/OpenAuth.Identity/SameSiteCookiesServiceCollectionExtensions.cs @@ -0,0 +1,136 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; + +namespace OpenAuth.IdentityServer +{ + public static class SameSiteCookiesServiceCollectionExtensions + { + /// + /// -1 defines the unspecified value, which tells ASPNET Core to NOT + /// send the SameSite attribute. With ASPNET Core 3.1 the + /// enum will have a definition for + /// Unspecified. + /// + private const SameSiteMode Unspecified = (SameSiteMode) (-1); + + /// + /// Configures a cookie policy to properly set the SameSite attribute + /// for Browsers that handle unknown values as Strict. Ensure that you + /// add the + /// into the pipeline before sending any cookies! + /// + /// + /// Minimum ASPNET Core Version required for this code: + /// - 2.1.14 + /// - 2.2.8 + /// - 3.0.1 + /// - 3.1.0-preview1 + /// Starting with version 80 of Chrome (to be released in February 2020) + /// cookies with NO SameSite attribute are treated as SameSite=Lax. + /// In order to always get the cookies send they need to be set to + /// SameSite=None. But since the current standard only defines Lax and + /// Strict as valid values there are some browsers that treat invalid + /// values as SameSite=Strict. We therefore need to check the browser + /// and either send SameSite=None or prevent the sending of SameSite=None. + /// Relevant links: + /// - https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-4.1 + /// - https://tools.ietf.org/html/draft-west-cookie-incrementalism-00 + /// - https://www.chromium.org/updates/same-site + /// - https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/ + /// - https://bugs.webkit.org/show_bug.cgi?id=198181 + /// + /// The service collection to register into. + /// The modified . + public static IServiceCollection ConfigureNonBreakingSameSiteCookies(this IServiceCollection services) + { + services.Configure(options => + { + options.MinimumSameSitePolicy = Unspecified; + options.OnAppendCookie = cookieContext => + CheckSameSite(cookieContext.Context, cookieContext.CookieOptions); + options.OnDeleteCookie = cookieContext => + CheckSameSite(cookieContext.Context, cookieContext.CookieOptions); + }); + + return services; + } + + private static void CheckSameSite(HttpContext httpContext, CookieOptions options) + { + if (options.SameSite == SameSiteMode.None) + { + var userAgent = httpContext.Request.Headers["User-Agent"].ToString(); + + // if (DisallowsSameSiteNone(userAgent)) + // { + options.SameSite = Unspecified; + // } + } + } + + /// + /// Checks if the UserAgent is known to interpret an unknown value as Strict. + /// For those the property should be + /// set to . + /// + /// + /// This code is taken from Microsoft: + /// https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/ + /// + /// The user agent string to check. + /// Whether the specified user agent (browser) accepts SameSite=None or not. + private static bool DisallowsSameSiteNone(string userAgent) + { + // Cover all iOS based browsers here. This includes: + // - Safari on iOS 12 for iPhone, iPod Touch, iPad + // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad + // - Chrome on iOS 12 for iPhone, iPod Touch, iPad + // All of which are broken by SameSite=None, because they use the + // iOS networking stack. + // Notes from Thinktecture: + // Regarding https://caniuse.com/#search=samesite iOS versions lower + // than 12 are not supporting SameSite at all. Starting with version 13 + // unknown values are NOT treated as strict anymore. Therefore we only + // need to check version 12. + if (userAgent.Contains("CPU iPhone OS 12") + || userAgent.Contains("iPad; CPU OS 12")) + { + return true; + } + + // Cover Mac OS X based browsers that use the Mac OS networking stack. + // This includes: + // - Safari on Mac OS X. + // This does not include: + // - Chrome on Mac OS X + // because they do not use the Mac OS networking stack. + // Notes from Thinktecture: + // Regarding https://caniuse.com/#search=samesite MacOS X versions lower + // than 10.14 are not supporting SameSite at all. Starting with version + // 10.15 unknown values are NOT treated as strict anymore. Therefore we + // only need to check version 10.14. + if (userAgent.Contains("Safari") + && userAgent.Contains("Macintosh; Intel Mac OS X 10_14") + && userAgent.Contains("Version/")) + { + return true; + } + + // Cover Chrome 50-69, because some versions are broken by SameSite=None + // and none in this range require it. + // Note: this covers some pre-Chromium Edge versions, + // but pre-Chromium Edge does not require SameSite=None. + // Notes from Thinktecture: + // We can not validate this assumption, but we trust Microsofts + // evaluation. And overall not sending a SameSite value equals to the same + // behavior as SameSite=None for these old versions anyways. + if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6")) + { + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Startup.cs b/OpenAuth.Identity/Startup.cs new file mode 100644 index 0000000..28f2a9b --- /dev/null +++ b/OpenAuth.Identity/Startup.cs @@ -0,0 +1,81 @@ +using System; +using System.Linq; +using Autofac; +using Infrastructure; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenAuth.App; +using OpenAuth.Repository; + +namespace OpenAuth.IdentityServer +{ + public class Startup + { + public IHostEnvironment Environment { get; } + public IConfiguration Configuration { get; } + public Startup(IConfiguration configuration, IHostEnvironment environment) + { + Configuration = configuration; + Environment = environment; + } + + public void ConfigureServices(IServiceCollection services) + { + services.AddControllersWithViews(); + + var builder = services.AddIdentityServer() + .AddDeveloperSigningCredential() + .AddInMemoryApiScopes(Config.ApiScopes) + .AddInMemoryClients(Config.GetClients()); + //.AddInMemoryIdentityResources(Config.GetIdentityResources()) + //.AddInMemoryApiResources(Config.GetApis()) + //.AddProfileService(); + + services.ConfigureNonBreakingSameSiteCookies(); + + services.AddCors(); + + builder.AddDeveloperSigningCredential(); + + services.AddAuthentication(); + + //映射配置文件 + services.Configure(Configuration.GetSection("AppSetting")); + } + + public void ConfigureContainer(ContainerBuilder builder) + { + AutofacExt.InitAutofac(builder); + } + + public void Configure(IApplicationBuilder app, IHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + + app.UseCookiePolicy(); + + //todo:测试可以允许任意跨域,正式环境要加权限 + app.UseCors(builder => builder.AllowAnyOrigin() + .AllowAnyMethod() + .AllowAnyHeader()); + + app.UseStaticFiles(); + app.UseRouting(); + + app.UseIdentityServer(); + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapDefaultControllerRoute(); + }); + } + } +} \ No newline at end of file diff --git a/OpenAuth.Identity/Views/Account/AccessDenied.cshtml b/OpenAuth.Identity/Views/Account/AccessDenied.cshtml new file mode 100644 index 0000000..ff22987 --- /dev/null +++ b/OpenAuth.Identity/Views/Account/AccessDenied.cshtml @@ -0,0 +1,8 @@ + +
+ + +

You do not have access to that resource.

+
\ No newline at end of file diff --git a/OpenAuth.Identity/Views/Account/LoggedOut.cshtml b/OpenAuth.Identity/Views/Account/LoggedOut.cshtml new file mode 100644 index 0000000..14db8f9 --- /dev/null +++ b/OpenAuth.Identity/Views/Account/LoggedOut.cshtml @@ -0,0 +1,34 @@ +@model OpenAuth.IdentityServer.Quickstart.Account.LoggedOutViewModel + +@{ + // set this so the layout rendering sees an anonymous user + ViewData["signed-out"] = true; +} + + + +@section scripts +{ + @if (Model.AutomaticRedirectAfterSignOut) + { + + } +} diff --git a/OpenAuth.Identity/Views/Account/Login.cshtml b/OpenAuth.Identity/Views/Account/Login.cshtml new file mode 100644 index 0000000..d906d90 --- /dev/null +++ b/OpenAuth.Identity/Views/Account/Login.cshtml @@ -0,0 +1,92 @@ +@model OpenAuth.IdentityServer.Quickstart.Account.LoginViewModel + + \ No newline at end of file diff --git a/OpenAuth.Identity/Views/Account/Logout.cshtml b/OpenAuth.Identity/Views/Account/Logout.cshtml new file mode 100644 index 0000000..648fecc --- /dev/null +++ b/OpenAuth.Identity/Views/Account/Logout.cshtml @@ -0,0 +1,21 @@ +@model OpenAuth.IdentityServer.Quickstart.Account.LogoutViewModel + +
+ + +
+
+

Would you like to logout of IdentityServer?

+
+ +
+
+ +
+
+
+
+
+
\ No newline at end of file diff --git a/OpenAuth.Identity/Views/Consent/Index.cshtml b/OpenAuth.Identity/Views/Consent/Index.cshtml new file mode 100644 index 0000000..e990320 --- /dev/null +++ b/OpenAuth.Identity/Views/Consent/Index.cshtml @@ -0,0 +1,82 @@ +@model OpenAuth.IdentityServer.Quickstart.Consent.ConsentViewModel + + \ No newline at end of file diff --git a/OpenAuth.Identity/Views/Device/Success.cshtml b/OpenAuth.Identity/Views/Device/Success.cshtml new file mode 100644 index 0000000..f41cdef --- /dev/null +++ b/OpenAuth.Identity/Views/Device/Success.cshtml @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/OpenAuth.Identity/Views/Device/UserCodeCapture.cshtml b/OpenAuth.Identity/Views/Device/UserCodeCapture.cshtml new file mode 100644 index 0000000..cbe38dd --- /dev/null +++ b/OpenAuth.Identity/Views/Device/UserCodeCapture.cshtml @@ -0,0 +1,14 @@ +@model string + + \ No newline at end of file diff --git a/OpenAuth.Identity/Views/Device/UserCodeConfirmation.cshtml b/OpenAuth.Identity/Views/Device/UserCodeConfirmation.cshtml new file mode 100644 index 0000000..9861210 --- /dev/null +++ b/OpenAuth.Identity/Views/Device/UserCodeConfirmation.cshtml @@ -0,0 +1,93 @@ +@model OpenAuth.IdentityServer.Quickstart.Device.DeviceAuthorizationViewModel + + \ No newline at end of file diff --git a/OpenAuth.Identity/Views/Diagnostics/Index.cshtml b/OpenAuth.Identity/Views/Diagnostics/Index.cshtml new file mode 100644 index 0000000..c14c6d4 --- /dev/null +++ b/OpenAuth.Identity/Views/Diagnostics/Index.cshtml @@ -0,0 +1,32 @@ +@model OpenAuth.IdentityServer.Quickstart.Diagnostics.DiagnosticsViewModel + +

Authentication cookie

+ +

Claims

+
+ @foreach (var claim in Model.AuthenticateResult.Principal.Claims) + { +
@claim.Type
+
@claim.Value
+ } +
+ +

Properties

+
+ @foreach (var prop in Model.AuthenticateResult.Properties.Items) + { +
@prop.Key
+
@prop.Value
+ } +
+ +@if (Model.Clients.Any()) +{ +

Clients

+
    + @foreach (var client in Model.Clients) + { +
  • @client
  • + } +
+} \ No newline at end of file diff --git a/OpenAuth.Identity/Views/Grants/Index.cshtml b/OpenAuth.Identity/Views/Grants/Index.cshtml new file mode 100644 index 0000000..d34f007 --- /dev/null +++ b/OpenAuth.Identity/Views/Grants/Index.cshtml @@ -0,0 +1,79 @@ +@model OpenAuth.IdentityServer.Quickstart.Grants.GrantsViewModel + +
+ + + @if (Model.Grants.Any() == false) + { +
+
+
+ You have not given access to any applications +
+
+
+ } + else + { + foreach (var grant in Model.Grants) + { +
+
+ @if (grant.ClientLogoUrl != null) + { + + } +
+
+
@grant.ClientName
+
+ Created: @grant.Created.ToString("yyyy-MM-dd") +
+ @if (grant.Expires.HasValue) + { +
+ Expires: @grant.Expires.Value.ToString("yyyy-MM-dd") +
+ } + @if (grant.IdentityGrantNames.Any()) + { +
+
Identity Grants
+
    + @foreach (var name in grant.IdentityGrantNames) + { +
  • @name
  • + } +
+
+ } + @if (grant.ApiGrantNames.Any()) + { +
+
API Grants
+
    + @foreach (var name in grant.ApiGrantNames) + { +
  • @name
  • + } +
+
+ } +
+
+
+ + +
+
+
+ } + } +
\ No newline at end of file diff --git a/OpenAuth.Identity/Views/Home/Index.cshtml b/OpenAuth.Identity/Views/Home/Index.cshtml new file mode 100644 index 0000000..5720569 --- /dev/null +++ b/OpenAuth.Identity/Views/Home/Index.cshtml @@ -0,0 +1,39 @@ +@{ + var version = typeof(IdentityServer4.Hosting.IdentityServerMiddleware).Assembly.GetName().Version.ToString(); +} + +
+ + +
+
+

+ IdentityServer publishes a + discovery document + where you can find metadata and links to all the endpoints, key material, etc. +

+
+
+

+ Click here to manage your stored grants. +

+
+
+
+
+

+ Here are links to the + source code repository, + and ready to use samples. +

+
+
+
diff --git a/OpenAuth.Identity/Views/Shared/Error.cshtml b/OpenAuth.Identity/Views/Shared/Error.cshtml new file mode 100644 index 0000000..407f057 --- /dev/null +++ b/OpenAuth.Identity/Views/Shared/Error.cshtml @@ -0,0 +1,40 @@ +@model OpenAuth.IdentityServer.Quickstart.Home.ErrorViewModel + +@{ + var error = Model?.Error?.Error; + var errorDescription = Model?.Error?.ErrorDescription; + var request_id = Model?.Error?.RequestId; +} + +
+ + +
+
+
+ Sorry, there was an error + + @if (error != null) + { + + + : @error + + + + if (errorDescription != null) + { +
@errorDescription
+ } + } +
+ + @if (request_id != null) + { +
Request Id: @request_id
+ } +
+
+
diff --git a/OpenAuth.Identity/Views/Shared/Redirect.cshtml b/OpenAuth.Identity/Views/Shared/Redirect.cshtml new file mode 100644 index 0000000..73a7040 --- /dev/null +++ b/OpenAuth.Identity/Views/Shared/Redirect.cshtml @@ -0,0 +1,7 @@ +@model OpenAuth.IdentityServer.Quickstart.Account.RedirectViewModel + +

You are now being returned to the application.

+

Once complete, you may close this tab

+ + + diff --git a/OpenAuth.Identity/Views/Shared/_Layout.cshtml b/OpenAuth.Identity/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000..e825983 --- /dev/null +++ b/OpenAuth.Identity/Views/Shared/_Layout.cshtml @@ -0,0 +1,72 @@ +@using IdentityServer4.Extensions +@{ + string name = null; + if (!true.Equals(ViewData["signed-out"])) + { + name = Context.User?.GetDisplayName(); + } +} + + + + + + + OpenAuth.Net认证中心- 最好用的.net权限工作流框架|.net core快速开发框架|.net core权限管理|.net core工作流 + + + + + + + + + + +
+ @RenderBody() +
+ + + + + @RenderSection("scripts", required: false) + + diff --git a/OpenAuth.Identity/Views/Shared/_ScopeListItem.cshtml b/OpenAuth.Identity/Views/Shared/_ScopeListItem.cshtml new file mode 100644 index 0000000..1a3a6fd --- /dev/null +++ b/OpenAuth.Identity/Views/Shared/_ScopeListItem.cshtml @@ -0,0 +1,34 @@ +@model OpenAuth.IdentityServer.Quickstart.Consent.ScopeViewModel + +
  • + + @if (Model.Required) + { + (required) + } + @if (Model.Description != null) + { + + } +
  • \ No newline at end of file diff --git a/OpenAuth.Identity/Views/Shared/_ValidationSummary.cshtml b/OpenAuth.Identity/Views/Shared/_ValidationSummary.cshtml new file mode 100644 index 0000000..674d68d --- /dev/null +++ b/OpenAuth.Identity/Views/Shared/_ValidationSummary.cshtml @@ -0,0 +1,7 @@ +@if (ViewContext.ModelState.IsValid == false) +{ +
    + Error +
    +
    +} \ No newline at end of file diff --git a/OpenAuth.Identity/Views/_ViewImports.cshtml b/OpenAuth.Identity/Views/_ViewImports.cshtml new file mode 100644 index 0000000..afa82bb --- /dev/null +++ b/OpenAuth.Identity/Views/_ViewImports.cshtml @@ -0,0 +1 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/OpenAuth.Identity/Views/_ViewStart.cshtml b/OpenAuth.Identity/Views/_ViewStart.cshtml new file mode 100644 index 0000000..a5f1004 --- /dev/null +++ b/OpenAuth.Identity/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/OpenAuth.Identity/appsettings.Development.json b/OpenAuth.Identity/appsettings.Development.json new file mode 100644 index 0000000..e203e94 --- /dev/null +++ b/OpenAuth.Identity/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/OpenAuth.Identity/appsettings.Production.json b/OpenAuth.Identity/appsettings.Production.json new file mode 100644 index 0000000..b28e46b --- /dev/null +++ b/OpenAuth.Identity/appsettings.Production.json @@ -0,0 +1,16 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "OpenAuthDBContext": "server=127.0.0.1;user id=root;database=openauthdb;password=000000" //my sql + }, + "AppSetting": { + "DbTypes": { + "OpenAuthDBContext":"MySql" //数据库类型:SqlServer、MySql、Oracle + } + } +} diff --git a/OpenAuth.Identity/appsettings.json b/OpenAuth.Identity/appsettings.json new file mode 100644 index 0000000..681c672 --- /dev/null +++ b/OpenAuth.Identity/appsettings.json @@ -0,0 +1,11 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "OpenAuthDBContext": "" + } +} diff --git a/OpenAuth.Identity/tempkey.jwk b/OpenAuth.Identity/tempkey.jwk new file mode 100644 index 0000000..326af7c --- /dev/null +++ b/OpenAuth.Identity/tempkey.jwk @@ -0,0 +1 @@ +{"AdditionalData":{},"Alg":"RS256","Crv":null,"D":"FZBC8mpgLd9n9VG6MQfc1XLbCOgWRzGEuVdXr1lDrjO9Yb8mj09FhssAJ-J6K0Pm-UgTQUmtNzvmZSCz_2rToPDaj64GbhXBSA7SxDjwAxDZuE-7T3v9delijy3eksEmSZLN51Ymmt3Ta0QKF-lINBMD6HyGSQsceYeKED66N2DQ_5IzwReAH9J529pzVfvHceQFTwdfTGs_lxRoJZiitaeKS3C0Fekondwq8jvJdpRCdTqZq9azXSLhSnynB3AQ94pnm8nHmZA1WitwPcL2uh2655tmMYd8QT7nWJOUVkpwcI2E32peko_RwhkHQDMy4fFluZW0s2AFPWYMN-LhHQ","DP":"V-7TrHWriNm9mdFc0ziyeCFhdB_dFEJPNAlJis5XJbshufjH3DfnOmhSP_vyo2k_ynaJp0pKNoIX0bvaVTBN2yHyrbyJA9Wl_KNIPYvUoWDS8eBPJ-ROS7rE4La2fnkJRMiD5SOwNFgcXpURdORiyCF6xAAefhCvlr8ww9WORkE","DQ":"V7B-gNOY4YG6LjLf32De5GyUUtRTzBgkwnw7StLtGDyMhfXrs3kzqSS7DumpJIeLWiuU0Yw8vV5a9dUTYbjrrFon-mEReK4ZAKjPy3DRQIQXsvSrIXlPRn6_hxzNpjR6iw4lsrhfE5L1Z6IrVdWyHSBvk0DdgfH7k1dGFWfl0Ak","E":"AQAB","K":null,"KeyId":"58F23E7865126BE9B4F964EC9719EC4D","Kid":"58F23E7865126BE9B4F964EC9719EC4D","Kty":"RSA","N":"okUXzORMUQAGQMbuHuzNGONpufShLixiQ1D0SrDerg823XoG82J30L-fq2uOtF57bztOJGsSKdUSlBCcnpSInt02EqdRogAoYhB8QOUrW4gXjNCTL78BnSP2ulE9e6f2rHZjH6juPvn7gVnXX_S3Oo-fc9uhv1BDZFM7_RVxQvf98759T3GM-Qj0NZR467YsdqqGrdq98hnXTD8EFHAjMEZKrOmkkGT4lINLmylf91cENNzJ-gf9QjtO3j3t2TRbtnktPpc2Wbw9f8sZoAefJG026sENZNttJL72h149U12d4GG8WRKtPZWPHKhHyc9Gq2XWdEKE8ohE12EHZlsIVQ","Oth":null,"P":"xa7j24z_JNvObtlrYtLOsKYFPz0hVfvQtJ-XpAnaPWuxOLc8Ch1BWucZ7QQZARaCR9qFdesT9W4ALJKDGapRl-JVkJKbHuY7vBO2qef-Jh_uvdnKrh2zbNSW3NXFdHl22RiGKWADBWmGhaIApkTGOM0pozjJL-esCxbT6HNfga8","Q":"0iPHZecnU2kjTvC-FVmCw6LsQweWkETBAes8T_ZWv5NPJCfa8bSBk2sD0N2XER43NR9BdiTA2SAXjbkrKTDDpz0ve69iFJb8uxV1kwuwVUVibfl3igUsl9oDkxSZ2GembmOuYbWBLc_uk194h7RKA7F86HPIKS7Rgf4Q99scazs","QI":"n4-4jQ9GnBZvNSJ4ls0u74IShfsJkG63VaZgypTnhItPHGDIzwCI_VdASKN55RXMWSr0lfDVjNDBKgqdgFJczsxaaDm8fUiA0e7Mso6DznpmYqvtJ-cL7xAKIY9aJrb_3YqQILAtTjcZh9aYr-dDY4qgnQmmQ3GpL7tCU0t8zb8","Use":null,"X":null,"X5t":null,"X5tS256":null,"X5u":null,"Y":null,"KeySize":2048,"HasPrivateKey":true,"CryptoProviderFactory":{"CryptoProviderCache":{},"CustomCryptoProvider":null,"CacheSignatureProviders":true,"SignatureProviderObjectPoolCacheSize":48}} \ No newline at end of file diff --git a/OpenAuth.Identity/tempkey.rsa b/OpenAuth.Identity/tempkey.rsa new file mode 100644 index 0000000..7b7bf59 --- /dev/null +++ b/OpenAuth.Identity/tempkey.rsa @@ -0,0 +1 @@ +{"KeyId":"a33ecf9fadd0a1cd0aa7fbe05ab80eed","Parameters":{"D":"KqUVQKufCYXPJPp6/wCKYMX0044mHb/N+ZKjCQh7F5GQOvGpSEINAiPBuCEroyORDdT4jMwfTJYb4OPH9hOddBxLBZuKCNVZVlv4kxauiKMnUkEneIwOJL5thw5seAR1qnGxKZMby/1NlpqriY7ahYC5zHdlRm387xOz1/AtrjKilh5wYnSZOayq3lvjY8MRjf9v/89jnFNqM3i34ruUk5wOZgXwe6cNAaOG4xYJJ79+2x0hhqzwaDrpTfPQmmogDKf511OrcO1A6QokLN/qjdAYMFt0HLI6DN9GDePYjB8zUoXigtjO8Th4zHyUW2O2rHpsqExBALw1OGPaIeD97Q==","DP":"N6eDU4ySwI7VEFPUTwuWnRPxWoJWkzuTy19alD/2+c7wlcaYiIi26qZLdwL3j95xH645WxlKOMWFkU8HedQSUtCpNCEcKu7ejS/Gir/65V0fs3SxF1JT56RGF8E4Ma+vsIRRzKBsVtIuNca3mgDpdI1gxmuCradee2Z4fhKe3bU=","DQ":"26nTIdNfj7Ps68BSE74LynW4JdsUQorHMTGXgJfTSVth/hBkBbjF98Tjta2iG1EMRAJHveJ29lCQzxVYhxsrd1obyuD3mTX+n+k0ciHYAdGzPQKIel/iP8OYrsDvTgioAuS0Jy7WowT9TK7zC/yb/MbaqvQls1KcjF2jjSstpes=","Exponent":"AQAB","InverseQ":"ge27mwfvTlhFmMs1lMRG+WpFPrNHQtZFNPFoajJ9qL12VRaT0vodqW4M9MRp6Vs+Xvy+3pNzWkJRVZQq0HTN0oXIYgpSdG8stbt3g8orbTLsS8NFKWHnDsiKK1O1Dd9AsKoQmQbfPhRxECdWVQsCgTsedU6f24sJBIoBluF25BE=","Modulus":"+BjnkJNAxS78/tUd6trgJXV1Ltvh0Yw7NTa2qHlbD6wvR7IaXAWqJffzucyXFaOafs63tKiIXh1Tfhg+lQXIxXoJohyrz7exLqOkn4OvLGu3fjRDCF/2M2riDyJIGDNlt09e0NnrwQfUo1rhqr5k3N9T85LeETWA5i0EVRV3eanEbEOlNHtVPDEFm3LEKFm/FWxkchKnrjFz0t/2trsjo3gLDkslXKFkC/F9wPPldh5wCabVmr5pcKZpCPLnSzrRS35gF/g0+Fd9pZoflC+c798OsKFcsDDTKmtoRwU4FiX8I/z5H1pF2VHMEHpvU4akRD92TfmkKr+VdK+yiIZjxQ==","P":"/MQyAzEKfLXoWrT3tnrwFJ/sYv0A2Azl5wF9R1PmfBPphHA74KgIAe//88Q5PyhKDWaGW2BtUewr+fqMvEHtdXYwjYqz9q/NZ3hiZl+wDFkT6lz4ufwDKEZa+bUiAen0b8Ruk9sdwXSBJwLBq+rqEBaE1vPrlU68dOS2dMow5kc=","Q":"+0Vq//ZIhAadpc8riyD10/n9CkTiGecVc7WGsk6vfeDac2PaQvcDUDs/LeP7qT2Q9+2kra6jA7hOrPCxyP6PLukNOdqcmrdU+z2UJGZVLCZJ7RJJSt4H1fP26cJ/x1egkubVwImKiapYSpXWYLx9K8wTixZQHRAdzsK3qr1sD5M="}} \ No newline at end of file diff --git a/OpenAuth.Identity/wwwroot/css/site.css b/OpenAuth.Identity/wwwroot/css/site.css new file mode 100644 index 0000000..a0bbbed --- /dev/null +++ b/OpenAuth.Identity/wwwroot/css/site.css @@ -0,0 +1,82 @@ +body { + margin-top: 65px; +} +.navbar-header { + position: relative; + top: -4px; +} +.navbar-brand > .icon-banner { + position: relative; + top: -2px; + display: inline; +} +.icon { + position: relative; + top: -10px; +} +.logged-out iframe { + display: none; + width: 0; + height: 0; +} +.page-consent .client-logo { + float: left; +} +.page-consent .client-logo img { + width: 80px; + height: 80px; +} +.page-consent .consent-buttons { + margin-top: 25px; +} +.page-consent .consent-form .consent-scopecheck { + display: inline-block; + margin-right: 5px; +} +.page-consent .consent-form .consent-description { + margin-left: 25px; +} +.page-consent .consent-form .consent-description label { + font-weight: normal; +} +.page-consent .consent-form .consent-remember { + padding-left: 16px; +} +.grants .page-header { + margin-bottom: 10px; +} +.grants .grant { + margin-top: 20px; + padding-bottom: 20px; + border-bottom: 1px solid lightgray; +} +.grants .grant img { + width: 100px; + height: 100px; +} +.grants .grant .clientname { + font-size: 140%; + font-weight: bold; +} +.grants .grant .granttype { + font-size: 120%; + font-weight: bold; +} +.grants .grant .created { + font-size: 120%; + font-weight: bold; +} +.grants .grant .expires { + font-size: 120%; + font-weight: bold; +} +.grants .grant li { + list-style-type: none; + display: inline; +} +.grants .grant li:after { + content: ', '; +} +.grants .grant li:last-child:after { + content: ''; +} \ No newline at end of file diff --git a/OpenAuth.Identity/wwwroot/css/site.less b/OpenAuth.Identity/wwwroot/css/site.less new file mode 100644 index 0000000..09f5141 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/css/site.less @@ -0,0 +1,116 @@ +body { + margin-top: 65px; +} + +.navbar-header { + position: relative; + top: -4px; +} + +.navbar-brand > .icon-banner { + position: relative; + top: -2px; + display: inline; +} + +.icon { + position: relative; + top: -10px; +} + +.logged-out iframe { + display: none; + width: 0; + height: 0; +} + +.page-consent { + .client-logo { + float: left; + + img { + width: 80px; + height: 80px; + } + } + + .consent-buttons { + margin-top: 25px; + } + + .consent-form { + .consent-scopecheck { + display: inline-block; + margin-right: 5px; + } + + .consent-scopecheck[disabled] { + //visibility:hidden; + } + + .consent-description { + margin-left: 25px; + + label { + font-weight: normal; + } + } + + .consent-remember { + padding-left: 16px; + } + } +} + +.grants { + .page-header { + margin-bottom: 10px; + } + + .grant { + margin-top: 20px; + padding-bottom: 20px; + border-bottom: 1px solid lightgray; + + img { + width: 100px; + height: 100px; + } + + .clientname { + font-size: 140%; + font-weight: bold; + } + + .granttype { + font-size: 120%; + font-weight: bold; + } + + .created { + font-size: 120%; + font-weight: bold; + } + + .expires { + font-size: 120%; + font-weight: bold; + } + + li { + list-style-type: none; + display: inline; + + &:after { + content: ', '; + } + + &:last-child:after { + content: ''; + } + + .displayname { + } + } + } +} diff --git a/OpenAuth.Identity/wwwroot/css/site.min.css b/OpenAuth.Identity/wwwroot/css/site.min.css new file mode 100644 index 0000000..84ae0c4 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/css/site.min.css @@ -0,0 +1 @@ +body{margin-top:65px;}.navbar-header{position:relative;top:-4px;}.navbar-brand>.icon-banner{position:relative;top:-2px;display:inline;}.icon{position:relative;top:-10px;}.logged-out iframe{display:none;width:0;height:0;}.page-consent .client-logo{float:left;}.page-consent .client-logo img{width:80px;height:80px;}.page-consent .consent-buttons{margin-top:25px;}.page-consent .consent-form .consent-scopecheck{display:inline-block;margin-right:5px;}.page-consent .consent-form .consent-description{margin-left:25px;}.page-consent .consent-form .consent-description label{font-weight:normal;}.page-consent .consent-form .consent-remember{padding-left:16px;}.grants .page-header{margin-bottom:10px;}.grants .grant{margin-top:20px;padding-bottom:20px;border-bottom:1px solid #d3d3d3;}.grants .grant img{width:100px;height:100px;}.grants .grant .clientname{font-size:140%;font-weight:bold;}.grants .grant .granttype{font-size:120%;font-weight:bold;}.grants .grant .created{font-size:120%;font-weight:bold;}.grants .grant .expires{font-size:120%;font-weight:bold;}.grants .grant li{list-style-type:none;display:inline;}.grants .grant li:after{content:', ';}.grants .grant li:last-child:after{content:'';} \ No newline at end of file diff --git a/OpenAuth.Identity/wwwroot/favicon.ico b/OpenAuth.Identity/wwwroot/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ee470e42facff8210727fb7caca55407becc0135 GIT binary patch literal 1150 zcmZuwTS!z<6g@hck8yM!&Zsl@&OLKS$1=k5M+Y>f(jbcrA}oV`>cgK33H&H}Kv5(Z zN?N|n2$JeUixi;;r6mj%rB)CVRD?uSls_Xy?$%Z>X?ccq_ugx-bV(Vh-K0jAfHK4LS;MUkI;{y8Cq>Dr=dFzQ>w!tkQ3dZ1P|rQYw^H$vw5E8tR&G+4dLc?m z^I|{uc2@3gaHePSd%pq-m_sD#un%$0!_`UMT1%AFOSEWx?yV1%ZqR)>{B7O<7UmFt zOSk(Q=R9)ysN2&tP452x{Wfd5$DO4beuee$*Yf{2$A}TG_dlkFxE3O%?N>F|etU99 zXkF<*Z|}7&M-Cswnx-*$`2EYd&jWd*%jKpLnKrz=b?kE74WhEfXJ>=D^RC10B1ovI zsd?|g12r-sK6xDa0ibQxJpWK^md&dy;!I)vSYJ{f(YB^=Pq8Oq+?k$rD-g&##wB6I?{Pz) m)CkcK#5)uTp%)7gn1?Qf;LB5l6}{+nK{L8Wh<7K2VDBGM+S%6t literal 0 HcmV?d00001 diff --git a/OpenAuth.Identity/wwwroot/icon.jpg b/OpenAuth.Identity/wwwroot/icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e6525028aca7ed7a339915a3986c38034e31ab1c GIT binary patch literal 19482 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 literal 0 HcmV?d00001 diff --git a/OpenAuth.Identity/wwwroot/icon.png b/OpenAuth.Identity/wwwroot/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd386d5170151f6fb166bf1eab2486b1ffb3a421 GIT binary patch literal 20796 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 .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} + +.radio.inline, +.checkbox.inline, +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} + +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline, +.radio-inline .checkbox-inline { + margin-left: 10px; +} + +.input-mini { + width: 60px; +} + +.input-small { + width: 90px; +} + +.input-medium { + width: 150px; +} + +.input-large { + width: 210px; +} + +.input-xlarge { + width: 270px; +} + +.input-xxlarge { + width: 530px; +} + +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} + +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +input, +textarea, +.uneditable-input { + margin-left: 0; +} + +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} + +input.span12, +textarea.span12 { + float: none; + width: 926px; + margin-left: 0; +} + +.uneditable-input-span12 { + width: 926px; +} + +input.span11, +textarea.span11 { + float: none; + width: 846px; + margin-left: 0; +} + +.uneditable-input-span11 { + width: 846px; +} + +input.span10, +textarea.span10 { + float: none; + width: 766px; + margin-left: 0; +} + +.uneditable-input-span10 { + width: 766px; +} + +input.span9, +textarea.span9 { + float: none; + width: 686px; + margin-left: 0; +} + +.uneditable-input-span9 { + width: 686px; +} + +input.span8, +textarea.span8 { + float: none; + width: 606px; + margin-left: 0; +} + +.uneditable-input-span8 { + width: 606px; +} + +input.span7, +textarea.span7 { + float: none; + width: 526px; + margin-left: 0; +} + +.uneditable-input-span7 { + width: 526px; +} + +input.span6, +textarea.span6 { + float: none; + width: 446px; + margin-left: 0; +} + +.uneditable-input-span6 { + width: 446px; +} + +input.span5, +textarea.span5 { + float: none; + width: 366px; + margin-left: 0; +} + +.uneditable-input-span5 { + width: 366px; +} + +input.span4, +textarea.span4 { + float: none; + width: 286px; + margin-left: 0; +} + +.uneditable-input-span4 { + width: 286px; +} + +input.span3, +textarea.span3 { + float: none; + width: 206px; + margin-left: 0; +} + +.uneditable-input-span3 { + width: 206px; +} + +input.span2, +textarea.span2 { + float: none; + width: 126px; + margin-left: 0; +} + +.uneditable-input-span2 { + width: 126px; +} + +input.span1, +textarea.span1 { + float: none; + width: 46px; + margin-left: 0; +} + +.uneditable-input-span1 { + width: 46px; +} + +.controls-row { + *zoom: 1; +} + +.controls-row:before, +.controls-row:after { + display: table; + line-height: 0; + content: ""; +} + +.controls-row:after { + clear: both; +} + +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} + +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + +.input-disabled, +.select-disabled, +.textarea-disabled, +.input-readonly, +.select-readonly, +.textarea-readonly { + cursor: not-allowed; + background-color: #eeeeee; +} + +.radio-disabled, +.checkbox-disabled, +.radio-readonly, +.checkbox-readonly { + background-color: transparent; +} + +.control-group-warning label, +.control-group-warning .help-block, +.control-group-warning .help-inline { + color: #c09853; +} + +.control-group-warning * label { + color: inherit; +} + +.control-group-warning .checkbox, +.control-group-warning .radio, +.control-group-warning input, +.control-group-warning select, +.control-group-warning textarea { + color: #c09853; +} + +.control-group-warning input, +.control-group-warning select, +.control-group-warning textarea { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group-warning input:focus, +.control-group-warning select:focus, +.control-group-warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.control-group-warning .input-prepend .add-on, +.control-group-warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.control-group-error label, +.control-group-error .help-block, +.control-group-error .help-inline { + color: #b94a48; +} + +.control-group-error * label { + color: inherit; +} + +.control-group-error .checkbox, +.control-group-error .radio, +.control-group-error input, +.control-group-error select, +.control-group-error textarea { + color: #b94a48; +} + +.control-group-error input, +.control-group-error select, +.control-group-error textarea { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group-error input:focus, +.control-group-error select:focus, +.control-group-error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.control-group-error .input-prepend .add-on, +.control-group-error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.control-group-success label, +.control-group-success .help-block, +.control-group-success .help-inline { + color: #468847; +} + +.control-group-success * label { + color: inherit; +} + +.control-group-success .checkbox, +.control-group-success .radio, +.control-group-success input, +.control-group-success select, +.control-group-success textarea { + color: #468847; +} + +.control-group-success input, +.control-group-success select, +.control-group-success textarea { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group-success input:focus, +.control-group-success select:focus, +.control-group-success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.control-group-success .input-prepend .add-on, +.control-group-success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.control-group-info label, +.control-group-info .help-block, +.control-group-info .help-inline { + color: #3a87ad; +} + +.control-group-info * label { + color: inherit; +} + +.control-group-info .checkbox, +.control-group-info .radio, +.control-group-info input, +.control-group-info select, +.control-group-info textarea { + color: #3a87ad; +} + +.control-group-info input, +.control-group-info select, +.control-group-info textarea { + border-color: #3a87ad; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group-info input:focus, +.control-group-info select:focus, +.control-group-info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} + +.control-group-info .input-prepend .add-on, +.control-group-info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} + +input:focus:required:invalid, +textarea:focus:required:invalid, +select:focus:required:invalid { + color: #b94a48; + border-color: #ee5f5b; +} + +input:focus:required:invalid:focus, +textarea:focus:required:invalid:focus, +select:focus:required:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} + +.form-actions { + padding: 19px 20px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} + +.form-actions:before, +.form-actions:after { + display: table; + line-height: 0; + content: ""; +} + +.form-actions:after { + clear: both; +} + +.help-block, +.help-inline { + color: #595959; +} + +.help-block { + display: block; + margin-bottom: 10px; +} + +.help-inline { + display: inline-block; + *display: inline; + padding-left: 5px; + vertical-align: middle; + *zoom: 1; +} + +.input-append, +.input-prepend { + margin-bottom: 5px; + font-size: 0; + white-space: nowrap; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu { + font-size: 14px; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} + +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} + +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn { + *margin-top: 1px; + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} + +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; + *margin-right: -2px; +} + +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input + .btn-group .btn, +.input-append select + .btn-group .btn, +.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; + *margin-left: -2px; +} + +.input-append .add-on:last-child, +.input-append .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} + +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +/* Allow for input prepend/append in search forms */ + +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + margin-bottom: 0; + vertical-align: middle; + *zoom: 1; +} + +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} + +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} + +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} + +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} + +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + +.control-group { + margin-bottom: 10px; +} + +legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; +} + +.form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; +} + +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + line-height: 0; + content: ""; +} + +.form-horizontal .control-group:after { + clear: both; +} + +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} + +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} + +.form-horizontal .controls-first-child { + *padding-left: 180px; +} + +.form-horizontal .help-block { + margin-bottom: 0; +} + +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block { + margin-top: 10px; +} + +.form-horizontal .form-actions { + padding-left: 180px; +} + +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table th { + font-weight: bold; +} + +.table thead th { + vertical-align: bottom; +} + +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} + +.table tbody + tbody { + border-top: 2px solid #dddddd; +} + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} + +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} + +.table-bordered thead:first-child tr:first-child th:first-child, +.table-bordered tbody:first-child tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered thead:first-child tr:first-child th:last-child, +.table-bordered tbody:first-child tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-bordered thead:last-child tr:last-child th:first-child, +.table-bordered tbody:last-child tr:last-child td:first-child, +.table-bordered tfoot:last-child tr:last-child td:first-child { + -webkit-border-radius: 0 0 0 4px; + -moz-border-radius: 0 0 0 4px; + border-radius: 0 0 0 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.table-bordered thead:last-child tr:last-child th:last-child, +.table-bordered tbody:last-child tr:last-child td:last-child, +.table-bordered tfoot:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-striped tbody tr:nth-child(odd) td, +.table-striped tbody tr:nth-child(odd) th { + background-color: #f9f9f9; +} + +.table-hover tbody .tr-hover td, +.table-hover tbody .tr-hover th { + background-color: #f5f5f5; +} + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} + +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} + +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} + +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} + +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} + +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} + +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} + +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} + +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} + +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} + +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} + +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} + +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} + +.table tbody tr.success td { + background-color: #dff0d8; +} + +.table tbody tr.error td { + background-color: #f2dede; +} + +.table tbody tr.warning td { + background-color: #fcf8e3; +} + +.table tbody tr.info td { + background-color: #d9edf7; +} + +.table-hover tbody tr.success:hover td { + background-color: #d0e9c6; +} + +.table-hover tbody tr.error:hover td { + background-color: #ebcccc; +} + +.table-hover tbody tr.warning:hover td { + background-color: #faf2cc; +} + +.table-hover tbody tr.info:hover td { + background-color: #c4e3f3; +} + +.icon-xxx { + display: inline-block; + _display: inline; + width: 14px; + _width: 14px; + height: 14px; + _height: 19px; + margin-top: 1px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + _vertical-align: middle; + background-image: url("../img/glyphicons-halflings.png"); + _background-image: url("../img/glyphicons-halflings-8.png"); + background-position: 14px 14px; + background-repeat: no-repeat; + _zoom: 1; +} + +/* White icons with optional class, or on hover/active states of certain elements */ + +.icon-white { + background-image: url("../img/glyphicons-halflings-white.png"); +} + +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"] { + background-image: url("../img/glyphicons-halflings-white.png"); +} + +.icon-glass { + background-position: 0 0; +} + +.icon-music { + background-position: -24px 0; +} + +.icon-search { + background-position: -48px 0; +} + +.icon-envelope { + background-position: -72px 0; +} + +.icon-heart { + background-position: -96px 0; +} + +.icon-star { + background-position: -120px 0; +} + +.icon-star-empty { + background-position: -144px 0; +} + +.icon-user { + background-position: -168px 0; +} + +.icon-film { + background-position: -192px 0; +} + +.icon-th-large { + background-position: -216px 0; +} + +.icon-th { + background-position: -240px 0; +} + +.icon-th-list { + background-position: -264px 0; +} + +.icon-ok { + background-position: -288px 0; +} + +.icon-remove { + background-position: -312px 0; +} + +.icon-zoom-in { + background-position: -336px 0; +} + +.icon-zoom-out { + background-position: -360px 0; +} + +.icon-off { + background-position: -384px 0; +} + +.icon-signal { + background-position: -408px 0; +} + +.icon-cog { + background-position: -432px 0; +} + +.icon-trash { + background-position: -456px 0; +} + +.icon-home { + background-position: 0 -24px; +} + +.icon-file { + background-position: -24px -24px; +} + +.icon-time { + background-position: -48px -24px; +} + +.icon-road { + background-position: -72px -24px; +} + +.icon-download-alt { + background-position: -96px -24px; +} + +.icon-download { + background-position: -120px -24px; +} + +.icon-upload { + background-position: -144px -24px; +} + +.icon-inbox { + background-position: -168px -24px; +} + +.icon-play-circle { + background-position: -192px -24px; +} + +.icon-repeat { + background-position: -216px -24px; +} + +.icon-refresh { + background-position: -240px -24px; +} + +.icon-list-alt { + background-position: -264px -24px; +} + +.icon-lock { + background-position: -287px -24px; +} + +.icon-flag { + background-position: -312px -24px; +} + +.icon-headphones { + background-position: -336px -24px; +} + +.icon-volume-off { + background-position: -360px -24px; +} + +.icon-volume-down { + background-position: -384px -24px; +} + +.icon-volume-up { + background-position: -408px -24px; +} + +.icon-qrcode { + background-position: -432px -24px; +} + +.icon-barcode { + background-position: -456px -24px; +} + +.icon-tag { + background-position: 0 -48px; +} + +.icon-tags { + background-position: -25px -48px; +} + +.icon-book { + background-position: -48px -48px; +} + +.icon-bookmark { + background-position: -72px -48px; +} + +.icon-print { + background-position: -96px -48px; +} + +.icon-camera { + background-position: -120px -48px; +} + +.icon-font { + background-position: -144px -48px; +} + +.icon-bold { + background-position: -167px -48px; +} + +.icon-italic { + background-position: -192px -48px; +} + +.icon-text-height { + background-position: -216px -48px; +} + +.icon-text-width { + background-position: -240px -48px; +} + +.icon-align-left { + background-position: -264px -48px; +} + +.icon-align-center { + background-position: -288px -48px; +} + +.icon-align-right { + background-position: -312px -48px; +} + +.icon-align-justify { + background-position: -336px -48px; +} + +.icon-list { + background-position: -360px -48px; +} + +.icon-indent-left { + background-position: -384px -48px; +} + +.icon-indent-right { + background-position: -408px -48px; +} + +.icon-facetime-video { + background-position: -432px -48px; +} + +.icon-picture { + background-position: -456px -48px; +} + +.icon-pencil { + background-position: 0 -72px; +} + +.icon-map-marker { + background-position: -24px -72px; +} + +.icon-adjust { + background-position: -48px -72px; +} + +.icon-tint { + background-position: -72px -72px; +} + +.icon-edit { + background-position: -96px -72px; +} + +.icon-share { + background-position: -120px -72px; +} + +.icon-check { + background-position: -144px -72px; +} + +.icon-move { + background-position: -168px -72px; +} + +.icon-step-backward { + background-position: -192px -72px; +} + +.icon-fast-backward { + background-position: -216px -72px; +} + +.icon-backward { + background-position: -240px -72px; +} + +.icon-play { + background-position: -264px -72px; +} + +.icon-pause { + background-position: -288px -72px; +} + +.icon-stop { + background-position: -312px -72px; +} + +.icon-forward { + background-position: -336px -72px; +} + +.icon-fast-forward { + background-position: -360px -72px; +} + +.icon-step-forward { + background-position: -384px -72px; +} + +.icon-eject { + background-position: -408px -72px; +} + +.icon-chevron-left { + background-position: -432px -72px; +} + +.icon-chevron-right { + background-position: -456px -72px; +} + +.icon-plus-sign { + background-position: 0 -96px; +} + +.icon-minus-sign { + background-position: -24px -96px; +} + +.icon-remove-sign { + background-position: -48px -96px; +} + +.icon-ok-sign { + background-position: -72px -96px; +} + +.icon-question-sign { + background-position: -96px -96px; +} + +.icon-info-sign { + background-position: -120px -96px; +} + +.icon-screenshot { + background-position: -144px -96px; +} + +.icon-remove-circle { + background-position: -168px -96px; +} + +.icon-ok-circle { + background-position: -192px -96px; +} + +.icon-ban-circle { + background-position: -216px -96px; +} + +.icon-arrow-left { + background-position: -240px -96px; +} + +.icon-arrow-right { + background-position: -264px -96px; +} + +.icon-arrow-up { + background-position: -289px -96px; +} + +.icon-arrow-down { + background-position: -312px -96px; +} + +.icon-share-alt { + background-position: -336px -96px; +} + +.icon-resize-full { + background-position: -360px -96px; +} + +.icon-resize-small { + background-position: -384px -96px; +} + +.icon-plus { + background-position: -408px -96px; +} + +.icon-minus { + background-position: -433px -96px; +} + +.icon-asterisk { + background-position: -456px -96px; +} + +.icon-exclamation-sign { + background-position: 0 -120px; +} + +.icon-gift { + background-position: -24px -120px; +} + +.icon-leaf { + background-position: -48px -120px; +} + +.icon-fire { + background-position: -72px -120px; +} + +.icon-eye-open { + background-position: -96px -120px; +} + +.icon-eye-close { + background-position: -120px -120px; +} + +.icon-warning-sign { + background-position: -144px -120px; +} + +.icon-plane { + background-position: -168px -120px; +} + +.icon-calendar { + background-position: -192px -120px; +} + +.icon-random { + width: 16px; + background-position: -216px -120px; +} + +.icon-comment { + background-position: -240px -120px; +} + +.icon-magnet { + background-position: -264px -120px; +} + +.icon-chevron-up { + background-position: -288px -120px; +} + +.icon-chevron-down { + background-position: -313px -119px; +} + +.icon-retweet { + background-position: -336px -120px; +} + +.icon-shopping-cart { + background-position: -360px -120px; +} + +.icon-folder-close { + background-position: -384px -120px; +} + +.icon-folder-open { + width: 16px; + background-position: -408px -120px; +} + +.icon-resize-vertical { + background-position: -432px -119px; +} + +.icon-resize-horizontal { + background-position: -456px -118px; +} + +.icon-hdd { + background-position: 0 -144px; +} + +.icon-bullhorn { + background-position: -24px -144px; +} + +.icon-bell { + background-position: -48px -144px; +} + +.icon-certificate { + background-position: -72px -144px; +} + +.icon-thumbs-up { + background-position: -96px -144px; +} + +.icon-thumbs-down { + background-position: -120px -144px; +} + +.icon-hand-right { + background-position: -144px -144px; +} + +.icon-hand-left { + background-position: -168px -144px; +} + +.icon-hand-up { + background-position: -192px -144px; +} + +.icon-hand-down { + background-position: -216px -144px; +} + +.icon-circle-arrow-right { + background-position: -240px -144px; +} + +.icon-circle-arrow-left { + background-position: -264px -144px; +} + +.icon-circle-arrow-up { + background-position: -288px -144px; +} + +.icon-circle-arrow-down { + background-position: -312px -144px; +} + +.icon-globe { + background-position: -336px -144px; +} + +.icon-wrench { + background-position: -360px -144px; +} + +.icon-tasks { + background-position: -384px -144px; +} + +.icon-filter { + background-position: -408px -144px; +} + +.icon-briefcase { + background-position: -432px -144px; +} + +.icon-fullscreen { + background-position: -456px -144px; +} + +.dropup, +.dropdown { + position: relative; + /* fix for IE6 BFC */ + + display: inline; + *zoom: 1; +} + +.dropdown-toggle { + *margin-bottom: -3px; +} + +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} + +.caret { + display: inline-block; + *display: inline; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; + *zoom: 1; +} + +/* fix for IE6 */ + +.caret { + width: 0; + height: 0; + line-height: 0; + border-color: #000000 transparent transparent; + *border-color: #000000 #fffffe #fffffe; + border-style: solid; + border-width: 4px 4px 0; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + *width: auto !important; + *width: 160px; + *height: 1px; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.dropdown-menu li a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; + *zoom: 1; +} + +.dropdown-menu li a:hover, +.dropdown-menu li a:focus, +.dropdown-submenu:hover a, +.dropdown-submenu-hover a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +/* fix for IE6 li:hover */ + +.dropdown-submenu-hover * a { + *color: inherit; + *background-color: #fffffe; + *background-image: none; + *filter: none; + *filter: chroma(color=#fffffe); +} + +.dropdown-menu .active a, +.dropdown-menu .active a:hover { + color: #333333; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + outline: 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu .disabled a, +.dropdown-menu .disabled a:hover { + color: #999999; +} + +.dropdown-menu .disabled a:hover { + text-decoration: none; + cursor: default; + background-color: transparent; + *background-color: #fffffe; + background-image: none; + *filter: chroma(color=#fffffe); +} + +.open { + *z-index: 1000; +} + +.open .dropdown-menu { + display: block; + /* fix for IE6 inline-block */ + + *zoom: 1; +} + +.pull-right .dropdown-menu { + right: 0; + left: auto; +} + +.pull-right * .dropdown-menu { + right: auto; + left: 0; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +.dropdown-submenu { + position: relative; + /* fix for IE6 absolute element will expand parent element's height */ + + *display: inline; + *zoom: 1; +} + +.dropdown-submenu .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover .dropdown-menu, +.dropdown-submenu-hover .dropdown-menu { + display: block; +} + +.dropup .dropdown-submenu .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} + +.dropdown-submenu a:after { + display: block; + float: right; + width: 0; + height: 0; + margin-top: 5px; + margin-right: -10px; + border-color: transparent; + *border-color: #fffffe; + border-left-color: #cccccc; + border-style: solid; + border-width: 5px 0 5px 5px; + content: " "; + *filter: chroma(color=#fffffe); + *zoom: 1; +} + +/* fix for IE6 */ + +.dropdown-submenu .dropdown-tri { + display: block; + float: right; + width: 0; + height: 0; + margin: -1.3em 5px 0 0; + line-height: 0; + border-color: transparent transparent transparent #cccccc; + _border-color: #fffffe #fffffe #fffffe #cccccc; + border-style: solid; + border-width: 5px 0 5px 5px; + _filter: chroma(color=#fffffe); + zoom: 1; +} + +.dropdown-submenu:hover a:after, +.dropdown-submenu-hover .dropdown-tri { + border-left-color: #ffffff; +} + +.dropdown-submenu-pull-left { + float: none; + /* fix for IE6 */ + +} + +.dropdown-submenu-pull-left .dropdown-menu { + left: -100%; + margin-left: 10px; + *margin-left: 18px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.dropdown-submenu-pull-left * .dropdown-menu { + left: 0; + margin-left: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.dropdown .dropdown-menu .nav-header { + padding-right: 20px; + padding-left: 20px; +} + +.typeahead { + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.btn { + display: inline-block; + *display: inline; + padding: 4px 12px; + _padding-top: 3px; + _padding-bottom: 3px; + margin-bottom: 0; + *margin-left: .3em; + font-size: 14px; + line-height: 20px; + *line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + *background-color: #e6e6e6; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + border: 1px solid #bbbbbb; + *border: 0; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border-bottom-color: #a2a2a2; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn:hover, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} + +.btn:active, +.btn.active { + background-color: #cccccc \9; +} + +.btn:first-child { + *margin-left: 0; +} + +.btn.btn-hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + *background-color: #d9d9d9; + /* Buttons in IE7 don't get borders, so darken on hover */ + + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn:active, +.btn.active { + background-color: #e6e6e6; + background-color: #d9d9d9 \9; + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn.disabled, +.btn[disabled], +.btn-disabled { + cursor: default; + background-color: #e6e6e6; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} + +.btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} + +.btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} + +a.btn { + *padding-top: 5px; + *padding-bottom: 5px; +} + +a.btn.btn-large { + *padding-top: 13px; + *padding-bottom: 15px; +} + +a.btn.btn-small { + *padding-top: 4px; + *padding-bottom: 4px; +} + +a.btn.btn-mini { + *padding-top: 3px; + *padding-bottom: 3px; +} + +.btn-large { + padding: 11px 19px; + font-size: 17.5px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 2px; +} + +.btn-small { + padding: 2px 10px; + font-size: 11.9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} + +.btn-mini { + padding: 1px 6px; + font-size: 10.5px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn { + border-color: #c5c5c5; + border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); +} + +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + *background-color: #0044cc; + background-image: -moz-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(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + 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(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} + +.btn-primary.btn-primary-hover { + color: #fff; + background-color: #0044cc; + *background-color: #003bb3; +} + +a.btn-primary-hover:hover { + color: #fff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + *background-color: #f89406; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + border-color: #f89406 #f89406 #ad6704; + 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(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-warning:hover, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} + +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} + +.btn-warning.btn-warning-hover { + color: #fff; + background-color: #f89406; + *background-color: #df8505; +} + +a.btn-warning-hover:hover { + color: #fff; + background-color: #f89406; + *background-color: #df8505; +} + +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + *background-color: #bd362f; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + border-color: #bd362f #bd362f #802420; + 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(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-danger:hover, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} + +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} + +.btn-danger.btn-danger-hover { + color: #fff; + background-color: #bd362f; + *background-color: #a9302a; +} + +a.btn-danger-hover:hover { + color: #fff; + background-color: #bd362f; + *background-color: #a9302a; +} + +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + *background-color: #51a351; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + border-color: #51a351 #51a351 #387038; + 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(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-success:hover, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} + +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} + +.btn-success.btn-success-hover { + color: #fff; + background-color: #51a351; + *background-color: #499249; +} + +a.btn-success-hover:hover { + color: #fff; + background-color: #51a351; + *background-color: #499249; +} + +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + *background-color: #2f96b4; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + border-color: #2f96b4 #2f96b4 #1f6377; + 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(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-info:hover, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} + +.btn-info.btn-info-hover { + color: #fff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +a.btn-info-hover:hover { + color: #fff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + *background-color: #222222; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + border-color: #222222 #222222 #000000; + 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(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-inverse:hover, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} + +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} + +.btn-inverse.btn-inverse-hover { + color: #fff; + background-color: #222222; + *background-color: #3c3c3c; +} + +a.btn-inverse-hover:hover { + color: #fff; + background-color: #222222; + *background-color: #3c3c3c; +} + +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} + +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} + +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-link { + color: #0088cc; + cursor: pointer; + border-color: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-link:hover { + color: #005580; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover { + color: #333333; + text-decoration: none; +} + +.btn-disabled { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + filter: alpha(opacity=35); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *margin-left: .3em; + font-size: 0; + white-space: nowrap; + vertical-align: middle; + *zoom: 1; +} + +.btn-group:first-child { + *margin-left: 0; +} + +.btn-group { + margin-left: 5px; +} + +.btn-group-first { + /* fix for IE6 */ + + margin-left: 0; +} + +.btn-toolbar { + margin-top: 10px; + margin-bottom: 10px; + font-size: 0; +} + +.btn-toolbar .btn .btn-group { + margin-left: 5px; +} + +.btn-toolbar .btn-first, +.btn-toolbar .btn-group-first { + margin-left: 0; +} + +.btn-group .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group .btn { + margin-left: -1px; +} + +.btn-group .btn-first { + margin-left: 0; +} + +.btn-group .btn, +.btn-group .dropdown-menu { + font-size: 14px; +} + +.btn-group .dropdown-menu .divider { + _margin: 5px 0 -5px; +} + +.btn-group .btn-mini { + font-size: 11px; +} + +.btn-group .btn-small { + font-size: 12px; +} + +.btn-group .btn-large { + font-size: 16px; +} + +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group .dropdown-toggle { + padding-right: 9px; + padding-left: 9px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group .btn-mini-dropdown-toggle { + padding-right: 7px; + padding-left: 7px; +} + +.btn-group .btn-large-dropdown-toggle { + padding-right: 17px; + padding-left: 17px; +} + +.btn-group-open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group-open .btn-dropdown-toggle { + background-color: #e6e6e6; +} + +.btn-group-open .btn-primary-dropdown-toggle { + background-color: #0044cc; +} + +.btn-group-open .btn-warning-dropdown-toggle { + background-color: #f89406; +} + +.btn-group-open .btn-danger-dropdown-toggle { + background-color: #bd362f; +} + +.btn-group-open .btn-success-dropdown-toggle { + background-color: #51a351; +} + +.btn-group-open .btn-info-dropdown-toggle { + background-color: #2f96b4; +} + +.btn-group-open .btn-inverse-dropdown-toggle { + background-color: #222222; +} + +.btn .caret { + _display: inline; + _height: 8px; + margin-top: 8px; + margin-left: 0; + _vertical-align: middle; + _zoom: 1; +} + +.btn-mini .caret, +.btn-small .caret { + _height: 10px; +} + +.btn-mini .caret, +.btn-small .caret, +.btn-large .caret { + margin-top: 6px; +} + +.btn-large .caret { + _height: 9px; + border-top-width: 5px; + border-right-width: 5px; + border-left-width: 5px; +} + +.dropup .btn-large .caret { + border-bottom-width: 5px; +} + +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} + +.btn-group-vertical .btn { + display: block; + float: none; + width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group-vertical .btn + .btn { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.btn-group-vertical .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.btn-group-vertical .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} + +.btn-group-vertical .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 20px; + color: #c09853; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.alert h4 { + *display: inline; + margin: 0; + *zoom: 1; +} + +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 20px; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-danger, +.alert-error { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} + +.alert-block p, +.alert-block ul { + margin-bottom: 0; +} + +.alert-block p + p { + margin-top: 5px; +} + +.nav { + margin-bottom: 20px; + margin-left: 0; + list-style: none; +} + +.nav li a { + display: block; + *zoom: 1; +} + +.nav * li a { + display: inline; +} + +.nav li * a { + display: inline; +} + +.nav li a:hover { + text-decoration: none; + background-color: #eeeeee; +} + +.nav * li a:hover { + text-decoration: inherit; + background-color: inherit; +} + +.nav li * a:hover { + text-decoration: inherit; + background-color: inherit; +} + +.nav > .pull-right { + float: right; +} + +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; + *zoom: 1; +} + +.nav .nav-header { + margin-top: 9px; +} + +.nav-list { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 0; +} + +.nav-list li a, +.nav-list .nav-header { + margin-right: -15px; + margin-left: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} + +.nav-list li a { + padding: 3px 15px; +} + +.nav-list * li a { + padding: 0; + margin-right: 0; + margin-left: 0; + text-shadow: none; +} + +.nav-list li * a { + padding: 0; + margin-right: 0; + margin-left: 0; + text-shadow: none; +} + +.nav-list .active a, +.nav-list .active a:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} + +.nav-list * .active a, +.nav-list * .active a:hover { + color: inherit; + text-shadow: none; + background-color: inherit; +} + +.nav-list .active * a, +.nav-list .active * a:hover { + color: inherit; + text-shadow: none; + background-color: inherit; +} + +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} + +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.nav-tabs, +.nav-pills { + *zoom: 1; +} + +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + line-height: 0; + content: ""; +} + +.nav-tabs:after, +.nav-pills:after { + clear: both; +} + +.nav-tabs li, +.nav-pills li { + float: left; +} + +.nav-tabs * li, +.nav-pills * li { + float: none; +} + +.nav-tabs li a, +.nav-pills li a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} + +.nav-tabs * li a, +.nav-pills * li a { + padding: 0; + margin: 0; + line-height: auto; +} + +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +.nav-tabs li { + margin-bottom: -1px; + *background-color: #ffffff; + *zoom: 1; +} + +.nav-tabs * li { + zoom: normal; +} + +.nav-tabs li a { + *display: inline; + padding-top: 8px; + padding-bottom: 8px; + line-height: 20px; + *background-color: #fffffe; + border: 1px solid transparent; + *border: 1px solid #fffffe; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; + *filter: chroma(color=#fffffe); + *zoom: 1; +} + +.nav-tabs li a:hover { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs * li a { + padding: 0; + line-height: auto; + background-color: inherit; + border: none; + filter: none; + zoom: normal; +} + +.nav-tabs .active a, +.nav-tabs .active a:hover { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #ddd; + *border: 1px solid #999; + border-bottom-color: transparent; +} + +.nav-tabs * .active a, +.nav-tabs * .active a:hover { + color: inherit; + background-color: inherit; + border: none; +} + +.nav-pills li { + *background-color: #ffffff; + *zoom: 1; +} + +.nav-pills * li { + background-color: inherit; + zoom: normal; +} + +.nav-pills li a { + *display: inline; + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + *zoom: 1; +} + +.nav-pills * li a { + padding: 0; + margin: 0; + -webkit-border-radius: none; + -moz-border-radius: none; + border-radius: none; + zoom: normal; +} + +.nav-pills .active a, +.nav-pills .active a:hover { + color: #ffffff; + background-color: #0088cc; +} + +.nav-pills * .active a, +.nav-pills * .active a:hover { + color: inherit; + background-color: inherit; +} + +.nav-stacked > li { + float: none; +} + +.nav-stacked > li > a { + margin-right: 0; +} + +.nav-tabs.nav-stacked { + border-bottom: 0; +} + +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; +} + +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.nav-tabs.nav-stacked > li > a:hover { + z-index: 2; + border-color: #ddd; +} + +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} + +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} + +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + /* fix for IE6 li:hover */ + +} + +.nav-tabs .dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.nav-tabs .dropdown-menu li a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; + *zoom: 1; +} + +.nav-tabs .dropdown-menu li a:hover, +.nav-tabs .dropdown-menu li a:focus, +.nav-tabs .dropdown-menu .dropdown-submenu:hover a, +.nav-tabs .dropdown-menu .dropdown-submenu-hover a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.nav-tabs .dropdown-menu .dropdown-submenu-hover * a { + *color: inherit; + *background-color: #fffffe; + *background-image: none; + *filter: none; + *filter: chroma(color=#fffffe); +} + +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + /* fix for IE6 li:hover */ + +} + +.nav-pills .dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.nav-pills .dropdown-menu li a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; + *zoom: 1; +} + +.nav-pills .dropdown-menu li a:hover, +.nav-pills .dropdown-menu li a:focus, +.nav-pills .dropdown-menu .dropdown-submenu:hover a, +.nav-pills .dropdown-menu .dropdown-submenu-hover a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.nav-pills .dropdown-menu .dropdown-submenu-hover * a { + *color: inherit; + *background-color: #fffffe; + *background-image: none; + *filter: none; + *filter: chroma(color=#fffffe); +} + +.nav-tabs .dropdown-toggle { + *padding-top: 10px; + *padding-bottom: 12px; +} + +.nav-pills .dropdown-toggle { + *padding-top: 8px; + *padding-bottom: 6px; + *margin-bottom: 3px; +} + +.nav .dropdown-toggle .caret { + width: 0; + height: 0; + margin-top: 6px; + line-height: 0; + border-color: #0088cc transparent transparent; + *border-color: #0088cc #fffffe #fffffe; + border-top-color: #0088cc; + border-bottom-color: #0088cc; + border-style: solid; + border-width: 4px 4px 0; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.nav .dropdown-toggle:hover .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} + +/* move down carets for tabs */ + +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} + +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} + +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.nav .dropdown.active a:hover { + cursor: pointer; +} + +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav li.dropdown-open.active a:hover { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} + +.nav li.dropdown-open .caret, +.nav li.dropdown-open.active .caret, +.nav li.dropdown-open a:hover .caret { + width: 0; + height: 0; + line-height: 0; + border-color: #ffffff transparent transparent; + *border-color: #ffffff #fffffe #fffffe; + border-top-color: #ffffff; + border-bottom-color: #ffffff; + border-style: solid; + border-width: 4px 4px 0; + opacity: 1; + filter: alpha(opacity=100); + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.tabs-stacked .open > a:hover { + border-color: #999999; +} + +.tabbable { + *zoom: 1; +} + +.tabbable:before, +.tabbable:after { + display: table; + line-height: 0; + content: ""; +} + +.tabbable:after { + clear: both; +} + +.tab-content { + overflow: auto; +} + +.tabs-below .nav-tabs, +.tabs-right .nav-tabs, +.tabs-left .nav-tabs { + border-bottom: 0; +} + +.tab-content .tab-pane, +.pill-content .pill-pane { + display: none; + *background-color: #ffffff; + *zoom: 1; +} + +.tab-content .active, +.pill-content .active { + display: block; +} + +.tabs-below .nav-tabs { + border-top: 1px solid #ddd; +} + +.tabs-below * .nav-tabs { + border-top: none; +} + +.tabs-below .nav-tabs li { + margin-top: -1px; + margin-bottom: 0; +} + +.tabs-below * .nav-tabs li { + margin-top: 0; + margin-bottom: -1px; +} + +.tabs-below .nav-tabs li a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.tabs-below .nav-tabs li a:hover { + border-top-color: #ddd; + border-bottom-color: #fff; +} + +.tabs-below * .nav-tabs li a { + -webkit-border-radius: none; + -moz-border-radius: none; + border-radius: none; +} + +.tabs-below * .nav-tabs li a:hover { + border-top-color: inherit; + border-bottom-color: inherit; +} + +.tabs-below .nav-tabs .active a, +.tabs-below .nav-tabs .active a:hover { + border-color: transparent #999 #999 #999; +} + +.tabs-below * .nav-tabs .active a, +.tabs-below * .nav-tabs .active a:hover { + border-color: inherit; +} + +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} + +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} + +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} + +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.tabs-left > .nav-tabs > li > a:hover { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} + +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} + +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.tabs-right > .nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.nav .disabled a { + color: #999999; +} + +.nav * .disabled a { + color: inherit; +} + +.nav .disabled a:hover { + text-decoration: none; + cursor: default; + background-color: transparent; +} + +.nav * .disabled a:hover { + text-decoration: underline; + cursor: default; + background-color: inherit; +} + +.navbar { + *position: relative; + *z-index: 2; + margin-bottom: 20px; + overflow: visible; + color: #777777; +} + +.navbar-inner { + _height: 40px; + min-height: 40px; + padding-right: 20px; + padding-left: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + *zoom: 1; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); +} + +.navbar-inner:before, +.navbar-inner:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-inner:after { + clear: both; +} + +.navbar .container { + width: auto; +} + +.nav-collapse.collapse { + height: auto; + overflow: visible; +} + +.navbar .brand { + display: block; + float: left; + padding: 10px 20px 10px; + margin-left: -20px; + _margin-left: -10px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .brand:hover { + text-decoration: none; +} + +.navbar .container-fluid .brand { + _margin-left: -10px; +} + +.navbar-text { + margin-bottom: 0; + line-height: 40px; +} + +.navbar-link { + color: #777777; +} + +.navbar-link:hover { + color: #333333; +} + +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-right: 1px solid #ffffff; + border-left: 1px solid #f2f2f2; +} + +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} + +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn { + margin-top: 0; +} + +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} + +.navbar-form:before, +.navbar-form:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-form:after { + clear: both; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} + +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} + +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 6px; + white-space: nowrap; +} + +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} + +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} + +.navbar-search .search-query { + padding: 4px 14px; + margin-bottom: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.navbar-static-top { + position: static; + margin-bottom: 0; +} + +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} + +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-right: 0; + padding-left: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.navbar-fixed-top { + top: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar-fixed-bottom { + bottom: 0; +} + +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} + +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} + +.navbar .nav li { + float: left; +} + +.navbar .nav * li { + float: none; +} + +.navbar .nav li a { + *display: inline; + float: none; + padding: 10px 15px 10px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; + *zoom: 1; +} + +.navbar .nav * li a { + padding: 0; + color: inherit; + text-decoration: inherit; + text-shadow: inherit; +} + +.navbar .nav li * a { + padding: 0; + color: inherit; + text-decoration: inherit; + text-shadow: inherit; +} + +.navbar .nav .dropdown-toggle { + /* fix for IE6 */ + + _padding: 12px; +} + +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} + +.navbar .nav li a:focus, +.navbar .nav li a:hover { + color: #333333; + text-decoration: none; + background-color: transparent; +} + +.navbar .nav * li a:focus, +.navbar .nav * li a:hover { + color: inherit; + text-decoration: inherit; + background-color: inherit; +} + +.navbar .nav .active a, +.navbar .nav .active a:hover, +.navbar .nav .active a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} + +.navbar .nav * .active a, +.navbar .nav * .active a:hover, +.navbar .nav * .active a:focus { + color: inherit; + text-decoration: inherit; + background-color: inherit; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-right: 5px; + margin-left: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + *background-color: #e5e5e5; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + 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(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); +} + +.navbar .btn-navbar:hover, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} + +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} + +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} + +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} + +.navbar .nav li .dropdown-menu { + /* fix for IE6 li:hover */ + +} + +.navbar .nav li .dropdown-menu:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.navbar .nav li .dropdown-menu:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-left: 6px solid transparent; + content: ''; +} + +.navbar .nav li .dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.navbar .nav li .dropdown-menu li a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; + *zoom: 1; +} + +.navbar .nav li .dropdown-menu li a:hover, +.navbar .nav li .dropdown-menu li a:focus, +.navbar .nav li .dropdown-menu .dropdown-submenu:hover a, +.navbar .nav li .dropdown-menu .dropdown-submenu-hover a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.navbar .nav li .dropdown-menu .dropdown-submenu-hover * a { + *color: inherit; + *background-color: #fffffe; + *background-image: none; + *filter: none; + *filter: chroma(color=#fffffe); +} + +.navbar-fixed-bottom .nav li .dropdown-menu:before { + top: auto; + bottom: -7px; + border-top: 7px solid #ccc; + border-bottom: 0; + border-top-color: rgba(0, 0, 0, 0.2); +} + +.navbar-fixed-bottom .nav li .dropdown-menu:after { + top: auto; + bottom: -6px; + border-top: 6px solid #ffffff; + border-bottom: 0; +} + +.navbar .nav li.dropdown.open .dropdown-toggle, +.navbar .nav li.dropdown.active .dropdown-toggle, +.navbar .nav li.dropdown.open.active .dropdown-toggle { + color: #555555; + background-color: #e5e5e5; +} + +.navbar .nav li.dropdown .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +.navbar .nav li.dropdown.open .dropdown-toggle .caret, +.navbar .nav li.dropdown.active .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar .pull-right li .dropdown-menu, +.navbar .nav li .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar .pull-right li .dropdown-menu:before, +.navbar .nav li .dropdown-menu.pull-right:before { + right: 12px; + left: auto; +} + +.navbar .pull-right li .dropdown-menu:after, +.navbar .nav li .dropdown-menu.pull-right:after { + right: 13px; + left: auto; +} + +.navbar .pull-right li .dropdown-menu .dropdown-menu, +.navbar .nav li .dropdown-menu.pull-right .dropdown-menu { + right: 100%; + left: auto; + margin-right: -1px; + margin-left: 0; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.navbar-inverse { + color: #999999; +} + +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + border-color: #252525; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); +} + +.navbar-inverse .brand, +.navbar-inverse .nav li a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.navbar-inverse .brand:hover, +.navbar-inverse .nav li a:hover { + color: #ffffff; +} + +.navbar-inverse .nav li a:focus, +.navbar-inverse .nav li a:hover { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .nav .active a, +.navbar-inverse .nav .active a:hover, +.navbar-inverse .nav .active a:focus { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover { + color: #ffffff; +} + +.navbar-inverse .divider-vertical { + border-right-color: #222222; + border-left-color: #111111; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} + +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + outline: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} + +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + *background-color: #040404; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + border-color: #040404 #040404 #000000; + 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(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} + +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} + +.breadcrumb { + padding: 8px 15px; + margin: 0 0 20px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.breadcrumb li { + display: inline-block; + *display: inline; + text-shadow: 0 1px 0 #ffffff; + *zoom: 1; +} + +.breadcrumb .divider { + padding: 0 5px; + color: #ccc; +} + +.breadcrumb .active { + color: #999999; + background-color: #f5f5f5; +} + +.pagination { + margin: 20px 0; +} + +.pagination ul { + display: inline-block; + *display: inline; + margin-bottom: 0; + margin-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *zoom: 1; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.pagination ul li { + display: inline; +} + +.pagination ul li a, +.pagination ul li span { + float: left; + padding: 4px 12px; + line-height: 20px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} + +.pagination ul li a:hover, +.pagination ul .active a, +.pagination ul .active span { + background-color: #f5f5f5; +} + +.pagination ul .active a, +.pagination ul .active span { + color: #999999; + cursor: default; +} + +.pagination ul .disabled span, +.pagination ul .disabled a, +.pagination ul .disabled a:hover { + color: #999999; + cursor: default; + background-color: transparent; +} + +.pagination ul li.first-child a, +.pagination ul li.first-child span { + border-left-width: 1px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.pagination ul li:last-child a, +.pagination ul li:last-child span { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.pagination-centered { + text-align: center; +} + +.pagination-right { + text-align: right; +} + +.pagination-large ul li a, +.pagination-large ul li span { + padding: 11px 19px; + font-size: 17.5px; +} + +.pagination-large ul li:first-child a, +.pagination-large ul li:first-child span { + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.pagination-large ul li:last-child a, +.pagination-large ul li:last-child span { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.pagination-mini ul li:first-child a, +.pagination-small ul li:first-child a, +.pagination-mini ul li:first-child span, +.pagination-small ul li:first-child span { + -webkit-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + -moz-border-radius-topleft: 3px; +} + +.pagination-mini ul li:last-child a, +.pagination-small ul li:last-child a, +.pagination-mini ul li:last-child span, +.pagination-small ul li:last-child span { + -webkit-border-top-right-radius: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; +} + +.pagination-small ul li a, +.pagination-small ul li span { + padding: 2px 10px; + font-size: 11.9px; +} + +.pagination-mini ul li a, +.pagination-mini ul li span { + padding: 1px 6px; + font-size: 10.5px; +} + +.pager { + margin: 20px 0; + text-align: center; + list-style: none; + *zoom: 1; +} + +.pager:before, +.pager:after { + display: table; + line-height: 0; + content: ""; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li a, +.pager li span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.pager li a:hover { + text-decoration: none; + background-color: #f5f5f5; +} + +.pager .next a, +.pager .next span { + float: right; +} + +.pager .previous a, +.pager .previous span { + float: left; +} + +.pager .disabled a, +.pager .disabled a:hover, +.pager .disabled span { + color: #999999; + cursor: default; + background-color: #fff; +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + padding: 5px; + font-size: 11px; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.tooltip.top { + margin-top: -3px; +} + +.tooltip.right { + margin-left: 3px; +} + +.tooltip.bottom { + margin-top: 3px; +} + +.tooltip.left { + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + width: 0; + height: 0; + margin-left: -5px; + line-height: 0; + border-color: #000000 transparent transparent; + *border-color: #000000 #fffffe #fffffe; + border-top-color: #000000; + border-style: solid; + border-width: 5px 5px 0; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + width: 0; + height: 0; + margin-top: -5px; + line-height: 0; + border-color: transparent #000000 transparent transparent; + *border-color: #fffffe #000000 #fffffe #fffffe; + border-right-color: #000000; + border-style: solid; + border-width: 5px 5px 5px 0; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + width: 0; + height: 0; + margin-top: -5px; + line-height: 0; + border-color: transparent transparent transparent #000000; + *border-color: #fffffe #fffffe #fffffe #000000; + border-left-color: #000000; + border-style: solid; + border-width: 5px 0 5px 5px; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + width: 0; + height: 0; + margin-left: -5px; + line-height: 0; + border-color: transparent transparent #000000; + *border-color: #fffffe #fffffe #000000; + border-bottom-color: #000000; + border-style: solid; + border-width: 0 5px 5px; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + width: 236px; + padding: 1px; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} + +.popover-content { + padding: 9px 14px; +} + +.popover-content p, +.popover-content ul, +.popover-content ol { + margin-bottom: 0; +} + +.popover .arrow, +.popover .arrow-after { + position: absolute; + display: inline-block; + *display: inline; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + *zoom: 1; +} + +.popover .arrow-after { + z-index: -1; + content: ""; +} + +.popover.top .arrow { + *bottom: -12px; + left: 50%; + width: 0; + height: 0; + margin-left: -10px; + line-height: 0; + border-color: #cccccc transparent transparent; + *border-color: #cccccc #fffffe #fffffe; + border-top-color: #ffffff; + border-style: solid; + border-width: 10px 10px 0; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.popover.top .arrow.arrow-after { + bottom: -1px; + left: -11px; + border-top-color: rgba(0, 0, 0, 0.25); + border-width: 11px 11px 0; +} + +.popover.right .arrow { + top: 50%; + *left: -10px; + width: 0; + height: 0; + margin-top: -10px; + line-height: 0; + border-color: transparent #cccccc transparent transparent; + *border-color: #fffffe #cccccc #fffffe #fffffe; + border-right-color: #ffffff; + border-style: solid; + border-width: 10px 10px 10px 0; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.popover.right .arrow-after { + bottom: -11px; + left: -1px; + border-right-color: rgba(0, 0, 0, 0.25); + border-width: 11px 11px 11px 0; +} + +.popover.bottom .arrow { + *top: -10px; + left: 50%; + width: 0; + height: 0; + margin-left: -10px; + line-height: 0; + border-color: transparent transparent #cccccc; + *border-color: #fffffe #fffffe #cccccc; + border-bottom-color: #ffffff; + border-style: solid; + border-width: 0 10px 10px; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.popover.bottom .arrow-after { + top: -1px; + left: -11px; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-width: 0 11px 11px; +} + +.popover.left .arrow { + top: 50%; + *right: -10px; + width: 0; + height: 0; + margin-top: -10px; + line-height: 0; + border-color: transparent transparent transparent #cccccc; + *border-color: #fffffe #fffffe #fffffe #cccccc; + border-left-color: #ffffff; + border-style: solid; + border-width: 10px 0 10px 10px; + *filter: progid:DXImageTransform.Microsoft.Chroma(color=#fffffe); +} + +.popover.left .arrow-after { + right: -1px; + bottom: -11px; + border-left-color: rgba(0, 0, 0, 0.25); + border-width: 11px 0 11px 11px; +} + +.carousel { + position: relative; + margin-bottom: 20px; + line-height: 1; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel .item img { + display: block; + *width: 100%; + *height: auto; + line-height: 1; +} + +.carousel .active, +.carousel .next, +.carousel .prev { + display: block; +} + +.carousel .active { + left: 0; +} + +.carousel .next, +.carousel .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel .next { + left: 100%; +} + +.carousel .prev { + left: -100%; +} + +.carousel .next.left, +.carousel .prev.right { + left: 0; +} + +.carousel .active.left { + left: -100%; +} + +.carousel .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control-right { + right: 15px; + left: auto; +} + +.carousel-control-left { + left: 15px; +} + +.carousel-control:hover { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-caption { + position: absolute; + right: 0; + bottom: 0; + left: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); + _filter: alpha(opacity=70); +} + +.carousel-caption h4, +.carousel-caption p { + line-height: 20px; + color: #ffffff; +} + +.carousel-caption h4 { + margin: 0 0 5px; +} + +.carousel-caption p { + margin-bottom: 0; +} + +.pull-right { + float: right; +} + +.pull-left { + float: left; +} + +.hide { + display: none; +} + +.show { + display: block; +} + +.invisible { + visibility: hidden; +} + +.affix { + position: fixed; +} diff --git a/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-ie6.min.css b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-ie6.min.css new file mode 100644 index 0000000..04b8c35 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-ie6.min.css @@ -0,0 +1 @@ +article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{display:inline;float:left;width:940px;min-height:1px;margin-left:20px}.span11{display:inline;float:left;width:860px;min-height:1px;margin-left:20px}.span10{display:inline;float:left;width:780px;min-height:1px;margin-left:20px}.span9{display:inline;float:left;width:700px;min-height:1px;margin-left:20px}.span8{display:inline;float:left;width:620px;min-height:1px;margin-left:20px}.span7{display:inline;float:left;width:540px;min-height:1px;margin-left:20px}.span6{display:inline;float:left;width:460px;min-height:1px;margin-left:20px}.span5{display:inline;float:left;width:380px;min-height:1px;margin-left:20px}.span4{display:inline;float:left;width:300px;min-height:1px;margin-left:20px}.span3{display:inline;float:left;width:220px;min-height:1px;margin-left:20px}.span2{display:inline;float:left;width:140px;min-height:1px;margin-left:20px}.span1{display:inline;float:left;width:60px;min-height:1px;margin-left:20px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.span-first-child{margin-left:10px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{display:block;float:left;width:100%;*width:99.94680851063829%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span11{display:block;float:left;width:100%;width:91.48936170212765%;*width:91.43617021276594%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span10{display:block;float:left;width:100%;width:82.97872340425532%;*width:82.92553191489361%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span9{display:block;float:left;width:100%;width:74.46808510638297%;*width:74.41489361702126%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span8{display:block;float:left;width:100%;width:65.95744680851064%;*width:65.90425531914893%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span7{display:block;float:left;width:100%;width:57.44680851063829%;*width:57.39361702127659%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span6{display:block;float:left;width:100%;width:48.93617021276595%;*width:48.88297872340425%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span5{display:block;float:left;width:100%;width:40.42553191489362%;*width:40.37234042553192%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span4{display:block;float:left;width:100%;width:31.914893617021278%;*width:31.861702127659576%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span3{display:block;float:left;width:100%;width:23.404255319148934%;*width:23.351063829787233%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span2{display:block;float:left;width:100%;width:14.893617021276595%;*width:14.840425531914894%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .span1{display:block;float:left;width:100%;width:6.382978723404255%;*width:6.329787234042553%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}.row-fluid .span-first-child{margin-left:0}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;*margin-left:-7px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,.input-text,.input-password,.input-datetime,.input-datetime-local,.input-date,.input-month,.input-time,.input-week,.input-number,.input-email,.input-url,.input-search,.input-tel,.input-color,.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,.input-text,.input-password,.input-datetime,.input-datetime-local,.input-date,.input-month,.input-time,.input-week,.input-number,.input-email,.input-url,.input-search,.input-tel,.input-color,.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,.input-text:focus,.input-password:focus,.input-datetime:focus,.input-datetime-local:focus,.input-date:focus,.input-month:focus,.input-time:focus,.input-week:focus,.input-number:focus,.input-email:focus,.input-url:focus,.input-search:focus,.input-tel:focus,.input-color:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal;cursor:pointer}.input-file,.input-image,.input-submit,.input-reset,.input-button,.input-radio,.input-checkbox{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}.select-multiple,.select-size{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px;_padding-left:0}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline,.radio-inline,.checkbox-inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline,.radio-inline .checkbox-inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12{float:none;width:926px;margin-left:0}.uneditable-input-span12{width:926px}input.span11,textarea.span11{float:none;width:846px;margin-left:0}.uneditable-input-span11{width:846px}input.span10,textarea.span10{float:none;width:766px;margin-left:0}.uneditable-input-span10{width:766px}input.span9,textarea.span9{float:none;width:686px;margin-left:0}.uneditable-input-span9{width:686px}input.span8,textarea.span8{float:none;width:606px;margin-left:0}.uneditable-input-span8{width:606px}input.span7,textarea.span7{float:none;width:526px;margin-left:0}.uneditable-input-span7{width:526px}input.span6,textarea.span6{float:none;width:446px;margin-left:0}.uneditable-input-span6{width:446px}input.span5,textarea.span5{float:none;width:366px;margin-left:0}.uneditable-input-span5{width:366px}input.span4,textarea.span4{float:none;width:286px;margin-left:0}.uneditable-input-span4{width:286px}input.span3,textarea.span3{float:none;width:206px;margin-left:0}.uneditable-input-span3{width:206px}input.span2,textarea.span2{float:none;width:126px;margin-left:0}.uneditable-input-span2{width:126px}input.span1,textarea.span1{float:none;width:46px;margin-left:0}.uneditable-input-span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}.input-disabled,.select-disabled,.textarea-disabled,.input-readonly,.select-readonly,.textarea-readonly{cursor:not-allowed;background-color:#eee}.radio-disabled,.checkbox-disabled,.radio-readonly,.checkbox-readonly{background-color:transparent}.control-group-warning label,.control-group-warning .help-block,.control-group-warning .help-inline{color:#c09853}.control-group-warning * label{color:inherit}.control-group-warning .checkbox,.control-group-warning .radio,.control-group-warning input,.control-group-warning select,.control-group-warning textarea{color:#c09853}.control-group-warning input,.control-group-warning select,.control-group-warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group-warning input:focus,.control-group-warning select:focus,.control-group-warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group-warning .input-prepend .add-on,.control-group-warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group-error label,.control-group-error .help-block,.control-group-error .help-inline{color:#b94a48}.control-group-error * label{color:inherit}.control-group-error .checkbox,.control-group-error .radio,.control-group-error input,.control-group-error select,.control-group-error textarea{color:#b94a48}.control-group-error input,.control-group-error select,.control-group-error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group-error input:focus,.control-group-error select:focus,.control-group-error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group-error .input-prepend .add-on,.control-group-error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group-success label,.control-group-success .help-block,.control-group-success .help-inline{color:#468847}.control-group-success * label{color:inherit}.control-group-success .checkbox,.control-group-success .radio,.control-group-success input,.control-group-success select,.control-group-success textarea{color:#468847}.control-group-success input,.control-group-success select,.control-group-success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group-success input:focus,.control-group-success select:focus,.control-group-success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group-success .input-prepend .add-on,.control-group-success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group-info label,.control-group-info .help-block,.control-group-info .help-inline{color:#3a87ad}.control-group-info * label{color:inherit}.control-group-info .checkbox,.control-group-info .radio,.control-group-info input,.control-group-info select,.control-group-info textarea{color:#3a87ad}.control-group-info input,.control-group-info select,.control-group-info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group-info input:focus,.control-group-info select:focus,.control-group-info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group-info .input-prepend .add-on,.control-group-info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{*margin-top:1px;vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;*margin-right:-2px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn,.input-append select+.btn-group .btn,.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px;*margin-left:-2px}.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls-first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child,.table-bordered tfoot:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child,.table-bordered tfoot:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9}.table-hover tbody .tr-hover td,.table-hover tbody .tr-hover th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success td{background-color:#dff0d8}.table tbody tr.error td{background-color:#f2dede}.table tbody tr.warning td{background-color:#fcf8e3}.table tbody tr.info td{background-color:#d9edf7}.table-hover tbody tr.success:hover td{background-color:#d0e9c6}.table-hover tbody tr.error:hover td{background-color:#ebcccc}.table-hover tbody tr.warning:hover td{background-color:#faf2cc}.table-hover tbody tr.info:hover td{background-color:#c4e3f3}.icon-xxx{display:inline-block;_display:inline;width:14px;_width:14px;height:14px;_height:19px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;_vertical-align:middle;background-image:url("../img/glyphicons-halflings.png");_background-image:url("../img/glyphicons-halflings-8.png");background-position:14px 14px;background-repeat:no-repeat;_zoom:1}.icon-white{background-image:url("../img/glyphicons-halflings-white.png")}.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative;display:inline;*zoom:1}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;*display:inline;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";*zoom:1}.caret{width:0;height:0;line-height:0;border-color:#000 transparent transparent;*border-color:#000 #fffffe #fffffe;border-style:solid;border-width:4px 4px 0;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;*width:auto!important;*width:160px;*height:1px;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu li a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;*zoom:1}.dropdown-menu li a:hover,.dropdown-menu li a:focus,.dropdown-submenu:hover a,.dropdown-submenu-hover a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-submenu-hover * a{*color:inherit;*background-color:#fffffe;*background-image:none;*filter:none;*filter:chroma(color=#fffffe)}.dropdown-menu .active a,.dropdown-menu .active a:hover{color:#333;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .disabled a,.dropdown-menu .disabled a:hover{color:#999}.dropdown-menu .disabled a:hover{text-decoration:none;cursor:default;background-color:transparent;*background-color:#fffffe;background-image:none;*filter:chroma(color=#fffffe)}.open{*z-index:1000}.open .dropdown-menu{display:block;*zoom:1}.pull-right .dropdown-menu{right:0;left:auto}.pull-right * .dropdown-menu{right:auto;left:0}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative;*display:inline;*zoom:1}.dropdown-submenu .dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover .dropdown-menu,.dropdown-submenu-hover .dropdown-menu{display:block}.dropup .dropdown-submenu .dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;*border-color:#fffffe;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" ";*filter:chroma(color=#fffffe);*zoom:1}.dropdown-submenu .dropdown-tri{display:block;float:right;width:0;height:0;margin:-1.3em 5px 0 0;line-height:0;border-color:transparent transparent transparent #ccc;_border-color:#fffffe #fffffe #fffffe #ccc;border-style:solid;border-width:5px 0 5px 5px;_filter:chroma(color=#fffffe);zoom:1}.dropdown-submenu:hover a:after,.dropdown-submenu-hover .dropdown-tri{border-left-color:#fff}.dropdown-submenu-pull-left{float:none}.dropdown-submenu-pull-left .dropdown-menu{left:-100%;margin-left:10px;*margin-left:18px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown-submenu-pull-left * .dropdown-menu{left:0;margin-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.btn{display:inline-block;*display:inline;padding:4px 12px;_padding-top:3px;_padding-bottom:3px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;*line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #bbb;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn.btn-hover{color:#333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:active,.btn.active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled],.btn-disabled{cursor:default;background-color:#e6e6e6;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn.btn-large{*padding-top:7px;*padding-bottom:7px}.btn.btn-small{*padding-top:3px;*padding-bottom:3px}.btn.btn-mini{*padding-top:1px;*padding-bottom:1px}a.btn{*padding-top:5px;*padding-bottom:5px}a.btn.btn-large{*padding-top:13px;*padding-bottom:15px}a.btn.btn-small{*padding-top:4px;*padding-bottom:4px}a.btn.btn-mini{*padding-top:3px;*padding-bottom:3px}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:2px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini{padding:1px 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn{border-color:#c5c5c5;border-color:rgba(0,0,0,0.15) rgba(0,0,0,0.15) rgba(0,0,0,0.25)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #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(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-primary.btn-primary-hover{color:#fff;background-color:#04c;*background-color:#003bb3}a.btn-primary-hover:hover{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;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(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-warning.btn-warning-hover{color:#fff;background-color:#f89406;*background-color:#df8505}a.btn-warning-hover:hover{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;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(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-danger.btn-danger-hover{color:#fff;background-color:#bd362f;*background-color:#a9302a}a.btn-danger-hover:hover{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;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(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-success.btn-success-hover{color:#fff;background-color:#51a351;*background-color:#499249}a.btn-success-hover:hover{color:#fff;background-color:#51a351;*background-color:#499249}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;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(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-info.btn-info-hover{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}a.btn-info-hover:hover{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;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(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}.btn-inverse.btn-inverse-hover{color:#fff;background-color:#222;*background-color:#3c3c3c}a.btn-inverse-hover:hover{color:#fff;background-color:#222;*background-color:#3c3c3c}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover{color:#333;text-decoration:none}.btn-disabled{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);filter:alpha(opacity=35);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group{margin-left:5px}.btn-group-first{margin-left:0}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar .btn .btn-group{margin-left:5px}.btn-toolbar .btn-first,.btn-toolbar .btn-group-first{margin-left:0}.btn-group .btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group .btn{margin-left:-1px}.btn-group .btn-first{margin-left:0}.btn-group .btn,.btn-group .dropdown-menu{font-size:14px}.btn-group .dropdown-menu .divider{_margin:5px 0 -5px}.btn-group .btn-mini{font-size:11px}.btn-group .btn-small{font-size:12px}.btn-group .btn-large{font-size:16px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group .dropdown-toggle{padding-right:9px;padding-left:9px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group .btn-mini-dropdown-toggle{padding-right:7px;padding-left:7px}.btn-group .btn-large-dropdown-toggle{padding-right:17px;padding-left:17px}.btn-group-open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group-open .btn-dropdown-toggle{background-color:#e6e6e6}.btn-group-open .btn-primary-dropdown-toggle{background-color:#04c}.btn-group-open .btn-warning-dropdown-toggle{background-color:#f89406}.btn-group-open .btn-danger-dropdown-toggle{background-color:#bd362f}.btn-group-open .btn-success-dropdown-toggle{background-color:#51a351}.btn-group-open .btn-info-dropdown-toggle{background-color:#2f96b4}.btn-group-open .btn-inverse-dropdown-toggle{background-color:#222}.btn .caret{_display:inline;_height:8px;margin-top:8px;margin-left:0;_vertical-align:middle;_zoom:1}.btn-mini .caret,.btn-small .caret{_height:10px}.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px}.btn-large .caret{_height:9px;border-top-width:5px;border-right-width:5px;border-left-width:5px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical .btn{display:block;float:none;width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical .btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical .btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical .btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical .btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical .btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert h4{*display:inline;margin:0;*zoom:1}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block p,.alert-block ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav li a{display:block;*zoom:1}.nav * li a{display:inline}.nav li * a{display:inline}.nav li a:hover{text-decoration:none;background-color:#eee}.nav * li a:hover{text-decoration:inherit;background-color:inherit}.nav li * a:hover{text-decoration:inherit;background-color:inherit}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase;*zoom:1}.nav .nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list li a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list li a{padding:3px 15px}.nav-list * li a{padding:0;margin-right:0;margin-left:0;text-shadow:none}.nav-list li * a{padding:0;margin-right:0;margin-left:0;text-shadow:none}.nav-list .active a,.nav-list .active a:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list * .active a,.nav-list * .active a:hover{color:inherit;text-shadow:none;background-color:inherit}.nav-list .active * a,.nav-list .active * a:hover{color:inherit;text-shadow:none;background-color:inherit}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs li,.nav-pills li{float:left}.nav-tabs * li,.nav-pills * li{float:none}.nav-tabs li a,.nav-pills li a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs * li a,.nav-pills * li a{padding:0;margin:0;line-height:auto}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs li{margin-bottom:-1px;*background-color:#fff;*zoom:1}.nav-tabs * li{zoom:normal}.nav-tabs li a{*display:inline;padding-top:8px;padding-bottom:8px;line-height:20px;*background-color:#fffffe;border:1px solid transparent;*border:1px solid #fffffe;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;*filter:chroma(color=#fffffe);*zoom:1}.nav-tabs li a:hover{border-color:#eee #eee #ddd}.nav-tabs * li a{padding:0;line-height:auto;background-color:inherit;border:0;filter:none;zoom:normal}.nav-tabs .active a,.nav-tabs .active a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;*border:1px solid #999;border-bottom-color:transparent}.nav-tabs * .active a,.nav-tabs * .active a:hover{color:inherit;background-color:inherit;border:0}.nav-pills li{*background-color:#fff;*zoom:1}.nav-pills * li{background-color:inherit;zoom:normal}.nav-pills li a{*display:inline;padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;*zoom:1}.nav-pills * li a{padding:0;margin:0;-webkit-border-radius:none;-moz-border-radius:none;border-radius:none;zoom:normal}.nav-pills .active a,.nav-pills .active a:hover{color:#fff;background-color:#08c}.nav-pills * .active a,.nav-pills * .active a:hover{color:inherit;background-color:inherit}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-tabs .dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs .dropdown-menu li a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;*zoom:1}.nav-tabs .dropdown-menu li a:hover,.nav-tabs .dropdown-menu li a:focus,.nav-tabs .dropdown-menu .dropdown-submenu:hover a,.nav-tabs .dropdown-menu .dropdown-submenu-hover a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.nav-tabs .dropdown-menu .dropdown-submenu-hover * a{*color:inherit;*background-color:#fffffe;*background-image:none;*filter:none;*filter:chroma(color=#fffffe)}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav-pills .dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-pills .dropdown-menu li a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;*zoom:1}.nav-pills .dropdown-menu li a:hover,.nav-pills .dropdown-menu li a:focus,.nav-pills .dropdown-menu .dropdown-submenu:hover a,.nav-pills .dropdown-menu .dropdown-submenu-hover a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.nav-pills .dropdown-menu .dropdown-submenu-hover * a{*color:inherit;*background-color:#fffffe;*background-image:none;*filter:none;*filter:chroma(color=#fffffe)}.nav-tabs .dropdown-toggle{*padding-top:10px;*padding-bottom:12px}.nav-pills .dropdown-toggle{*padding-top:8px;*padding-bottom:6px;*margin-bottom:3px}.nav .dropdown-toggle .caret{width:0;height:0;margin-top:6px;line-height:0;border-color:#08c transparent transparent;*border-color:#08c #fffffe #fffffe;border-top-color:#08c;border-bottom-color:#08c;border-style:solid;border-width:4px 4px 0;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav .dropdown.active a:hover{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav li.dropdown-open.active a:hover{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown-open .caret,.nav li.dropdown-open.active .caret,.nav li.dropdown-open a:hover .caret{width:0;height:0;line-height:0;border-color:#fff transparent transparent;*border-color:#fff #fffffe #fffffe;border-top-color:#fff;border-bottom-color:#fff;border-style:solid;border-width:4px 4px 0;opacity:1;filter:alpha(opacity=100);*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.tabs-stacked .open>a:hover{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below .nav-tabs,.tabs-right .nav-tabs,.tabs-left .nav-tabs{border-bottom:0}.tab-content .tab-pane,.pill-content .pill-pane{display:none;*background-color:#fff;*zoom:1}.tab-content .active,.pill-content .active{display:block}.tabs-below .nav-tabs{border-top:1px solid #ddd}.tabs-below * .nav-tabs{border-top:0}.tabs-below .nav-tabs li{margin-top:-1px;margin-bottom:0}.tabs-below * .nav-tabs li{margin-top:0;margin-bottom:-1px}.tabs-below .nav-tabs li a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below .nav-tabs li a:hover{border-top-color:#ddd;border-bottom-color:#fff}.tabs-below * .nav-tabs li a{-webkit-border-radius:none;-moz-border-radius:none;border-radius:none}.tabs-below * .nav-tabs li a:hover{border-top-color:inherit;border-bottom-color:inherit}.tabs-below .nav-tabs .active a,.tabs-below .nav-tabs .active a:hover{border-color:transparent #999 #999 #999}.tabs-below * .nav-tabs .active a,.tabs-below * .nav-tabs .active a:hover{border-color:inherit}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav .disabled a{color:#999}.nav * .disabled a{color:inherit}.nav .disabled a:hover{text-decoration:none;cursor:default;background-color:transparent}.nav * .disabled a:hover{text-decoration:underline;cursor:default;background-color:inherit}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible;color:#777}.navbar-inner{_height:40px;min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;_margin-left:-10px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover{text-decoration:none}.navbar .container-fluid .brand{_margin-left:-10px}.navbar-text{margin-bottom:0;line-height:40px}.navbar-link{color:#777}.navbar-link:hover{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav li{float:left}.navbar .nav * li{float:none}.navbar .nav li a{*display:inline;float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff;*zoom:1}.navbar .nav * li a{padding:0;color:inherit;text-decoration:inherit;text-shadow:inherit}.navbar .nav li * a{padding:0;color:inherit;text-decoration:inherit;text-shadow:inherit}.navbar .nav .dropdown-toggle{_padding:12px}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav li a:focus,.navbar .nav li a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav * li a:focus,.navbar .nav * li a:hover{color:inherit;text-decoration:inherit;background-color:inherit}.navbar .nav .active a,.navbar .nav .active a:hover,.navbar .nav .active a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .nav * .active a,.navbar .nav * .active a:hover,.navbar .nav * .active a:focus{color:inherit;text-decoration:inherit;background-color:inherit;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;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(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav li .dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav li .dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar .nav li .dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.navbar .nav li .dropdown-menu li a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;*zoom:1}.navbar .nav li .dropdown-menu li a:hover,.navbar .nav li .dropdown-menu li a:focus,.navbar .nav li .dropdown-menu .dropdown-submenu:hover a,.navbar .nav li .dropdown-menu .dropdown-submenu-hover a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.navbar .nav li .dropdown-menu .dropdown-submenu-hover * a{*color:inherit;*background-color:#fffffe;*background-image:none;*filter:none;*filter:chroma(color=#fffffe)}.navbar-fixed-bottom .nav li .dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav li .dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown.open .dropdown-toggle,.navbar .nav li.dropdown.active .dropdown-toggle,.navbar .nav li.dropdown.open.active .dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown .dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open .dropdown-toggle .caret,.navbar .nav li.dropdown.active .dropdown-toggle .caret,.navbar .nav li.dropdown.open.active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right li .dropdown-menu,.navbar .nav li .dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right li .dropdown-menu:before,.navbar .nav li .dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right li .dropdown-menu:after,.navbar .nav li .dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right li .dropdown-menu .dropdown-menu,.navbar .nav li .dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse{color:#999}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav li a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav li a:hover{color:#fff}.navbar-inverse .nav li a:focus,.navbar-inverse .nav li a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active a,.navbar-inverse .nav .active a:hover,.navbar-inverse .nav .active a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;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(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb .divider{padding:0 5px;color:#ccc}.breadcrumb .active{color:#999;background-color:#f5f5f5}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul li{display:inline}.pagination ul li a,.pagination ul li span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul li a:hover,.pagination ul .active a,.pagination ul .active span{background-color:#f5f5f5}.pagination ul .active a,.pagination ul .active span{color:#999;cursor:default}.pagination ul .disabled span,.pagination ul .disabled a,.pagination ul .disabled a:hover{color:#999;cursor:default;background-color:transparent}.pagination ul li.first-child a,.pagination ul li.first-child span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul li:last-child a,.pagination ul li:last-child span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul li a,.pagination-large ul li span{padding:11px 19px;font-size:17.5px}.pagination-large ul li:first-child a,.pagination-large ul li:first-child span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul li:last-child a,.pagination-large ul li:last-child span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul li:first-child a,.pagination-small ul li:first-child a,.pagination-mini ul li:first-child span,.pagination-small ul li:first-child span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul li:last-child a,.pagination-small ul li:last-child a,.pagination-mini ul li:last-child span,.pagination-small ul li:last-child span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul li a,.pagination-small ul li span{padding:2px 10px;font-size:11.9px}.pagination-mini ul li a,.pagination-mini ul li span{padding:1px 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li a,.pager li span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li a:hover{text-decoration:none;background-color:#f5f5f5}.pager .next a,.pager .next span{float:right}.pager .previous a,.pager .previous span{float:left}.pager .disabled a,.pager .disabled a:hover,.pager .disabled span{color:#999;cursor:default;background-color:#fff}.tooltip{position:absolute;z-index:1030;display:block;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px}.tooltip.right{margin-left:3px}.tooltip.bottom{margin-top:3px}.tooltip.left{margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;width:0;height:0;margin-left:-5px;line-height:0;border-color:#000 transparent transparent;*border-color:#000 #fffffe #fffffe;border-top-color:#000;border-style:solid;border-width:5px 5px 0;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.tooltip.right .tooltip-arrow{top:50%;left:0;width:0;height:0;margin-top:-5px;line-height:0;border-color:transparent #000 transparent transparent;*border-color:#fffffe #000 #fffffe #fffffe;border-right-color:#000;border-style:solid;border-width:5px 5px 5px 0;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.tooltip.left .tooltip-arrow{top:50%;right:0;width:0;height:0;margin-top:-5px;line-height:0;border-color:transparent transparent transparent #000;*border-color:#fffffe #fffffe #fffffe #000;border-left-color:#000;border-style:solid;border-width:5px 0 5px 5px;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.tooltip.bottom .tooltip-arrow{top:0;left:50%;width:0;height:0;margin-left:-5px;line-height:0;border-color:transparent transparent #000;*border-color:#fffffe #fffffe #000;border-bottom-color:#000;border-style:solid;border-width:0 5px 5px;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0}.popover .arrow,.popover .arrow-after{position:absolute;display:inline-block;*display:inline;width:0;height:0;border-color:transparent;border-style:solid;*zoom:1}.popover .arrow-after{z-index:-1;content:""}.popover.top .arrow{*bottom:-12px;left:50%;width:0;height:0;margin-left:-10px;line-height:0;border-color:#ccc transparent transparent;*border-color:#ccc #fffffe #fffffe;border-top-color:#fff;border-style:solid;border-width:10px 10px 0;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.popover.top .arrow.arrow-after{bottom:-1px;left:-11px;border-top-color:rgba(0,0,0,0.25);border-width:11px 11px 0}.popover.right .arrow{top:50%;*left:-10px;width:0;height:0;margin-top:-10px;line-height:0;border-color:transparent #ccc transparent transparent;*border-color:#fffffe #ccc #fffffe #fffffe;border-right-color:#fff;border-style:solid;border-width:10px 10px 10px 0;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.popover.right .arrow-after{bottom:-11px;left:-1px;border-right-color:rgba(0,0,0,0.25);border-width:11px 11px 11px 0}.popover.bottom .arrow{*top:-10px;left:50%;width:0;height:0;margin-left:-10px;line-height:0;border-color:transparent transparent #ccc;*border-color:#fffffe #fffffe #ccc;border-bottom-color:#fff;border-style:solid;border-width:0 10px 10px;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.popover.bottom .arrow-after{top:-1px;left:-11px;border-bottom-color:rgba(0,0,0,0.25);border-width:0 11px 11px}.popover.left .arrow{top:50%;*right:-10px;width:0;height:0;margin-top:-10px;line-height:0;border-color:transparent transparent transparent #ccc;*border-color:#fffffe #fffffe #fffffe #ccc;border-left-color:#fff;border-style:solid;border-width:10px 0 10px 10px;*filter:progid:DXImageTransform.Microsoft.Chroma(color=#fffffe)}.popover.left .arrow-after{right:-1px;bottom:-11px;border-left-color:rgba(0,0,0,0.25);border-width:11px 0 11px 11px}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel .item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel .item img{display:block;*width:100%;*height:auto;line-height:1}.carousel .active,.carousel .next,.carousel .prev{display:block}.carousel .active{left:0}.carousel .next,.carousel .prev{position:absolute;top:0;width:100%}.carousel .next{left:100%}.carousel .prev{left:-100%}.carousel .next.left,.carousel .prev.right{left:0}.carousel .active.left{left:-100%}.carousel .active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control-right{right:15px;left:auto}.carousel-control-left{left:15px}.carousel-control:hover{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75);_filter:alpha(opacity=70)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} diff --git a/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-responsive.css b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-responsive.css new file mode 100644 index 0000000..c0bba15 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-responsive.css @@ -0,0 +1,1109 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2013 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +@-ms-viewport { + width: device-width; +} + +.hidden { + display: none; + visibility: hidden; +} + +.visible-phone { + display: none !important; +} + +.visible-tablet { + display: none !important; +} + +.hidden-desktop { + display: none !important; +} + +.visible-desktop { + display: inherit !important; +} + +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} + +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} + +.visible-print { + display: none !important; +} + +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} + +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.564102564102564%; + *margin-left: 2.5109110747408616%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.564102564102564%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.45299145299145%; + *width: 91.39979996362975%; + } + .row-fluid .span10 { + width: 82.90598290598291%; + *width: 82.8527914166212%; + } + .row-fluid .span9 { + width: 74.35897435897436%; + *width: 74.30578286961266%; + } + .row-fluid .span8 { + width: 65.81196581196582%; + *width: 65.75877432260411%; + } + .row-fluid .span7 { + width: 57.26495726495726%; + *width: 57.21176577559556%; + } + .row-fluid .span6 { + width: 48.717948717948715%; + *width: 48.664757228587014%; + } + .row-fluid .span5 { + width: 40.17094017094017%; + *width: 40.11774868157847%; + } + .row-fluid .span4 { + width: 31.623931623931625%; + *width: 31.570740134569924%; + } + .row-fluid .span3 { + width: 23.076923076923077%; + *width: 23.023731587561375%; + } + .row-fluid .span2 { + width: 14.52991452991453%; + *width: 14.476723040552828%; + } + .row-fluid .span1 { + width: 5.982905982905983%; + *width: 5.929714493544281%; + } + .row-fluid .offset12 { + margin-left: 105.12820512820512%; + *margin-left: 105.02182214948171%; + } + .row-fluid .offset12:first-child { + margin-left: 102.56410256410257%; + *margin-left: 102.45771958537915%; + } + .row-fluid .offset11 { + margin-left: 96.58119658119658%; + *margin-left: 96.47481360247316%; + } + .row-fluid .offset11:first-child { + margin-left: 94.01709401709402%; + *margin-left: 93.91071103837061%; + } + .row-fluid .offset10 { + margin-left: 88.03418803418803%; + *margin-left: 87.92780505546462%; + } + .row-fluid .offset10:first-child { + margin-left: 85.47008547008548%; + *margin-left: 85.36370249136206%; + } + .row-fluid .offset9 { + margin-left: 79.48717948717949%; + *margin-left: 79.38079650845607%; + } + .row-fluid .offset9:first-child { + margin-left: 76.92307692307693%; + *margin-left: 76.81669394435352%; + } + .row-fluid .offset8 { + margin-left: 70.94017094017094%; + *margin-left: 70.83378796144753%; + } + .row-fluid .offset8:first-child { + margin-left: 68.37606837606839%; + *margin-left: 68.26968539734497%; + } + .row-fluid .offset7 { + margin-left: 62.393162393162385%; + *margin-left: 62.28677941443899%; + } + .row-fluid .offset7:first-child { + margin-left: 59.82905982905982%; + *margin-left: 59.72267685033642%; + } + .row-fluid .offset6 { + margin-left: 53.84615384615384%; + *margin-left: 53.739770867430444%; + } + .row-fluid .offset6:first-child { + margin-left: 51.28205128205128%; + *margin-left: 51.175668303327875%; + } + .row-fluid .offset5 { + margin-left: 45.299145299145295%; + *margin-left: 45.1927623204219%; + } + .row-fluid .offset5:first-child { + margin-left: 42.73504273504273%; + *margin-left: 42.62865975631933%; + } + .row-fluid .offset4 { + margin-left: 36.75213675213675%; + *margin-left: 36.645753773413354%; + } + .row-fluid .offset4:first-child { + margin-left: 34.18803418803419%; + *margin-left: 34.081651209310785%; + } + .row-fluid .offset3 { + margin-left: 28.205128205128204%; + *margin-left: 28.0987452264048%; + } + .row-fluid .offset3:first-child { + margin-left: 25.641025641025642%; + *margin-left: 25.53464266230224%; + } + .row-fluid .offset2 { + margin-left: 19.65811965811966%; + *margin-left: 19.551736679396257%; + } + .row-fluid .offset2:first-child { + margin-left: 17.094017094017094%; + *margin-left: 16.98763411529369%; + } + .row-fluid .offset1 { + margin-left: 11.11111111111111%; + *margin-left: 11.004728132387708%; + } + .row-fluid .offset1:first-child { + margin-left: 8.547008547008547%; + *margin-left: 8.440625568285142%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} + +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.7624309392265194%; + *margin-left: 2.709239449864817%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.7624309392265194%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.43646408839778%; + *width: 91.38327259903608%; + } + .row-fluid .span10 { + width: 82.87292817679558%; + *width: 82.81973668743387%; + } + .row-fluid .span9 { + width: 74.30939226519337%; + *width: 74.25620077583166%; + } + .row-fluid .span8 { + width: 65.74585635359117%; + *width: 65.69266486422946%; + } + .row-fluid .span7 { + width: 57.18232044198895%; + *width: 57.12912895262725%; + } + .row-fluid .span6 { + width: 48.61878453038674%; + *width: 48.56559304102504%; + } + .row-fluid .span5 { + width: 40.05524861878453%; + *width: 40.00205712942283%; + } + .row-fluid .span4 { + width: 31.491712707182323%; + *width: 31.43852121782062%; + } + .row-fluid .span3 { + width: 22.92817679558011%; + *width: 22.87498530621841%; + } + .row-fluid .span2 { + width: 14.3646408839779%; + *width: 14.311449394616199%; + } + .row-fluid .span1 { + width: 5.801104972375691%; + *width: 5.747913483013988%; + } + .row-fluid .offset12 { + margin-left: 105.52486187845304%; + *margin-left: 105.41847889972962%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243093922652%; + *margin-left: 102.6560479605031%; + } + .row-fluid .offset11 { + margin-left: 96.96132596685082%; + *margin-left: 96.8549429881274%; + } + .row-fluid .offset11:first-child { + margin-left: 94.1988950276243%; + *margin-left: 94.09251204890089%; + } + .row-fluid .offset10 { + margin-left: 88.39779005524862%; + *margin-left: 88.2914070765252%; + } + .row-fluid .offset10:first-child { + margin-left: 85.6353591160221%; + *margin-left: 85.52897613729868%; + } + .row-fluid .offset9 { + margin-left: 79.8342541436464%; + *margin-left: 79.72787116492299%; + } + .row-fluid .offset9:first-child { + margin-left: 77.07182320441989%; + *margin-left: 76.96544022569647%; + } + .row-fluid .offset8 { + margin-left: 71.2707182320442%; + *margin-left: 71.16433525332079%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729281768%; + *margin-left: 68.40190431409427%; + } + .row-fluid .offset7 { + margin-left: 62.70718232044199%; + *margin-left: 62.600799341718584%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138121547%; + *margin-left: 59.838368402492065%; + } + .row-fluid .offset6 { + margin-left: 54.14364640883978%; + *margin-left: 54.037263430116376%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121546961326%; + *margin-left: 51.27483249088986%; + } + .row-fluid .offset5 { + margin-left: 45.58011049723757%; + *margin-left: 45.47372751851417%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767955801105%; + *margin-left: 42.71129657928765%; + } + .row-fluid .offset4 { + margin-left: 37.01657458563536%; + *margin-left: 36.91019160691196%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414364640884%; + *margin-left: 34.14776066768544%; + } + .row-fluid .offset3 { + margin-left: 28.45303867403315%; + *margin-left: 28.346655695309746%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773480663%; + *margin-left: 25.584224756083227%; + } + .row-fluid .offset2 { + margin-left: 19.88950276243094%; + *margin-left: 19.783119783707537%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182320442%; + *margin-left: 17.02068884448102%; + } + .row-fluid .offset1 { + margin-left: 11.32596685082873%; + *margin-left: 11.219583872105325%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591160221%; + *margin-left: 8.457152932878806%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} + +@media (max-width: 767px) { + body { + padding-right: 20px; + padding-left: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-right: -20px; + margin-left: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + width: auto; + clear: none; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + display: block; + float: none; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } + .modal { + position: fixed; + top: 20px; + right: 20px; + left: 20px; + width: auto; + margin: 0; + } + .modal.fade { + top: -100px; + } + .modal.fade.in { + top: 20px; + } +} + +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 20px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-right: 10px; + padding-left: 10px; + } + .media .pull-left, + .media .pull-right { + display: block; + float: none; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal { + top: 10px; + right: 10px; + left: 10px; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} + +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 20px; + } + .navbar-fixed-bottom { + margin-top: 20px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-right: 10px; + padding-left: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 10px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #777777; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #777777; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #999999; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #111111; + } + .nav-collapse.in .btn-group { + padding: 0; + margin-top: 5px; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + display: none; + float: none; + max-width: none; + padding: 0; + margin: 0 15px; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 10px 15px; + margin: 10px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #111111; + border-bottom-color: #111111; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + height: 0; + overflow: hidden; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-right: 10px; + padding-left: 10px; + } +} + +@media (min-width: 980px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-responsive.min.css b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-responsive.min.css new file mode 100644 index 0000000..96a435b --- /dev/null +++ b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-responsive.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2013 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.css b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.css new file mode 100644 index 0000000..31d8882 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.css @@ -0,0 +1,587 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +.btn-default, +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); +} +.btn-default:active, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active, +.btn-default.active, +.btn-primary.active, +.btn-success.active, +.btn-info.active, +.btn-warning.active, +.btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-default.disabled, +.btn-primary.disabled, +.btn-success.disabled, +.btn-info.disabled, +.btn-warning.disabled, +.btn-danger.disabled, +.btn-default[disabled], +.btn-primary[disabled], +.btn-success[disabled], +.btn-info[disabled], +.btn-warning[disabled], +.btn-danger[disabled], +fieldset[disabled] .btn-default, +fieldset[disabled] .btn-primary, +fieldset[disabled] .btn-success, +fieldset[disabled] .btn-info, +fieldset[disabled] .btn-warning, +fieldset[disabled] .btn-danger { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-default .badge, +.btn-primary .badge, +.btn-success .badge, +.btn-info .badge, +.btn-warning .badge, +.btn-danger .badge { + text-shadow: none; +} +.btn:active, +.btn.active { + background-image: none; +} +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus { + background-color: #e0e0e0; + background-position: 0 -15px; +} +.btn-default:active, +.btn-default.active { + background-color: #e0e0e0; + border-color: #dbdbdb; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #e0e0e0; + background-image: none; +} +.btn-primary { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); + background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #245580; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #265a88; + background-position: 0 -15px; +} +.btn-primary:active, +.btn-primary.active { + background-color: #265a88; + border-color: #245580; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #265a88; + background-image: none; +} +.btn-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #3e8f3e; +} +.btn-success:hover, +.btn-success:focus { + background-color: #419641; + background-position: 0 -15px; +} +.btn-success:active, +.btn-success.active { + background-color: #419641; + border-color: #3e8f3e; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #419641; + background-image: none; +} +.btn-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #28a4c9; +} +.btn-info:hover, +.btn-info:focus { + background-color: #2aabd2; + background-position: 0 -15px; +} +.btn-info:active, +.btn-info.active { + background-color: #2aabd2; + border-color: #28a4c9; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #2aabd2; + background-image: none; +} +.btn-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #e38d13; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #eb9316; + background-position: 0 -15px; +} +.btn-warning:active, +.btn-warning.active { + background-color: #eb9316; + border-color: #e38d13; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #eb9316; + background-image: none; +} +.btn-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #b92c28; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #c12e2a; + background-position: 0 -15px; +} +.btn-danger:active, +.btn-danger.active { + background-color: #c12e2a; + border-color: #b92c28; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #c12e2a; + background-image: none; +} +.thumbnail, +.img-thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + background-color: #2e6da4; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.navbar-default { + background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); + background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); + background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); +} +.navbar-brand, +.navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255, 255, 255, .25); +} +.navbar-inverse { + background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); + background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); +} +.navbar-inverse .navbar-brand, +.navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); +} +.navbar-static-top, +.navbar-fixed-top, +.navbar-fixed-bottom { + border-radius: 0; +} +@media (max-width: 767px) { + .navbar .navbar-nav .open .dropdown-menu > .active > a, + .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; + } +} +.alert { + text-shadow: 0 1px 0 rgba(255, 255, 255, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); +} +.alert-success { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1; +} +.alert-info { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea; +} +.alert-warning { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e; +} +.alert-danger { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7; +} +.progress { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); + background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + text-shadow: 0 -1px 0 #286090; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); + background-repeat: repeat-x; + border-color: #2b669a; +} +.list-group-item.active .badge, +.list-group-item.active:hover .badge, +.list-group-item.active:focus .badge { + text-shadow: none; +} +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: 0 1px 2px rgba(0, 0, 0, .05); +} +.panel-default > .panel-heading { + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.panel-primary > .panel-heading { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.panel-success > .panel-heading { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x; +} +.panel-info > .panel-heading { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x; +} +.panel-warning > .panel-heading { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x; +} +.panel-danger > .panel-heading { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x; +} +.well { + background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); +} +/*# sourceMappingURL=bootstrap-theme.css.map */ diff --git a/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.css.map b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.css.map new file mode 100644 index 0000000..d876f60 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap-theme.css","less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","file":"bootstrap-theme.css","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default.disabled,\n.btn-primary.disabled,\n.btn-success.disabled,\n.btn-info.disabled,\n.btn-warning.disabled,\n.btn-danger.disabled,\n.btn-default[disabled],\n.btn-primary[disabled],\n.btn-success[disabled],\n.btn-info[disabled],\n.btn-warning[disabled],\n.btn-danger[disabled],\nfieldset[disabled] .btn-default,\nfieldset[disabled] .btn-primary,\nfieldset[disabled] .btn-success,\nfieldset[disabled] .btn-info,\nfieldset[disabled] .btn-warning,\nfieldset[disabled] .btn-danger {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.min.css b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.min.css new file mode 100644 index 0000000..5e39401 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} +/*# sourceMappingURL=bootstrap-theme.min.css.map */ \ No newline at end of file diff --git a/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.min.css.map b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.min.css.map new file mode 100644 index 0000000..94813e9 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap-theme.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n .box-shadow(none);\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257\n border-radius: @navbar-border-radius;\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.css b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.css new file mode 100644 index 0000000..680e768 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.css @@ -0,0 +1,6800 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +[role="button"] { + cursor: pointer; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +mark, +.mark { + padding: .2em; + background-color: #fcf8e3; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777; +} +.text-primary { + color: #337ab7; +} +a.text-primary:hover, +a.text-primary:focus { + color: #286090; +} +.text-success { + color: #3c763d; +} +a.text-success:hover, +a.text-success:focus { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover, +a.text-info:focus { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover, +a.text-warning:focus { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover, +a.text-danger:focus { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #337ab7; +} +a.bg-primary:hover, +a.bg-primary:focus { + background-color: #286090; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover, +a.bg-success:focus { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover, +a.bg-info:focus { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover, +a.bg-warning:focus { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover, +a.bg-danger:focus { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + min-height: .01%; + overflow-x: auto; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #eee; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 4px \9; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + min-height: 34px; + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-right: 0; + padding-left: 0; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.form-group-sm select.form-control { + height: 30px; + line-height: 30px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 30px; + min-height: 32px; + padding: 6px 10px; + font-size: 12px; + line-height: 1.5; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.form-group-lg select.form-control { + height: 46px; + line-height: 46px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 46px; + min-height: 38px; + padding: 11px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + padding-top: 7px; + margin-bottom: 0; + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 14.333333px; + font-size: 18px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 12px; + } +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:focus, +.btn-default.focus { + color: #333; + background-color: #e6e6e6; + border-color: #8c8c8c; +} +.btn-default:hover { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:focus, +.btn-primary.focus { + color: #fff; + background-color: #286090; + border-color: #122b40; +} +.btn-primary:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #fff; + background-color: #204d74; + border-color: #122b40; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:focus, +.btn-success.focus { + color: #fff; + background-color: #449d44; + border-color: #255625; +} +.btn-success:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #fff; + background-color: #398439; + border-color: #255625; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:focus, +.btn-info.focus { + color: #fff; + background-color: #31b0d5; + border-color: #1b6d85; +} +.btn-info:hover { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #fff; + background-color: #269abc; + border-color: #1b6d85; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:focus, +.btn-warning.focus { + color: #fff; + background-color: #ec971f; + border-color: #985f0d; +} +.btn-warning:hover { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #fff; + background-color: #d58512; + border-color: #985f0d; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:focus, +.btn-danger.focus { + color: #fff; + background-color: #c9302c; + border-color: #761c19; +} +.btn-danger:hover { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #fff; + background-color: #ac2925; + border-color: #761c19; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #337ab7; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #337ab7; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #337ab7; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #337ab7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-default .btn-link { + color: #777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #9d9d9d; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.navbar-inverse .btn-link { + color: #9d9d9d; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #337ab7; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + z-index: 3; + color: #23527c; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #fff; + cursor: default; + background-color: #337ab7; + border-color: #337ab7; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; + line-height: 1.3333333; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #337ab7; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #286090; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: #777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge, +.btn-group-xs > .btn .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #337ab7; + background-color: #fff; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding-top: 30px; + padding-bottom: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron, +.container-fluid .jumbotron { + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: border .2s ease-in-out; + -o-transition: border .2s ease-in-out; + transition: border .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #337ab7; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} +.media-object.img-thumbnail { + max-width: none; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} +.media-middle { + vertical-align: middle; +} +.media-bottom { + vertical-align: bottom; +} +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item, +button.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + color: #555; + text-decoration: none; + background-color: #f5f5f5; +} +button.list-group-item { + width: 100%; + text-align: left; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + color: #777; + cursor: not-allowed; + background-color: #eee; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #c7ddef; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success, +button.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +button.list-group-item-success:hover, +a.list-group-item-success:focus, +button.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +button.list-group-item-success.active, +a.list-group-item-success.active:hover, +button.list-group-item-success.active:hover, +a.list-group-item-success.active:focus, +button.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info, +button.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +button.list-group-item-info:hover, +a.list-group-item-info:focus, +button.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +button.list-group-item-info.active, +a.list-group-item-info.active:hover, +button.list-group-item-info.active:hover, +a.list-group-item-info.active:focus, +button.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning, +button.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +button.list-group-item-warning:hover, +a.list-group-item-warning:focus, +button.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +button.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus, +button.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger, +button.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +button.list-group-item-danger:hover, +a.list-group-item-danger:focus, +button.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +button.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus, +button.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-right: 15px; + padding-left: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #337ab7; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; +} +.panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #fff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} +.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + min-height: 16.42857143px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + filter: alpha(opacity=0); + opacity: 0; + + line-break: auto; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + right: 5px; + bottom: 0; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-style: normal; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + + line-break: auto; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} +.popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: -o-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: 0; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + margin-top: -10px; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + font-family: serif; + line-height: 1; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -15px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -15px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.css.map b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.css.map new file mode 100644 index 0000000..9f60ed2 --- /dev/null +++ b/OpenAuth.Identity/wwwroot/lib/bootstrap/css/bootstrap.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/mixins/reset-text.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"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,iBAAA;CHsR9C;AGrRmC;EAAW,iBAAA;CHwR9C;AGvRmC;EAAW,iBAAA;CH0R9C;AGzRmC;EAAW,iBAAA;CH4R9C;AG3RmC;EAAW,iBAAA;CH8R9C;AG7RmC;EAAW,iBAAA;CHgS9C;AG/RmC;EAAW,iBAAA;CHkS9C;AGjSmC;EAAW,iBAAA;CHoS9C;AGnSmC;EAAW,iBAAA;CHsS9C;AGrSmC;EAAW,iBAAA;CHwS9C;AGvSmC;EAAW,iBAAA;CH0S9C;AGzSmC;EAAW,iBAAA;CH4S9C;AG3SmC;EAAW,iBAAA;CH8S9C;AG7SmC;EAAW,iBAAA;CHgT9C;AG/SmC;EAAW,iBAAA;CHkT9C;AGjTmC;EAAW,iBAAA;CHoT9C;AGnTmC;EAAW,iBAAA;CHsT9C;AGrTmC;EAAW,iBAAA;CHwT9C;AGvTmC;EAAW,iBAAA;CH0T9C;AGzTmC;EAAW,iBAAA;CH4T9C;AG3TmC;EAAW,iBAAA;CH8T9C;AG7TmC;EAAW,iBAAA;CHgU9C;AG/TmC;EAAW,iBAAA;CHkU9C;AGjUmC;EAAW,iBAAA;CHoU9C;AGnUmC;EAAW,iBAAA;CHsU9C;AGrUmC;EAAW,iBAAA;CHwU9C;AGvUmC;EAAW,iBAAA;CH0U9C;AGzUmC;EAAW,iBAAA;CH4U9C;AG3UmC;EAAW,iBAAA;CH8U9C;AG7UmC;EAAW,iBAAA;CHgV9C;AG/UmC;EAAW,iBAAA;CHkV9C;AGjVmC;EAAW,iBAAA;CHoV9C;AGnVmC;EAAW,iBAAA;CHsV9C;AGrVmC;EAAW,iBAAA;CHwV9C;AGvVmC;EAAW,iBAAA;CH0V9C;AGzVmC;EAAW,iBAAA;CH4V9C;AG3VmC;EAAW,iBAAA;CH8V9C;AG7VmC;EAAW,iBAAA;CHgW9C;AG/VmC;EAAW,iBAAA;CHkW9C;AGjWmC;EAAW,iBAAA;CHoW9C;AGnWmC;EAAW,iBAAA;CHsW9C;AGrWmC;EAAW,iBAAA;CHwW9C;AGvWmC;EAAW,iBAAA;CH0W9C;AGzWmC;EAAW,iBAAA;CH4W9C;AG3WmC;EAAW,iBAAA;CH8W9C;AG7WmC;EAAW,iBAAA;CHgX9C;AG/WmC;EAAW,iBAAA;CHkX9C;AGjXmC;EAAW,iBAAA;CHoX9C;AGnXmC;EAAW,iBAAA;CHsX9C;AGrXmC;EAAW,iBAAA;CHwX9C;AGvXmC;EAAW,iBAAA;CH0X9C;AGzXmC;EAAW,iBAAA;CH4X9C;AG3XmC;EAAW,iBAAA;CH8X9C;AG7XmC;EAAW,iBAAA;CHgY9C;AG/XmC;EAAW,iBAAA;CHkY9C;AGjYmC;EAAW,iBAAA;CHoY9C;AGnYmC;EAAW,iBAAA;CHsY9C;AGrYmC;EAAW,iBAAA;CHwY9C;AGvYmC;EAAW,iBAAA;CH0Y9C;AGzYmC;EAAW,iBAAA;CH4Y9C;AG3YmC;EAAW,iBAAA;CH8Y9C;AG7YmC;EAAW,iBAAA;CHgZ9C;AG/YmC;EAAW,iBAAA;CHkZ9C;AGjZmC;EAAW,iBAAA;CHoZ9C;AGnZmC;EAAW,iBAAA;CHsZ9C;AGrZmC;EAAW,iBAAA;CHwZ9C;AGvZmC;EAAW,iBAAA;CH0Z9C;AGzZmC;EAAW,iBAAA;CH4Z9C;AG3ZmC;EAAW,iBAAA;CH8Z9C;AG7ZmC;EAAW,iBAAA;CHga9C;AG/ZmC;EAAW,iBAAA;CHka9C;AGjamC;EAAW,iBAAA;CHoa9C;AGnamC;EAAW,iBAAA;CHsa9C;AGramC;EAAW,iBAAA;CHwa9C;AGvamC;EAAW,iBAAA;CH0a9C;AGzamC;EAAW,iBAAA;CH4a9C;AG3amC;EAAW,iBAAA;CH8a9C;AG7amC;EAAW,iBAAA;CHgb9C;AG/amC;EAAW,iBAAA;CHkb9C;AGjbmC;EAAW,iBAAA;CHob9C;AGnbmC;EAAW,iBAAA;CHsb9C;AGrbmC;EAAW,iBAAA;CHwb9C;AGvbmC;EAAW,iBAAA;CH0b9C;AGzbmC;EAAW,iBAAA;CH4b9C;AG3bmC;EAAW,iBAAA;CH8b9C;AG7bmC;EAAW,iBAAA;CHgc9C;AG/bmC;EAAW,iBAAA;CHkc9C;AGjcmC;EAAW,iBAAA;CHoc9C;AGncmC;EAAW,iBAAA;CHsc9C;AGrcmC;EAAW,iBAAA;CHwc9C;AGvcmC;EAAW,iBAAA;CH0c9C;AGzcmC;EAAW,iBAAA;CH4c9C;AG3cmC;EAAW,iBAAA;CH8c9C;AG7cmC;EAAW,iBAAA;CHgd9C;AG/cmC;EAAW,iBAAA;CHkd9C;AGjdmC;EAAW,iBAAA;CHod9C;AGndmC;EAAW,iBAAA;CHsd9C;AGrdmC;EAAW,iBAAA;CHwd9C;AGvdmC;EAAW,iBAAA;CH0d9C;AGzdmC;EAAW,iBAAA;CH4d9C;AG3dmC;EAAW,iBAAA;CH8d9C;AG7dmC;EAAW,iBAAA;CHge9C;AG/dmC;EAAW,iBAAA;CHke9C;AGjemC;EAAW,iBAAA;CHoe9C;AGnemC;EAAW,iBAAA;CHse9C;AGremC;EAAW,iBAAA;CHwe9C;AGvemC;EAAW,iBAAA;CH0e9C;AGzemC;EAAW,iBAAA;CH4e9C;AG3emC;EAAW,iBAAA;CH8e9C;AG7emC;EAAW,iBAAA;CHgf9C;AG/emC;EAAW,iBAAA;CHkf9C;AGjfmC;EAAW,iBAAA;CHof9C;AGnfmC;EAAW,iBAAA;CHsf9C;AGrfmC;EAAW,iBAAA;CHwf9C;AGvfmC;EAAW,iBAAA;CH0f9C;AGzfmC;EAAW,iBAAA;CH4f9C;AG3fmC;EAAW,iBAAA;CH8f9C;AG7fmC;EAAW,iBAAA;CHggB9C;AG/fmC;EAAW,iBAAA;CHkgB9C;AGjgBmC;EAAW,iBAAA;CHogB9C;AGngBmC;EAAW,iBAAA;CHsgB9C;AGrgBmC;EAAW,iBAAA;CHwgB9C;AGvgBmC;EAAW,iBAAA;CH0gB9C;AGzgBmC;EAAW,iBAAA;CH4gB9C;AG3gBmC;EAAW,iBAAA;CH8gB9C;AG7gBmC;EAAW,iBAAA;CHghB9C;AG/gBmC;EAAW,iBAAA;CHkhB9C;AGjhBmC;EAAW,iBAAA;CHohB9C;AGnhBmC;EAAW,iBAAA;CHshB9C;AGrhBmC;EAAW,iBAAA;CHwhB9C;AGvhBmC;EAAW,iBAAA;CH0hB9C;AGzhBmC;EAAW,iBAAA;CH4hB9C;AG3hBmC;EAAW,iBAAA;CH8hB9C;AG7hBmC;EAAW,iBAAA;CHgiB9C;AG/hBmC;EAAW,iBAAA;CHkiB9C;AGjiBmC;EAAW,iBAAA;CHoiB9C;AGniBmC;EAAW,iBAAA;CHsiB9C;AGriBmC;EAAW,iBAAA;CHwiB9C;AGviBmC;EAAW,iBAAA;CH0iB9C;AGziBmC;EAAW,iBAAA;CH4iB9C;AG3iBmC;EAAW,iBAAA;CH8iB9C;AG7iBmC;EAAW,iBAAA;CHgjB9C;AG/iBmC;EAAW,iBAAA;CHkjB9C;AGjjBmC;EAAW,iBAAA;CHojB9C;AGnjBmC;EAAW,iBAAA;CHsjB9C;AGrjBmC;EAAW,iBAAA;CHwjB9C;AGvjBmC;EAAW,iBAAA;CH0jB9C;AGzjBmC;EAAW,iBAAA;CH4jB9C;AG3jBmC;EAAW,iBAAA;CH8jB9C;AG7jBmC;EAAW,iBAAA;CHgkB9C;AG/jBmC;EAAW,iBAAA;CHkkB9C;AGjkBmC;EAAW,iBAAA;CHokB9C;AGnkBmC;EAAW,iBAAA;CHskB9C;AGrkBmC;EAAW,iBAAA;CHwkB9C;AGvkBmC;EAAW,iBAAA;CH0kB9C;AGzkBmC;EAAW,iBAAA;CH4kB9C;AG3kBmC;EAAW,iBAAA;CH8kB9C;AG7kBmC;EAAW,iBAAA;CHglB9C;AG/kBmC;EAAW,iBAAA;CHklB9C;AGjlBmC;EAAW,iBAAA;CHolB9C;AGnlBmC;EAAW,iBAAA;CHslB9C;AGrlBmC;EAAW,iBAAA;CHwlB9C;AGvlBmC;EAAW,iBAAA;CH0lB9C;AGzlBmC;EAAW,iBAAA;CH4lB9C;AG3lBmC;EAAW,iBAAA;CH8lB9C;AG7lBmC;EAAW,iBAAA;CHgmB9C;AG/lBmC;EAAW,iBAAA;CHkmB9C;AGjmBmC;EAAW,iBAAA;CHomB9C;AGnmBmC;EAAW,iBAAA;CHsmB9C;AGrmBmC;EAAW,iBAAA;CHwmB9C;AGvmBmC;EAAW,iBAAA;CH0mB9C;AGzmBmC;EAAW,iBAAA;CH4mB9C;AG3mBmC;EAAW,iBAAA;CH8mB9C;AG7mBmC;EAAW,iBAAA;CHgnB9C;AG/mBmC;EAAW,iBAAA;CHknB9C;AGjnBmC;EAAW,iBAAA;CHonB9C;AGnnBmC;EAAW,iBAAA;CHsnB9C;AGrnBmC;EAAW,iBAAA;CHwnB9C;AGvnBmC;EAAW,iBAAA;CH0nB9C;AGznBmC;EAAW,iBAAA;CH4nB9C;AG3nBmC;EAAW,iBAAA;CH8nB9C;AG7nBmC;EAAW,iBAAA;CHgoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AG/nBmC;EAAW,iBAAA;CHkoB9C;AGjoBmC;EAAW,iBAAA;CHooB9C;AGnoBmC;EAAW,iBAAA;CHsoB9C;AGroBmC;EAAW,iBAAA;CHwoB9C;AGvoBmC;EAAW,iBAAA;CH0oB9C;AGzoBmC;EAAW,iBAAA;CH4oB9C;AG3oBmC;EAAW,iBAAA;CH8oB9C;AG7oBmC;EAAW,iBAAA;CHgpB9C;AG/oBmC;EAAW,iBAAA;CHkpB9C;AGjpBmC;EAAW,iBAAA;CHopB9C;AGnpBmC;EAAW,iBAAA;CHspB9C;AGrpBmC;EAAW,iBAAA;CHwpB9C;AGvpBmC;EAAW,iBAAA;CH0pB9C;AGzpBmC;EAAW,iBAAA;CH4pB9C;AG3pBmC;EAAW,iBAAA;CH8pB9C;AG7pBmC;EAAW,iBAAA;CHgqB9C;AG/pBmC;EAAW,iBAAA;CHkqB9C;AGjqBmC;EAAW,iBAAA;CHoqB9C;AGnqBmC;EAAW,iBAAA;CHsqB9C;AGrqBmC;EAAW,iBAAA;CHwqB9C;AGvqBmC;EAAW,iBAAA;CH0qB9C;AGzqBmC;EAAW,iBAAA;CH4qB9C;AG3qBmC;EAAW,iBAAA;CH8qB9C;AG7qBmC;EAAW,iBAAA;CHgrB9C;AG/qBmC;EAAW,iBAAA;CHkrB9C;AGjrBmC;EAAW,iBAAA;CHorB9C;AGnrBmC;EAAW,iBAAA;CHsrB9C;AGrrBmC;EAAW,iBAAA;CHwrB9C;AGvrBmC;EAAW,iBAAA;CH0rB9C;AGzrBmC;EAAW,iBAAA;CH4rB9C;AG3rBmC;EAAW,iBAAA;CH8rB9C;AG7rBmC;EAAW,iBAAA;CHgsB9C;AG/rBmC;EAAW,iBAAA;CHksB9C;AGjsBmC;EAAW,iBAAA;CHosB9C;AGnsBmC;EAAW,iBAAA;CHssB9C;AGrsBmC;EAAW,iBAAA;CHwsB9C;AGvsBmC;EAAW,iBAAA;CH0sB9C;AGzsBmC;EAAW,iBAAA;CH4sB9C;AG3sBmC;EAAW,iBAAA;CH8sB9C;AG7sBmC;EAAW,iBAAA;CHgtB9C;AG/sBmC;EAAW,iBAAA;CHktB9C;AGjtBmC;EAAW,iBAAA;CHotB9C;AGntBmC;EAAW,iBAAA;CHstB9C;AGrtBmC;EAAW,iBAAA;CHwtB9C;AGvtBmC;EAAW,iBAAA;CH0tB9C;AGztBmC;EA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DH;AezkDC;EACE,oBAAA;Cf2kDH;Ae5kDC;EACE,WAAA;Cf8kDH;Ae/kDC;EACE,oBAAA;CfilDH;AellDC;EACE,mBAAA;CfolDH;AehlDC;EACE,YAAA;CfklDH;AelmDC;EACE,WAAA;CfomDH;AermDC;EACE,mBAAA;CfumDH;AexmDC;EACE,mBAAA;Cf0mDH;Ae3mDC;EACE,UAAA;Cf6mDH;Ae9mDC;EACE,mBAAA;CfgnDH;AejnDC;EACE,mBAAA;CfmnDH;AepnDC;EACE,UAAA;CfsnDH;AevnDC;EACE,mBAAA;CfynDH;Ae1nDC;EACE,mBAAA;Cf4nDH;Ae7nDC;EACE,UAAA;Cf+nDH;AehoDC;EACE,mBAAA;CfkoDH;AenoDC;EACE,kBAAA;CfqoDH;AejoDC;EACE,WAAA;CfmoDH;AernDC;EACE,kBAAA;CfunDH;AexnDC;EACE,0BAAA;Cf0nDH;Ae3nDC;EACE,0BAAA;Cf6nDH;Ae9nDC;EACE,iBAAA;CfgoDH;AejoDC;EACE,0BAAA;CfmoDH;AepoDC;EACE,0BAAA;CfsoDH;AevoDC;EACE,iBAAA;CfyoDH;Ae1oDC;EACE,0BAAA;Cf4oDH;Ae7oDC;EACE,0BAAA;Cf+oDH;AehpDC;EACE,iBAAA;CfkpDH;AenpDC;EACE,0BAAA;CfqpDH;AetpDC;EACE,yBAAA;CfwpDH;AezpDC;EACE,gBAAA;Cf2pDH;Aa3pDD;EElCI;IACE,YAAA;GfgsDH;EezrDD;IACE,YAAA;Gf2rDD;Ee5rDD;IACE,oBAAA;Gf8rDD;Ee/rDD;IACE,oBAAA;GfisDD;EelsDD;IACE,WAAA;GfosDD;EersDD;IACE,oBAAA;GfusDD;EexsDD;IACE,oBAAA;Gf0sDD;Ee3sDD;IACE,WAAA;Gf6sDD;Ee9sDD;IACE,oBAAA;GfgtDD;EejtDD;IACE,oBAAA;GfmtDD;EeptDD;IACE,WAAA;GfstDD;EevtDD;IACE,oBAAA;GfytDD;Ee1tDD;IACE,mBAAA;Gf4tDD;Ee9sDD;IACE,YAAA;GfgtDD;EejtDD;IACE,oBAAA;GfmtDD;EeptDD;IACE,oBAAA;GfstDD;EevtDD;IACE,WAAA;GfytDD;Ee1tDD;IACE,oBAAA;Gf4tDD;Ee7tDD;IACE,oBAAA;Gf+tDD;EehuDD;IACE,WAAA;GfkuDD;EenuDD;IACE,oBAAA;GfquDD;EetuDD;IACE,oBAAA;GfwuDD;EezuDD;IACE,WAAA;Gf2uDD;Ee5uDD;IACE,oBAAA;Gf8uDD;Ee/uDD;IACE,mBAAA;GfivDD;Ee7uDD;IACE,YAAA;Gf+uDD;Ee/vDD;IACE,WAAA;GfiwDD;EelwDD;IACE,mBAAA;GfowDD;EerwDD;IACE,mBAAA;GfuwDD;EexwDD;IACE,UAAA;Gf0wDD;Ee3wDD;IACE,mBAAA;Gf6wDD;Ee9wDD;IACE,mBAAA;GfgxDD;EejxDD;IACE,UAAA;GfmxDD;EepxDD;IACE,mBAAA;GfsxDD;EevxDD;IACE,mBAAA;GfyxDD;Ee1xDD;IACE,UAAA;Gf4xDD;Ee7xDD;IACE,mBAAA;Gf+xDD;EehyDD;IACE,kBAAA;GfkyDD;Ee9xDD;IACE,WAAA;GfgyDD;EelxDD;IACE,kBAAA;GfoxDD;EerxDD;IACE,0BAAA;GfuxDD;EexxDD;IACE,0BAAA;Gf0xDD;Ee3xDD;IACE,iBAAA;Gf6xDD;Ee9xDD;IACE,0BAAA;GfgyDD;EejyDD;IACE,0BAAA;GfmyDD;EepyDD;IACE,iBAAA;GfsyDD;EevyDD;IACE,0BAAA;GfyyDD;Ee1yDD;IACE,0BAAA;Gf4yDD;Ee7yDD;IACE,iBAAA;Gf+yDD;EehzDD;IACE,0BAAA;GfkzDD;EenzDD;IACE,yBAAA;GfqzDD;EetzDD;IACE,gBAAA;GfwzDD;CACF;AahzDD;EE3CI;IACE,YAAA;Gf81DH;Eev1DD;IACE,YAAA;Gfy1DD;Ee11DD;IACE,oBAAA;Gf41DD;Ee71DD;IACE,oBAAA;Gf+1DD;Eeh2DD;IACE,WAAA;Gfk2DD;Een2DD;IACE,oBAAA;Gfq2DD;Eet2DD;IACE,oBAAA;Gfw2DD;Eez2DD;IACE,WAAA;Gf22DD;Ee52DD;IACE,oBAAA;Gf82DD;Ee/2DD;IACE,oBAAA;Gfi3DD;Eel3DD;IACE,WAAA;Gfo3DD;Eer3DD;IACE,oBAAA;Gfu3DD;Eex3DD;IACE,mBAAA;Gf03DD;Ee52DD;IACE,YAAA;Gf82DD;Ee/2DD;IACE,oBAAA;Gfi3DD;Eel3DD;IACE,oBAAA;Gfo3DD;Eer3DD;IACE,WAAA;Gfu3DD;Eex3DD;IACE,oBAAA;Gf03DD;Ee33DD;IACE,oBAAA;Gf63DD;Ee93DD;IACE,WAAA;Gfg4DD;Eej4DD;IACE,oBAAA;Gfm4DD;Eep4DD;IACE,oBAAA;Gfs4DD;Eev4DD;IACE,WAAA;Gfy4DD;Ee14DD;IACE,oBAAA;Gf44DD;Ee74DD;IACE,mBAAA;Gf+4DD;Ee34DD;IACE,YAAA;Gf64DD;Ee75DD;IACE,WAAA;Gf+5DD;Eeh6DD;IACE,mBAAA;Gfk6DD;Een6DD;IACE,mBAAA;Gfq6DD;Eet6DD;IACE,UAAA;Gfw6DD;Eez6DD;IACE,mBAAA;Gf26DD;Ee56DD;IACE,mBAAA;Gf86DD;Ee/6DD;IACE,UAAA;Gfi7DD;Eel7DD;IACE,mBAAA;Gfo7DD;Eer7DD;IACE,mBAAA;Gfu7DD;Eex7DD;IACE,UAAA;Gf07DD;Ee37DD;IACE,mBAAA;Gf67DD;Ee97DD;IACE,kBAAA;Gfg8DD;Ee57DD;IACE,WAAA;Gf87DD;Eeh7DD;IACE,kBAAA;Gfk7DD;Een7DD;IACE,0BAAA;Gfq7DD;Eet7DD;IACE,0BAAA;Gfw7DD;Eez7DD;IACE,iBAAA;Gf27DD;Ee57DD;IACE,0BAAA;Gf87DD;Ee/7DD;IACE,0BAAA;Gfi8DD;Eel8DD;IACE,iBAAA;Gfo8DD;Eer8DD;IACE,0BAAA;Gfu8DD;Eex8DD;IACE,0BAAA;Gf08DD;Ee38DD;IACE,iBAAA;Gf68DD;Ee98DD;IACE,0BAAA;Gfg9DD;Eej9DD;IACE,yBAAA;Gfm9DD;Eep9DD;IACE,gBAAA;Gfs9DD;CACF;Aa38DD;EE9CI;IACE,YAAA;Gf4/DH;Eer/DD;IACE,YAAA;Gfu/DD;Eex/DD;IACE,oBAAA;Gf0/DD;Ee3/DD;IACE,oBAAA;Gf6/DD;Ee9/DD;IACE,WAAA;GfggED;EejgED;IACE,oBAAA;GfmgED;EepgED;IACE,oBAAA;GfsgED;EevgED;IACE,WAAA;GfygED;Ee1gED;IACE,oBAAA;Gf4gED;Ee7gED;IACE,oBAAA;Gf+gED;EehhED;IACE,WAAA;GfkhED;EenhED;IACE,oBAAA;GfqhED;EethED;IACE,mBAAA;GfwhED;Ee1gED;IACE,YAAA;Gf4gED;Ee7gED;IACE,oBAAA;Gf+gED;EehhED;IACE,oBAAA;GfkhED;EenhED;IACE,WAAA;GfqhED;EethED;IACE,oBAAA;GfwhED;EezhED;IACE,oBAAA;Gf2hED;Ee5hED;IACE,WAAA;Gf8hED;Ee/hED;IACE,oBAAA;GfiiED;EeliED;IACE,oBAAA;GfoiED;EeriED;IACE,WAAA;GfuiED;EexiED;IACE,oBAAA;Gf0iED;Ee3iED;IACE,mBAAA;Gf6iED;EeziED;IACE,YAAA;Gf2iED;Ee3jED;IACE,WAAA;Gf6jED;Ee9jED;IACE,mBAAA;GfgkED;EejkED;IACE,mBAAA;GfmkED;EepkED;IACE,UAAA;GfskED;EevkED;IACE,mBAAA;GfykED;Ee1kED;IACE,mBAAA;Gf4kED;Ee7kED;IACE,UAAA;Gf+kED;EehlED;IACE,mBAAA;GfklED;EenlED;IACE,mBAAA;GfqlED;EetlED;IACE,UAAA;GfwlED;EezlED;IACE,mBAAA;Gf2lED;Ee5lED;IACE,kBAAA;Gf8lED;Ee1lED;IACE,WAAA;Gf4lED;Ee9kED;IACE,kBAAA;GfglED;EejlED;IACE,0BAAA;GfmlED;EeplED;IACE,0BAAA;GfslED;EevlED;IACE,iBAAA;GfylED;Ee1lED;IACE,0BAAA;Gf4lED;Ee7lED;IACE,0BAAA;Gf+lED;EehmED;IACE,iBAAA;GfkmED;EenmED;IACE,0BAAA;GfqmED;EetmED;IACE,0BAAA;GfwmED;EezmED;IACE,iBAAA;Gf2mED;Ee5mED;IACE,0BAAA;Gf8mED;Ee/mED;IACE,yBAAA;GfinED;EelnED;IACE,gBAAA;GfonED;CACF;AgBxrED;EACE,8BAAA;ChB0rED;AgBxrED;EACE,iBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;ChB0rED;AgBxrED;EACE,iBAAA;ChB0rED;AgBprED;EACE,YAAA;EACA,gBAAA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","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v3.3.5 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\2a\";\n}\n.glyphicon-plus:before {\n content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #ffffff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #ffffff;\n background-color: #333333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #dddddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #dddddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #dddddd;\n}\n.table .table {\n background-color: #ffffff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #dddddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #ffffff;\n background-image: none;\n border: 1px solid #cccccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n min-height: 34px;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 14.333333px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333333;\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default .badge {\n color: #ffffff;\n background-color: #333333;\n}\n.btn-primary {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #ffffff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #ffffff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #ffffff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #ffffff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.btn-success {\n color: #ffffff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #ffffff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #ffffff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #ffffff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #ffffff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #ffffff;\n}\n.btn-info {\n color: #ffffff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #ffffff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #ffffff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #ffffff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #ffffff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #ffffff;\n}\n.btn-warning {\n color: #ffffff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #ffffff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #ffffff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #ffffff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #ffffff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #ffffff;\n}\n.btn-danger {\n color: #ffffff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #ffffff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #ffffff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #ffffff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #ffffff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #ffffff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #ffffff;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #ffffff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-bottom-left-radius: 4px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #dddddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #dddddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #ffffff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #dddddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #dddddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777777;\n}\n.navbar-default .navbar-link:hover {\n color: #333333;\n}\n.navbar-default .btn-link {\n color: #777777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #cccccc;\n}\n.navbar-inverse {\n background-color: #222222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #ffffff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #ffffff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #ffffff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #ffffff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #cccccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 3;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #dddddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #ffffff;\n border-color: #dddddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #ffffff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #ffffff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #ffffff;\n line-height: 1;\n vertical-align: middle;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #ffffff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n zoom: 1;\n overflow: hidden;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n text-decoration: none;\n color: #555555;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #ffffff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #dddddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #dddddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #dddddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #dddddd;\n}\n.panel-default {\n border-color: #dddddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #dddddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #dddddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #dddddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000000;\n text-shadow: 0 1px 0 #ffffff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #ffffff;\n border: 1px solid #999999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n min-height: 16.42857143px;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 12px;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #ffffff;\n text-align: center;\n background-color: #000000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: normal;\n letter-spacing: normal;\n line-break: auto;\n line-height: 1.42857143;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n white-space: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n font-size: 14px;\n background-color: #ffffff;\n background-clip: padding-box;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #ffffff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #ffffff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #ffffff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #ffffff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #ffffff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n margin-top: -10px;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n line-height: 1;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #ffffff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #ffffff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -15px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -15px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\2a\"; } }\n.glyphicon-plus { &:before { content: \"\\2b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // Default\n outline: thin dotted;\n // WebKit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @grid-float-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: ceil((@gutter / -2));\n margin-right: floor((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: ceil((@grid-gutter-width / 2));\n padding-right: floor((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius; // Note: This has no effect on s in CSS.\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655\n }\n\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848\n//\n// Note that as of 8.3, iOS doesn't support `datetime` or `week`.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n &.form-control {\n line-height: @input-height-base;\n }\n\n &.input-sm,\n .input-group-sm & {\n line-height: @input-height-small;\n }\n\n &.input-lg,\n .input-group-lg & {\n line-height: @input-height-large;\n }\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: @form-group-margin-bottom;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n\n label {\n min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because

    K9as6pFK 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%0AYhJp#77ZeFWy|U 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