From 5590717c39d59338a415227379fe24383b46d1ce Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Mon, 5 Aug 2019 12:09:15 +0300 Subject: [PATCH] Removed project files --- Plan/Class Diagram.xml | 7 - Plan/Database.jpg | Bin 108647 -> 0 bytes Plan/Database.xml | 1 - Plan/PlanEnable.jpg | Bin 84105 -> 0 bytes Plan/api/build.gradle | 41 - .../plan/capability/Capability.java | 70 - .../plan/capability/CapabilityService.java | 76 - .../djrapitops/plan/extension/CallEvents.java | 65 - .../com/djrapitops/plan/extension/Caller.java | 50 - .../plan/extension/DataExtension.java | 93 - .../plan/extension/ElementOrder.java | 77 - .../plan/extension/ExtensionService.java | 84 - .../djrapitops/plan/extension/FormatType.java | 54 - .../com/djrapitops/plan/extension/Group.java | 35 - .../plan/extension/NotReadyException.java | 37 - .../extension/annotation/BooleanProvider.java | 124 - .../extension/annotation/Conditional.java | 54 - .../extension/annotation/DoubleProvider.java | 100 - .../annotation/InvalidateMethod.java | 50 - .../extension/annotation/NumberProvider.java | 112 - .../annotation/PercentageProvider.java | 103 - .../plan/extension/annotation/PluginInfo.java | 70 - .../extension/annotation/StringProvider.java | 112 - .../plan/extension/annotation/Tab.java | 44 - .../plan/extension/annotation/TabInfo.java | 74 - .../plan/extension/annotation/TabOrder.java | 45 - .../extension/annotation/TableProvider.java | 49 - .../extractor/ExtensionExtractor.java | 373 - .../extractor/MethodAnnotations.java | 76 - .../djrapitops/plan/extension/icon/Color.java | 59 - .../plan/extension/icon/Family.java | 41 - .../djrapitops/plan/extension/icon/Icon.java | 107 - .../plan/extension/table/Table.java | 213 - .../djrapitops/plan/query/CommonQueries.java | 64 - .../djrapitops/plan/query/QueryService.java | 163 - .../extractor/ExtensionExtractorTest.java | 257 - Plan/build.gradle | 153 - Plan/bukkit/build.gradle | 23 - .../com/djrapitops/plan/BStatsBukkit.java | 52 - .../plan/BukkitServerShutdownSave.java | 64 - .../main/java/com/djrapitops/plan/Plan.java | 172 - .../djrapitops/plan/PlanBukkitComponent.java | 66 - .../api/events/PlanBukkitEnableEvent.java | 58 - .../commands/RegisterCommandFilter.java | 99 - .../plan/modules/bukkit/BukkitPlanModule.java | 42 - .../bukkit/BukkitServerPropertiesModule.java | 40 - .../bukkit/BukkitSuperClassBindingModule.java | 65 - .../plan/system/database/BukkitDBSystem.java | 68 - .../system/importing/BukkitImportSystem.java | 45 - .../data/BukkitUserImportRefiner.java | 235 - .../importing/importers/BukkitImporter.java | 215 - .../importers/OfflinePlayerImporter.java | 82 - .../properties/BukkitServerProperties.java | 40 - .../listeners/BukkitListenerSystem.java | 92 - .../system/listeners/bukkit/AFKListener.java | 111 - .../system/listeners/bukkit/ChatListener.java | 84 - .../listeners/bukkit/CommandListener.java | 108 - .../listeners/bukkit/DeathEventListener.java | 157 - .../bukkit/GameModeChangeListener.java | 87 - .../bukkit/PlayerOnlineListener.java | 217 - .../listeners/bukkit/WorldChangeListener.java | 81 - .../plan/system/tasks/BukkitTaskSystem.java | 125 - .../tasks/bukkit/BukkitTPSCountTimer.java | 154 - .../tasks/bukkit/PaperTPSCountTimer.java | 77 - .../tasks/bukkit/PingCountTimerBukkit.java | 220 - .../plan/utilities/java/Reflection.java | 432 - .../com/djrapitops/plan/BukkitSystemTest.java | 106 - .../system/listeners/AFKListenerTest.java | 75 - .../java/rules/BukkitComponentMocker.java | 57 - .../utilities/mocks/PlanBukkitMocker.java | 135 - .../org.mockito.plugins.MockMaker | 1 - Plan/bungeecord/build.gradle | 20 - .../com/djrapitops/plan/BStatsBungee.java | 58 - .../java/com/djrapitops/plan/PlanBungee.java | 114 - .../djrapitops/plan/PlanBungeeComponent.java | 66 - .../api/events/PlanBungeeEnableEvent.java | 46 - .../modules/bungee/BungeeCommandModule.java | 32 - .../plan/modules/bungee/BungeePlanModule.java | 42 - .../bungee/BungeeServerPropertiesModule.java | 41 - .../bungee/BungeeSuperClassBindingModule.java | 44 - .../system/info/server/BungeeServerInfo.java | 112 - .../properties/BungeeServerProperties.java | 43 - .../info/server/properties/RedisCheck.java | 36 - .../RedisPlayersOnlineSupplier.java | 34 - .../listeners/BungeeListenerSystem.java | 55 - .../bungee/PlayerOnlineListener.java | 153 - .../plan/system/tasks/BungeeTaskSystem.java | 115 - .../tasks/bungee/BungeeTPSCountTimer.java | 64 - .../tasks/bungee/PingCountTimerBungee.java | 142 - .../com/djrapitops/plan/BungeeSystemTest.java | 142 - .../java/rules/BungeeComponentMocker.java | 57 - .../utilities/mocks/PlanBungeeMocker.java | 131 - .../org.mockito.plugins.MockMaker | 1 - Plan/checkstyle.xml | 97 - Plan/common/build.gradle | 56 - .../java/com/djrapitops/plan/PlanPlugin.java | 48 - .../djrapitops/plan/ServerShutdownSave.java | 135 - .../com/djrapitops/plan/ShutdownHook.java | 67 - .../com/djrapitops/plan/api/CommonAPI.java | 135 - .../java/com/djrapitops/plan/api/PlanAPI.java | 104 - .../plan/api/data/PlayerContainer.java | 52 - .../plan/api/data/ServerContainer.java | 44 - .../DataExtensionMethodCallException.java | 44 - .../plan/api/exceptions/EnableException.java | 33 - .../plan/api/exceptions/ParseException.java | 29 - .../api/exceptions/PassEncryptException.java | 29 - .../api/exceptions/WebUserAuthException.java | 49 - .../connection/BadRequestException.java | 31 - .../connection/ConnectionFailException.java | 35 - .../connection/ForbiddenException.java | 30 - .../connection/GatewayException.java | 31 - .../connection/InternalErrorException.java | 34 - .../connection/NoServersException.java | 37 - .../connection/NotFoundException.java | 30 - .../connection/TransferDatabaseException.java | 31 - .../UnauthorizedServerException.java | 39 - .../exceptions/connection/WebException.java | 71 - .../connection/WebFailException.java | 43 - .../exceptions/database/DBInitException.java | 33 - .../exceptions/database/DBOpException.java | 40 - .../exceptions/database/FatalDBException.java | 24 - .../CapabilityServiceImplementation.java | 61 - .../djrapitops/plan/command/PlanCommand.java | 135 - .../plan/command/PlanProxyCommand.java | 126 - .../plan/command/commands/AnalyzeCommand.java | 159 - .../commands/BungeeSetupToggleCommand.java | 65 - .../plan/command/commands/DevCommand.java | 56 - .../plan/command/commands/DisableCommand.java | 51 - .../plan/command/commands/InfoCommand.java | 90 - .../plan/command/commands/InspectCommand.java | 154 - .../command/commands/ListPlayersCommand.java | 73 - .../command/commands/ListServersCommand.java | 105 - .../plan/command/commands/ManageCommand.java | 82 - .../plan/command/commands/NetworkCommand.java | 73 - .../command/commands/QInspectCommand.java | 175 - .../command/commands/RegisterCommand.java | 195 - .../plan/command/commands/ReloadCommand.java | 75 - .../plan/command/commands/SearchCommand.java | 112 - .../plan/command/commands/WebUserCommand.java | 65 - .../commands/manage/ManageBackupCommand.java | 156 - .../commands/manage/ManageClearCommand.java | 136 - .../manage/ManageConDebugCommand.java | 161 - .../commands/manage/ManageDisableCommand.java | 70 - .../commands/manage/ManageExportCommand.java | 157 - .../commands/manage/ManageHotSwapCommand.java | 105 - .../commands/manage/ManageImportCommand.java | 107 - .../commands/manage/ManageMoveCommand.java | 137 - .../commands/manage/ManageRawDataCommand.java | 79 - .../commands/manage/ManageRemoveCommand.java | 139 - .../commands/manage/ManageRestoreCommand.java | 143 - .../commands/manage/ManageSetupCommand.java | 126 - .../manage/ManageUninstalledCommand.java | 130 - .../commands/webuser/WebCheckCommand.java | 102 - .../commands/webuser/WebDeleteCommand.java | 105 - .../commands/webuser/WebLevelCommand.java | 52 - .../commands/webuser/WebListUsersCommand.java | 92 - .../com/djrapitops/plan/data/WebUser.java | 64 - .../plan/data/container/BaseUser.java | 86 - .../plan/data/container/GeoInfo.java | 127 - .../djrapitops/plan/data/container/Ping.java | 53 - .../plan/data/container/PlayerDeath.java | 53 - .../plan/data/container/PlayerKill.java | 108 - .../plan/data/container/Session.java | 247 - .../djrapitops/plan/data/container/TPS.java | 171 - .../plan/data/container/UserInfo.java | 93 - .../data/container/builders/TPSBuilder.java | 90 - .../plan/data/element/AnalysisContainer.java | 63 - .../plan/data/element/InspectContainer.java | 103 - .../plan/data/element/TableContainer.java | 162 - .../djrapitops/plan/data/plugin/BanData.java | 41 - .../plan/data/plugin/ContainerSize.java | 31 - .../plan/data/plugin/HookHandler.java | 136 - .../plan/data/plugin/PluginData.java | 142 - .../data/plugin/PluginsConfigSection.java | 77 - .../plan/data/store/CachingSupplier.java | 63 - .../com/djrapitops/plan/data/store/Key.java | 97 - .../plan/data/store/PlaceholderKey.java | 51 - .../com/djrapitops/plan/data/store/Type.java | 61 - .../store/containers/AnalysisContainer.java | 561 - .../data/store/containers/DataContainer.java | 152 - .../containers/DynamicDataContainer.java | 107 - .../store/containers/NetworkContainer.java | 295 - .../store/containers/PerServerContainer.java | 120 - .../store/containers/PlayerContainer.java | 49 - .../store/containers/RawDataContainer.java | 108 - .../store/containers/ServerContainer.java | 26 - .../containers/SupplierDataContainer.java | 138 - .../plan/data/store/keys/AnalysisKeys.java | 192 - .../plan/data/store/keys/CommonKeys.java | 71 - .../store/keys/CommonPlaceholderKeys.java | 65 - .../plan/data/store/keys/NetworkKeys.java | 84 - .../plan/data/store/keys/PerServerKeys.java | 62 - .../plan/data/store/keys/PlayerKeys.java | 68 - .../plan/data/store/keys/ServerKeys.java | 68 - .../plan/data/store/keys/SessionKeys.java | 59 - .../data/store/mutators/ActivityIndex.java | 159 - .../store/mutators/CommandUseMutator.java | 51 - .../store/mutators/DateHoldersMutator.java | 82 - .../data/store/mutators/GeoInfoMutator.java | 57 - .../data/store/mutators/MutatorFunctions.java | 51 - .../mutators/NetworkPerServerMutator.java | 64 - .../data/store/mutators/PerServerMutator.java | 116 - .../plan/data/store/mutators/PingMutator.java | 102 - .../data/store/mutators/PlayersMutator.java | 274 - .../store/mutators/PlayersOnlineResolver.java | 56 - .../data/store/mutators/PvpInfoMutator.java | 73 - .../data/store/mutators/RetentionData.java | 111 - .../data/store/mutators/SessionsMutator.java | 234 - .../plan/data/store/mutators/TPSMutator.java | 248 - .../mutators/health/AbstractHealthInfo.java | 191 - .../mutators/health/HealthInformation.java | 166 - .../health/NetworkHealthInformation.java | 187 - .../plan/data/store/objects/DateHolder.java | 33 - .../plan/data/store/objects/DateMap.java | 39 - .../plan/data/store/objects/DateObj.java | 42 - .../plan/data/store/objects/DateSet.java | 36 - .../plan/data/store/objects/Nickname.java | 75 - .../djrapitops/plan/data/time/GMTimes.java | 96 - .../djrapitops/plan/data/time/TimeKeeper.java | 170 - .../djrapitops/plan/data/time/WorldTimes.java | 195 - .../djrapitops/plan/db/AbstractDatabase.java | 45 - .../com/djrapitops/plan/db/DBAccessLock.java | 73 - .../java/com/djrapitops/plan/db/DBType.java | 104 - .../java/com/djrapitops/plan/db/Database.java | 77 - .../java/com/djrapitops/plan/db/H2DB.java | 220 - .../java/com/djrapitops/plan/db/MySQLDB.java | 181 - .../java/com/djrapitops/plan/db/SQLDB.java | 287 - .../java/com/djrapitops/plan/db/SQLiteDB.java | 225 - .../plan/db/access/ExecBatchStatement.java | 37 - .../plan/db/access/ExecStatement.java | 72 - .../djrapitops/plan/db/access/Executable.java | 34 - .../access/HasMoreThanZeroQueryStatement.java | 44 - .../com/djrapitops/plan/db/access/Query.java | 31 - .../plan/db/access/QueryAPIExecutable.java | 50 - .../plan/db/access/QueryAPIQuery.java | 54 - .../plan/db/access/QueryAllStatement.java | 44 - .../plan/db/access/QueryStatement.java | 85 - .../db/access/queries/DataStoreQueries.java | 330 - .../db/access/queries/LargeFetchQueries.java | 149 - .../db/access/queries/LargeStoreQueries.java | 422 - .../queries/PerServerAggregateQueries.java | 190 - .../db/access/queries/PlayerFetchQueries.java | 107 - .../queries/ServerAggregateQueries.java | 163 - .../containers/AllPlayerContainersQuery.java | 174 - .../containers/ContainerFetchQueries.java | 87 - .../containers/NetworkContainerQuery.java | 78 - .../containers/PerServerContainerQuery.java | 121 - .../containers/PlayerContainerQuery.java | 96 - .../containers/ServerContainerQuery.java | 103 - .../ServerPlayerContainersQuery.java | 154 - .../ServerPlayersTableContainersQuery.java | 82 - .../queries/objects/BaseUserQueries.java | 147 - .../queries/objects/GeoInfoQueries.java | 140 - .../queries/objects/NewerConfigQuery.java | 74 - .../queries/objects/NicknameQueries.java | 214 - .../access/queries/objects/PingQueries.java | 158 - .../access/queries/objects/ServerQueries.java | 135 - .../queries/objects/SessionQueries.java | 252 - .../db/access/queries/objects/TPSQueries.java | 158 - .../objects/UserIdentifierQueries.java | 204 - .../queries/objects/UserInfoQueries.java | 185 - .../queries/objects/WebUserQueries.java | 87 - .../queries/objects/WorldTimesQueries.java | 172 - .../queries/schema/H2SchemaQueries.java | 57 - .../queries/schema/MySQLSchemaQueries.java | 160 - .../queries/schema/SQLiteSchemaQueries.java | 61 - .../SessionIDServerIDRelationQuery.java | 53 - .../transactions/BackupCopyTransaction.java | 115 - .../transactions/StoreConfigTransaction.java | 100 - .../StoreServerInformationTransaction.java | 76 - .../db/access/transactions/Transaction.java | 164 - .../commands/RegisterWebUserTransaction.java | 51 - .../commands/RemoveEverythingTransaction.java | 61 - .../commands/RemovePlayerTransaction.java | 85 - .../commands/RemoveWebUserTransaction.java | 50 - .../SetServerAsUninstalledTransaction.java | 60 - .../events/BanStatusTransaction.java | 63 - .../events/CommandStoreTransaction.java | 51 - .../events/GeoInfoStoreTransaction.java | 86 - .../events/KickStoreTransaction.java | 55 - .../events/NicknameStoreTransaction.java | 52 - .../events/OperatorStatusTransaction.java | 62 - .../events/PingStoreTransaction.java | 90 - .../events/PlayerRegisterTransaction.java | 55 - .../PlayerServerRegisterTransaction.java | 46 - .../events/ServerShutdownTransaction.java | 42 - .../events/SessionEndTransaction.java | 40 - .../events/TPSStoreTransaction.java | 69 - .../events/WorldNameStoreTransaction.java | 65 - .../init/CreateIndexTransaction.java | 95 - .../init/CreateTablesTransaction.java | 60 - .../init/OperationCriticalTransaction.java | 39 - .../RemoveDuplicateUserInfoTransaction.java | 50 - .../init/RemoveOldSampledDataTransaction.java | 87 - .../db/patches/BadAFKThresholdValuePatch.java | 65 - .../plan/db/patches/DeleteIPHashesPatch.java | 73 - .../plan/db/patches/DiskUsagePatch.java | 34 - .../ExtensionShowInPlayersTablePatch.java | 38 - .../plan/db/patches/GeoInfoLastUsedPatch.java | 34 - .../db/patches/GeoInfoOptimizationPatch.java | 65 - .../plan/db/patches/IPAnonPatch.java | 133 - .../db/patches/KillsOptimizationPatch.java | 86 - .../plan/db/patches/KillsServerIDPatch.java | 81 - .../db/patches/NicknameLastSeenPatch.java | 133 - .../patches/NicknamesOptimizationPatch.java | 71 - .../com/djrapitops/plan/db/patches/Patch.java | 130 - .../db/patches/PingOptimizationPatch.java | 77 - .../plan/db/patches/SessionAFKTimePatch.java | 34 - .../db/patches/SessionsOptimizationPatch.java | 83 - .../db/patches/TransferTableRemovalPatch.java | 30 - .../db/patches/UserInfoOptimizationPatch.java | 73 - .../plan/db/patches/Version10Patch.java | 137 - .../db/patches/VersionTableRemovalPatch.java | 30 - .../patches/WorldTimesOptimizationPatch.java | 80 - .../db/patches/WorldTimesSeverIDPatch.java | 78 - .../db/patches/WorldsOptimizationPatch.java | 71 - .../plan/db/patches/WorldsServerIDPatch.java | 193 - .../db/sql/parsing/CreateTableParser.java | 137 - .../plan/db/sql/parsing/Insert.java | 46 - .../plan/db/sql/parsing/Select.java | 42 - .../djrapitops/plan/db/sql/parsing/Sql.java | 45 - .../plan/db/sql/parsing/SqlParser.java | 50 - .../plan/db/sql/parsing/Update.java | 42 - .../plan/db/sql/parsing/WhereParser.java | 60 - .../plan/db/sql/tables/CommandUseTable.java | 64 - .../db/sql/tables/ExtensionIconTable.java | 81 - .../ExtensionPlayerTableValueTable.java | 60 - .../sql/tables/ExtensionPlayerValueTable.java | 62 - .../db/sql/tables/ExtensionPluginTable.java | 68 - .../db/sql/tables/ExtensionProviderTable.java | 90 - .../ExtensionServerTableValueTable.java | 62 - .../sql/tables/ExtensionServerValueTable.java | 61 - .../plan/db/sql/tables/ExtensionTabTable.java | 72 - .../tables/ExtensionTableProviderTable.java | 100 - .../plan/db/sql/tables/GeoInfoTable.java | 72 - .../plan/db/sql/tables/KillsTable.java | 101 - .../plan/db/sql/tables/NicknamesTable.java | 71 - .../plan/db/sql/tables/PingTable.java | 68 - .../plan/db/sql/tables/SecurityTable.java | 50 - .../plan/db/sql/tables/ServerTable.java | 78 - .../plan/db/sql/tables/SessionsTable.java | 83 - .../plan/db/sql/tables/SettingsTable.java | 59 - .../plan/db/sql/tables/TPSTable.java | 74 - .../plan/db/sql/tables/UserInfoTable.java | 67 - .../plan/db/sql/tables/UsersTable.java | 59 - .../plan/db/sql/tables/WorldTable.java | 66 - .../plan/db/sql/tables/WorldTimesTable.java | 121 - .../djrapitops/plan/db/tasks/DBCleanTask.java | 147 - .../plan/db/tasks/KeepAliveTask.java | 74 - .../ExtensionServerMethodCallerTask.java | 43 - .../ExtensionServiceImplementation.java | 211 - .../implementation/CallerImplementation.java | 60 - .../implementation/DataProviderExtractor.java | 161 - .../extension/implementation/MethodType.java | 58 - .../implementation/ProviderInformation.java | 92 - .../implementation/TabInformation.java | 85 - .../providers/BooleanDataProvider.java | 79 - .../providers/DataProvider.java | 43 - .../providers/DataProviders.java | 101 - .../providers/DoubleDataProvider.java | 52 - .../providers/MethodWrapper.java | 119 - .../providers/NumberDataProvider.java | 67 - .../providers/PercentageDataProvider.java | 52 - .../providers/StringDataProvider.java | 68 - .../providers/TableDataProvider.java | 69 - .../BooleanProviderValueGatherer.java | 159 - .../providers/gathering/Conditions.java | 42 - ...bleAndPercentageProviderValueGatherer.java | 127 - .../NumberProviderValueGatherer.java | 119 - .../gathering/ProviderValueGatherer.java | 141 - .../StringProviderValueGatherer.java | 121 - .../gathering/TableProviderValueGatherer.java | 124 - .../results/ExtensionBooleanData.java | 41 - .../implementation/results/ExtensionData.java | 33 - .../results/ExtensionDescriptive.java | 87 - .../results/ExtensionDoubleData.java | 47 - .../results/ExtensionInformation.java | 54 - .../results/ExtensionNumberData.java | 54 - .../results/ExtensionStringData.java | 47 - .../results/ExtensionTabData.java | 197 - .../results/ExtensionTableData.java | 106 - .../results/player/ExtensionPlayerData.java | 131 - .../results/server/ExtensionServerData.java | 125 - .../ExtensionAggregateBooleansQuery.java | 199 - .../ExtensionAggregateDoublesQuery.java | 195 - .../ExtensionAggregateNumbersQuery.java | 202 - .../ExtensionAggregatePercentagesQuery.java | 185 - .../queries/ExtensionInformationQueries.java | 115 - .../queries/ExtensionPlayerDataQuery.java | 265 - .../queries/ExtensionPlayerTablesQuery.java | 287 - .../queries/ExtensionServerDataQuery.java | 265 - .../ExtensionServerPlayerDataTableQuery.java | 165 - .../queries/ExtensionServerTablesQuery.java | 284 - .../transactions/StoreIconTransaction.java | 79 - .../transactions/StorePluginTransaction.java | 101 - .../StoreTabInformationTransaction.java | 105 - .../StoreBooleanProviderTransaction.java | 166 - .../StoreDoubleProviderTransaction.java | 150 - .../StoreNumberProviderTransaction.java | 153 - .../StoreStringProviderTransaction.java | 152 - .../StoreTableProviderTransaction.java | 173 - .../RemoveInvalidResultsTransaction.java | 131 - ...edConditionalPlayerResultsTransaction.java | 156 - ...edConditionalServerResultsTransaction.java | 150 - .../StorePlayerBooleanResultTransaction.java | 100 - .../StorePlayerDoubleResultTransaction.java | 100 - .../StorePlayerNumberResultTransaction.java | 100 - ...torePlayerPercentageResultTransaction.java | 100 - .../StorePlayerStringResultTransaction.java | 100 - .../StorePlayerTableResultTransaction.java | 155 - .../StoreServerBooleanResultTransaction.java | 93 - .../StoreServerDoubleResultTransaction.java | 93 - .../StoreServerNumberResultTransaction.java | 93 - ...toreServerPercentageResultTransaction.java | 93 - .../StoreServerStringResultTransaction.java | 93 - .../StoreServerTableResultTransaction.java | 154 - .../plan/extension/table/TableAccessor.java | 81 - .../djrapitops/plan/modules/APFModule.java | 89 - .../djrapitops/plan/modules/FilesModule.java | 42 - .../modules/ProxySuperClassBindingModule.java | 60 - .../ServerSuperClassBindingModule.java | 44 - .../modules/SystemObjectProvidingModule.java | 48 - .../query/CommonQueriesImplementation.java | 105 - .../query/QueryServiceImplementation.java | 115 - .../djrapitops/plan/system/DebugChannels.java | 39 - .../djrapitops/plan/system/HtmlUtilities.java | 72 - .../djrapitops/plan/system/PlanSystem.java | 269 - .../com/djrapitops/plan/system/SubSystem.java | 40 - .../plan/system/afk/AFKTracker.java | 94 - .../plan/system/cache/CacheSystem.java | 70 - .../plan/system/cache/GeolocationCache.java | 217 - .../plan/system/cache/NicknameCache.java | 106 - .../plan/system/cache/SessionCache.java | 104 - .../plan/system/database/DBSystem.java | 125 - .../plan/system/database/ProxyDBSystem.java | 52 - .../databases/operation/FetchOperations.java | 243 - .../databases/sql/operation/SQLFetchOps.java | 196 - .../plan/system/export/ExportSystem.java | 86 - .../plan/system/export/HtmlExport.java | 304 - .../plan/system/export/JSONExport.java | 108 - .../plan/system/export/SpecificExport.java | 155 - .../plan/system/file/FileResource.java | 81 - .../plan/system/file/JarResource.java | 88 - .../plan/system/file/PlanFiles.java | 137 - .../djrapitops/plan/system/file/Resource.java | 61 - .../system/importing/EmptyImportSystem.java | 39 - .../plan/system/importing/ImportSystem.java | 65 - .../importing/data/ServerImportData.java | 103 - .../system/importing/data/UserImportData.java | 314 - .../system/importing/importers/Importer.java | 23 - .../plan/system/info/InfoSystem.java | 170 - .../plan/system/info/ProxyInfoSystem.java | 62 - .../plan/system/info/ServerInfoSystem.java | 61 - .../system/info/connection/ConnectionIn.java | 121 - .../system/info/connection/ConnectionLog.java | 116 - .../system/info/connection/ConnectionOut.java | 201 - .../info/connection/ConnectionSystem.java | 116 - .../connection/InfoRequestPageHandler.java | 95 - .../connection/ProxyConnectionSystem.java | 136 - .../connection/ServerConnectionSystem.java | 173 - .../info/connection/WebExceptionLogger.java | 96 - .../request/CacheAnalysisPageRequest.java | 122 - .../info/request/CacheInspectPageRequest.java | 122 - .../CacheInspectPluginsTabRequest.java | 83 - .../system/info/request/CacheRequest.java | 25 - .../info/request/CheckConnectionRequest.java | 93 - .../request/GenerateAnalysisPageRequest.java | 139 - .../request/GenerateInspectPageRequest.java | 119 - .../GenerateInspectPluginsTabRequest.java | 90 - .../system/info/request/GenerateRequest.java | 25 - .../plan/system/info/request/InfoRequest.java | 35 - .../info/request/InfoRequestFactory.java | 223 - .../request/InfoRequestWithVariables.java | 40 - .../system/info/request/InfoRequests.java | 69 - .../info/request/SaveDBSettingsRequest.java | 130 - .../info/request/SendDBSettingsRequest.java | 96 - .../system/info/request/SetupRequest.java | 26 - .../plan/system/info/request/WideRequest.java | 25 - .../plan/system/info/server/Server.java | 120 - .../plan/system/info/server/ServerInfo.java | 70 - .../system/info/server/ServerInfoFile.java | 67 - .../system/info/server/ServerServerInfo.java | 169 - .../server/properties/ServerProperties.java | 89 - .../plan/system/listeners/ListenerSystem.java | 40 - .../plan/system/locale/LangCode.java | 63 - .../djrapitops/plan/system/locale/Locale.java | 143 - .../plan/system/locale/LocaleFileReader.java | 57 - .../plan/system/locale/LocaleFileWriter.java | 89 - .../plan/system/locale/LocaleSystem.java | 165 - .../plan/system/locale/Message.java | 65 - .../plan/system/locale/lang/CmdHelpLang.java | 79 - .../plan/system/locale/lang/CommandLang.java | 108 - .../system/locale/lang/CommonHtmlLang.java | 59 - .../plan/system/locale/lang/DeepHelpLang.java | 72 - .../system/locale/lang/ErrorPageLang.java | 57 - .../plan/system/locale/lang/GenericLang.java | 48 - .../system/locale/lang/HealthInfoLang.java | 61 - .../plan/system/locale/lang/Lang.java | 30 - .../plan/system/locale/lang/ManageLang.java | 69 - .../system/locale/lang/NetworkPageLang.java | 47 - .../system/locale/lang/PlayerPageLang.java | 97 - .../plan/system/locale/lang/PluginLang.java | 85 - .../system/locale/lang/ServerPageLang.java | 90 - .../system/processing/CriticalCallable.java | 22 - .../system/processing/CriticalRunnable.java | 20 - .../plan/system/processing/Processing.java | 181 - .../processing/processors/Processors.java | 44 - .../processors/info/InfoProcessors.java | 75 - .../info/InspectCacheRequestProcessor.java | 75 - .../info/PlayerPageUpdateProcessor.java | 61 - .../processors/player/MobKillProcessor.java | 57 - .../player/PlayerKillProcessor.java | 67 - .../system/settings/BukkitConfigSystem.java | 83 - .../plan/system/settings/ConfigSystem.java | 129 - .../plan/system/settings/Permissions.java | 68 - .../system/settings/ProxyConfigSystem.java | 80 - .../system/settings/SpongeConfigSystem.java | 76 - .../system/settings/changes/ConfigChange.java | 100 - .../settings/changes/ConfigUpdater.java | 145 - .../plan/system/settings/config/Config.java | 101 - .../system/settings/config/ConfigNode.java | 373 - .../system/settings/config/ConfigReader.java | 255 - .../settings/config/ConfigValueParser.java | 190 - .../system/settings/config/ConfigWriter.java | 172 - .../system/settings/config/PlanConfig.java | 143 - .../settings/config/WorldAliasSettings.java | 187 - .../network/NetworkSettingManager.java | 217 - .../network/ServerSettingsManager.java | 152 - .../settings/paths/DataGatheringSettings.java | 38 - .../settings/paths/DatabaseSettings.java | 42 - .../settings/paths/DisplaySettings.java | 60 - .../system/settings/paths/ExportSettings.java | 43 - .../system/settings/paths/FormatSettings.java | 50 - .../settings/paths/PluginDataSettings.java | 39 - .../system/settings/paths/PluginSettings.java | 44 - .../system/settings/paths/ProxySettings.java | 35 - .../system/settings/paths/TimeSettings.java | 51 - .../settings/paths/WebserverSettings.java | 45 - .../settings/paths/key/BooleanSetting.java | 42 - .../settings/paths/key/IntegerSetting.java | 42 - .../system/settings/paths/key/Setting.java | 85 - .../settings/paths/key/StringListSetting.java | 44 - .../settings/paths/key/StringSetting.java | 42 - .../settings/paths/key/TimeSetting.java | 59 - .../settings/theme/PlanColorScheme.java | 49 - .../plan/system/settings/theme/Theme.java | 127 - .../system/settings/theme/ThemeConfig.java | 95 - .../plan/system/settings/theme/ThemeVal.java | 90 - .../djrapitops/plan/system/status/Status.java | 39 - .../system/tasks/LogsFolderCleanTask.java | 87 - .../system/tasks/PlayersPageRefreshTask.java | 38 - .../plan/system/tasks/ServerTaskSystem.java | 79 - .../plan/system/tasks/TPSCountTimer.java | 128 - .../plan/system/tasks/TaskSystem.java | 55 - .../tasks/proxy/NetworkConfigStoreTask.java | 58 - .../tasks/proxy/NetworkPageRefreshTask.java | 41 - .../system/tasks/server/BootAnalysisTask.java | 61 - .../system/tasks/server/ConfigStoreTask.java | 66 - .../tasks/server/PeriodicAnalysisTask.java | 71 - .../system/update/VersionCheckSystem.java | 115 - .../plan/system/update/VersionInfo.java | 79 - .../plan/system/update/VersionInfoLoader.java | 80 - .../plan/system/webserver/Request.java | 91 - .../plan/system/webserver/RequestHandler.java | 185 - .../plan/system/webserver/RequestTarget.java | 88 - .../system/webserver/ResponseHandler.java | 160 - .../plan/system/webserver/WebServer.java | 293 - .../system/webserver/WebServerSystem.java | 60 - .../system/webserver/auth/Authentication.java | 31 - .../webserver/auth/BasicAuthentication.java | 76 - .../system/webserver/auth/FailReason.java | 53 - .../plan/system/webserver/cache/PageId.java | 64 - .../system/webserver/cache/ResponseCache.java | 118 - .../webserver/pages/DebugPageHandler.java | 55 - .../system/webserver/pages/PageHandler.java | 46 - .../webserver/pages/PlayerPageHandler.java | 116 - .../webserver/pages/PlayersPageHandler.java | 68 - .../webserver/pages/RootPageHandler.java | 71 - .../webserver/pages/ServerPageHandler.java | 141 - .../webserver/pages/TreePageHandler.java | 84 - .../webserver/pages/json/JSONFactory.java | 71 - .../pages/json/PlayersTableJSONHandler.java | 93 - .../webserver/pages/json/RootJSONHandler.java | 50 - .../webserver/response/ByteResponse.java | 60 - .../webserver/response/CSSResponse.java | 33 - .../webserver/response/DefaultResponses.java | 36 - .../webserver/response/FileResponse.java | 54 - .../response/JavaScriptResponse.java | 32 - .../response/PromptAuthorizationResponse.java | 102 - .../webserver/response/RedirectResponse.java | 40 - .../system/webserver/response/Response.java | 140 - .../webserver/response/ResponseCode.java | 45 - .../webserver/response/ResponseFactory.java | 215 - .../webserver/response/ResponseType.java | 41 - .../webserver/response/TextResponse.java | 30 - .../webserver/response/data/JSONResponse.java | 51 - .../response/errors/BadRequestResponse.java | 30 - .../response/errors/ErrorResponse.java | 84 - .../response/errors/ForbiddenResponse.java | 37 - .../response/errors/GatewayErrorResponse.java | 38 - .../errors/InternalErrorResponse.java | 67 - .../response/errors/NotFoundResponse.java | 40 - .../errors/RefreshingAnalysisResponse.java | 38 - .../errors/UnauthorizedServerResponse.java | 37 - .../response/pages/AnalysisPageResponse.java | 28 - .../response/pages/DebugPageResponse.java | 42 - .../response/pages/InspectPageResponse.java | 65 - .../response/pages/NetworkPageResponse.java | 33 - .../response/pages/PageResponse.java | 47 - .../response/pages/PlayersPageResponse.java | 31 - .../response/pages/RawDataResponse.java | 75 - .../response/pages/RawPlayerDataResponse.java | 31 - .../response/pages/RawServerDataResponse.java | 33 - .../parts/InspectPagePluginsContent.java | 113 - .../djrapitops/plan/utilities/Base64Util.java | 75 - .../djrapitops/plan/utilities/MiscUtils.java | 101 - .../plan/utilities/PassEncryptUtil.java | 210 - .../plan/utilities/analysis/Median.java | 71 - .../DateHolderRecentComparator.java | 34 - .../comparators/GeoInfoComparator.java | 26 - .../comparators/LocaleEntryComparator.java | 36 - .../comparators/PieSliceComparator.java | 34 - .../PlayerContainerLastPlayedComparator.java | 38 - .../comparators/PluginDataNameComparator.java | 35 - .../comparators/PointComparator.java | 35 - .../comparators/SessionStartComparator.java | 26 - .../comparators/StringLengthComparator.java | 32 - .../utilities/comparators/TPSComparator.java | 35 - .../comparators/WebUserComparator.java | 35 - .../plan/utilities/file/FileWatcher.java | 133 - .../plan/utilities/file/WatchedFile.java | 62 - .../formatting/DecimalFormatter.java | 42 - .../formatting/EntityNameFormatter.java | 32 - .../plan/utilities/formatting/Formatter.java | 28 - .../plan/utilities/formatting/Formatters.java | 124 - .../formatting/ItemNameFormatter.java | 38 - .../formatting/PercentageFormatter.java | 36 - .../formatting/PlaceholderReplacer.java | 63 - .../formatting/time/ClockFormatter.java | 44 - .../formatting/time/DateFormatter.java | 84 - .../formatting/time/DateHolderFormatter.java | 39 - .../formatting/time/DayFormatter.java | 48 - .../time/ISO8601NoClockFormatter.java | 43 - .../formatting/time/SecondFormatter.java | 48 - .../formatting/time/TimeAmountFormatter.java | 155 - .../formatting/time/YearFormatter.java | 47 - .../djrapitops/plan/utilities/html/Html.java | 198 - .../plan/utilities/html/HtmlStructure.java | 83 - .../plan/utilities/html/HtmlUtils.java | 52 - .../plan/utilities/html/graphs/Graphs.java | 84 - .../plan/utilities/html/graphs/HighChart.java | 28 - .../utilities/html/graphs/ProgressBar.java | 58 - .../plan/utilities/html/graphs/bar/Bar.java | 41 - .../utilities/html/graphs/bar/BarGraph.java | 44 - .../html/graphs/bar/BarGraphFactory.java | 39 - .../html/graphs/bar/GeolocationBarGraph.java | 49 - .../html/graphs/calendar/CalendarFactory.java | 72 - .../html/graphs/calendar/PlayerCalendar.java | 137 - .../html/graphs/calendar/ServerCalendar.java | 133 - .../utilities/html/graphs/line/CPUGraph.java | 32 - .../html/graphs/line/ChunkGraph.java | 32 - .../utilities/html/graphs/line/DiskGraph.java | 32 - .../html/graphs/line/EntityGraph.java | 32 - .../plan/utilities/html/graphs/line/Line.java | 77 - .../utilities/html/graphs/line/LineGraph.java | 72 - .../html/graphs/line/LineGraphFactory.java | 84 - .../utilities/html/graphs/line/PingGraph.java | 66 - .../html/graphs/line/PlayersOnlineGraph.java | 32 - .../utilities/html/graphs/line/Point.java | 65 - .../utilities/html/graphs/line/RamGraph.java | 32 - .../utilities/html/graphs/line/TPSGraph.java | 32 - .../line/alg/DouglasPeuckerAlgorithm.java | 84 - .../graphs/line/alg/ReduceGapTriangles.java | 74 - .../html/graphs/pie/ActivityPie.java | 50 - .../plan/utilities/html/graphs/pie/Pie.java | 43 - .../html/graphs/pie/PieGraphFactory.java | 70 - .../utilities/html/graphs/pie/PieSlice.java | 61 - .../html/graphs/pie/PieWithDrilldown.java | 34 - .../html/graphs/pie/ServerPreferencePie.java | 47 - .../utilities/html/graphs/pie/WorldPie.java | 112 - .../html/graphs/special/PunchCard.java | 154 - .../graphs/special/SpecialGraphFactory.java | 52 - .../html/graphs/special/WorldMap.java | 102 - .../html/graphs/stack/ActivityStackGraph.java | 62 - .../html/graphs/stack/StackDataSet.java | 65 - .../html/graphs/stack/StackGraph.java | 90 - .../html/graphs/stack/StackGraphFactory.java | 55 - .../plan/utilities/html/icon/Color.java | 74 - .../plan/utilities/html/icon/Family.java | 49 - .../plan/utilities/html/icon/Icon.java | 119 - .../plan/utilities/html/icon/Icons.java | 49 - .../utilities/html/pages/AnalysisPage.java | 203 - .../html/pages/AnalysisPluginTabs.java | 212 - .../plan/utilities/html/pages/DebugPage.java | 344 - .../utilities/html/pages/InspectPage.java | 378 - .../html/pages/InspectPluginTab.java | 231 - .../utilities/html/pages/NetworkPage.java | 100 - .../plan/utilities/html/pages/Page.java | 29 - .../utilities/html/pages/PageFactory.java | 196 - .../utilities/html/pages/PlayersPage.java | 93 - .../utilities/html/structure/Accordion.java | 68 - .../html/structure/AccordionElement.java | 115 - .../AccordionElementContentBuilder.java | 81 - .../utilities/html/structure/Accordions.java | 125 - .../AnalysisPluginsTabContentCreator.java | 211 - .../html/structure/NetworkServerBox.java | 117 - .../html/structure/RecentLoginList.java | 133 - .../html/structure/ServerAccordion.java | 163 - .../html/structure/SessionAccordion.java | 252 - .../utilities/html/structure/TabsElement.java | 87 - .../html/tables/CommandUseTable.java | 70 - .../utilities/html/tables/DeathsTable.java | 71 - .../utilities/html/tables/GeoInfoTable.java | 60 - .../utilities/html/tables/HtmlTables.java | 195 - .../utilities/html/tables/KillsTable.java | 72 - .../utilities/html/tables/NicknameTable.java | 64 - .../plan/utilities/html/tables/PingTable.java | 78 - .../html/tables/PlayerSessionTable.java | 85 - .../utilities/html/tables/PlayersTable.java | 126 - .../html/tables/PlayersTableJSONParser.java | 241 - .../html/tables/PluginPlayersTable.java | 132 - .../html/tables/ServerSessionTable.java | 90 - .../plan/utilities/java/ThrowableUtils.java | 53 - .../utilities/java/ThrowingVoidFunction.java | 30 - .../plan/utilities/java/VoidFunction.java | 28 - .../plan/utilities/uuid/UUIDUtility.java | 91 - Plan/common/src/main/resources/Cert.keystore | Bin 2252 -> 0 bytes .../assets/plan/DefaultServerInfoFile.yml | 4 - .../resources/assets/plan/bungeeconfig.yml | 180 - .../src/main/resources/assets/plan/config.yml | 200 - .../assets/plan/locale/locale_CN.txt | 337 - .../assets/plan/locale/locale_DE.txt | 336 - .../assets/plan/locale/locale_EN.txt | 336 - .../assets/plan/locale/locale_FI.txt | 335 - .../assets/plan/locale/locale_FR.txt | 336 - .../assets/plan/locale/locale_FR_old.txt | 118 - .../assets/plan/locale/locale_IT_old.txt | 118 - .../assets/plan/locale/locale_JA.txt | 340 - .../assets/plan/locale/locale_PT-BR.txt | 336 - .../assets/plan/locale/locale_TR.txt | 315 - .../assets/plan/themes/greyscale.yml | 63 - .../resources/assets/plan/themes/mute.yml | 63 - .../resources/assets/plan/themes/pastel.yml | 63 - .../resources/assets/plan/themes/sepia.yml | 63 - .../resources/assets/plan/themes/soft.yml | 63 - .../resources/assets/plan/themes/theme.yml | 63 - .../resources/assets/plan/web/css/main.css | 168 - .../assets/plan/web/css/materialize.css | 415 - .../resources/assets/plan/web/css/style.css | 8042 ----------- .../assets/plan/web/css/style.min.css | 1 - .../assets/plan/web/css/themes/all-themes.css | 900 -- .../plan/web/css/themes/all-themes.min.css | 1 - .../main/resources/assets/plan/web/error.html | 270 - .../resources/assets/plan/web/favicon.ico | Bin 1150 -> 0 bytes .../resources/assets/plan/web/js/admin.js | 463 - .../assets/plan/web/js/charts/activityPie.js | 25 - .../assets/plan/web/js/charts/diskGraph.js | 41 - .../assets/plan/web/js/charts/healthGauge.js | 101 - .../plan/web/js/charts/horizontalBarGraph.js | 40 - .../assets/plan/web/js/charts/lineGraph.js | 36 - .../web/js/charts/onlineActivityCalendar.js | 28 - .../plan/web/js/charts/performanceGraph.js | 72 - .../assets/plan/web/js/charts/playerGraph.js | 38 - .../plan/web/js/charts/playerGraphNoNav.js | 41 - .../assets/plan/web/js/charts/punchCard.js | 30 - .../plan/web/js/charts/resourceGraph.js | 60 - .../assets/plan/web/js/charts/serverPie.js | 53 - .../plan/web/js/charts/sessionCalendar.js | 30 - .../assets/plan/web/js/charts/stackGraph.js | 40 - .../assets/plan/web/js/charts/tpsGraph.js | 54 - .../assets/plan/web/js/charts/worldGraph.js | 60 - .../assets/plan/web/js/charts/worldMap.js | 21 - .../assets/plan/web/js/charts/worldPie.js | 70 - .../main/resources/assets/plan/web/js/demo.js | 68 - .../resources/assets/plan/web/js/helpers.js | 13 - .../resources/assets/plan/web/js/script.js | 1 - .../resources/assets/plan/web/network.html | 656 - .../resources/assets/plan/web/player.html | 932 -- .../resources/assets/plan/web/players.html | 351 - .../plan/web/plugins/animate-css/animate.css | 3340 ----- .../web/plugins/animate-css/animate.min.css | 11 - .../plan/web/plugins/autosize/autosize.js | 262 - .../plan/web/plugins/autosize/autosize.min.js | 6 - .../css/bootstrap-colorpicker.css | 222 - .../css/bootstrap-colorpicker.css.map | 1 - .../css/bootstrap-colorpicker.min.css | 10 - .../css/bootstrap-colorpicker.min.css.map | 1 - .../alpha-horizontal.png | Bin 557 -> 0 bytes .../img/bootstrap-colorpicker/alpha.png | Bin 488 -> 0 bytes .../bootstrap-colorpicker/hue-horizontal.png | Bin 478 -> 0 bytes .../img/bootstrap-colorpicker/hue.png | Bin 504 -> 0 bytes .../img/bootstrap-colorpicker/saturation.png | Bin 4143 -> 0 bytes .../js/bootstrap-colorpicker.js | 1106 -- .../js/bootstrap-colorpicker.min.js | 5 - .../css/bootstrap-material-datetimepicker.css | 49 - .../font/Material-Design-Icons.eot | Bin 102112 -> 0 bytes .../font/Material-Design-Icons.svg | 769 -- .../font/Material-Design-Icons.ttf | Bin 101892 -> 0 bytes .../font/Material-Design-Icons.woff | Bin 101968 -> 0 bytes .../font/Material-Design-Icons.woff2 | Bin 37028 -> 0 bytes .../js/bootstrap-material-datetimepicker.js | 1177 -- .../bootstrap-notify/bootstrap-notify.js | 352 - .../bootstrap-notify/bootstrap-notify.min.js | 1 - .../bootstrap-select/css/bootstrap-select.css | 282 - .../css/bootstrap-select.css.map | 1 - .../css/bootstrap-select.min.css | 6 - .../bootstrap-select/js/bootstrap-select.js | 1735 --- .../js/bootstrap-select.js.map | 1 - .../js/bootstrap-select.min.js | 8 - .../bootstrap-tagsinput-angular.js | 87 - .../bootstrap-tagsinput-angular.min.js | 7 - .../bootstrap-tagsinput-typeahead.css | 49 - .../bootstrap-tagsinput.css | 55 - .../bootstrap-tagsinput.js | 663 - .../bootstrap-tagsinput.min.js | 7 - .../plugins/fullcalendar/fullcalendar.min.css | 5 - .../plugins/fullcalendar/fullcalendar.min.js | 12 - .../plugins/jquery-cookie/jquery.cookie.js | 117 - .../plugins/jquery-countto/jquery.countTo.js | 130 - .../inputmask/inputmask.date.extensions.js | 515 - .../inputmask.dependencyLib.jquery.js | 12 - .../inputmask/inputmask.extensions.js | 93 - .../jquery-inputmask/inputmask/inputmask.js | 1465 -- .../inputmask/inputmask.numeric.extensions.js | 379 - .../inputmask/inputmask.phone.extensions.js | 52 - .../inputmask/inputmask.regex.extensions.js | 115 - .../inputmask/jquery.inputmask.js | 60 - .../jquery.inputmask.bundle.js | 2617 ---- .../plugins/jquery-knob/jquery.knob.min.js | 1 - .../jquery-slimscroll/jquery.slimscroll.js | 443 - .../jquery-spinner/css/bootstrap-spinner.css | 61 - .../css/bootstrap-spinner.css.map | 1 - .../css/bootstrap-spinner.min.css | 1 - .../jquery-spinner/js/jquery.spinner.js | 255 - .../jquery-spinner/js/jquery.spinner.min.js | 6 - .../web/plugins/jquery-steps/jquery.steps.css | 382 - .../web/plugins/jquery-steps/jquery.steps.js | 2040 --- .../plugins/jquery-steps/jquery.steps.min.js | 6 - .../assets/plan/web/plugins/jquery/jquery.js | 11006 ---------------- .../plan/web/plugins/jquery/jquery.min.js | 5 - .../plan/web/plugins/jquery/jquery.min.map | 1 - .../css/material-design-iconic-font.css | 5166 -------- .../css/material-design-iconic-font.min.css | 1 - .../fonts/Material-Design-Iconic-Font.eot | Bin 42495 -> 0 bytes .../fonts/Material-Design-Iconic-Font.svg | 787 -- .../fonts/Material-Design-Iconic-Font.ttf | Bin 99212 -> 0 bytes .../fonts/Material-Design-Iconic-Font.woff | Bin 50312 -> 0 bytes .../fonts/Material-Design-Iconic-Font.woff2 | Bin 38384 -> 0 bytes .../materialize-css/css/materialize.css | 8461 ------------ .../materialize-css/css/materialize.min.css | 16 - .../plugins/materialize-css/js/materialize.js | 8137 ------------ .../materialize-css/js/materialize.min.js | 10 - .../assets/plan/web/plugins/momentjs/ender.js | 1 - .../plan/web/plugins/momentjs/moment.js | 4184 ------ .../plan/web/plugins/momentjs/package.js | 11 - .../plugins/multi-select/css/multi-select.css | 93 - .../web/plugins/multi-select/img/switch.png | Bin 540 -> 0 bytes .../multi-select/js/jquery.multi-select.js | 536 - .../web/plugins/nestable/jquery-nestable.css | 247 - .../web/plugins/nestable/jquery.nestable.js | 484 - .../plan/web/plugins/node-waves/waves.css | 136 - .../plan/web/plugins/node-waves/waves.js | 582 - .../plan/web/plugins/node-waves/waves.min.css | 8 - .../plan/web/plugins/node-waves/waves.min.js | 10 - .../web/plugins/node-waves/waves.min.js.map | 1 - .../plan/web/plugins/nouislider/nouislider.js | 1959 --- .../web/plugins/nouislider/nouislider.min.css | 4 - .../web/plugins/nouislider/nouislider.min.js | 3 - .../assets/plan/web/plugins/waitme/img.svg | 1 - .../assets/plan/web/plugins/waitme/waitMe.css | 227 - .../assets/plan/web/plugins/waitme/waitMe.js | 245 - .../plan/web/plugins/waitme/waitMe.min.css | 6 - .../plan/web/plugins/waitme/waitMe.min.js | 12 - .../resources/assets/plan/web/server.html | 1586 --- Plan/common/src/main/resources/bungee.yml | 9 - Plan/common/src/main/resources/plugin.yml | 121 - .../com/djrapitops/plan/ShutdownSaveTest.java | 157 - .../djrapitops/plan/data/PlayerKillTest.java | 68 - .../plan/data/cache/ResponseCacheTest.java | 60 - .../plan/data/container/GeoInfoTest.java | 66 - .../plan/data/container/SessionTest.java | 109 - .../djrapitops/plan/data/store/KeyTest.java | 72 - .../containers/SupplierDataContainerTest.java | 114 - .../data/store/mutators/TPSMutatorTest.java | 160 - .../formatting/DecimalFormatterTest.java | 67 - .../TimeAmountFormatterDefaultTest.java | 145 - .../TimeAmountFormatterExtraZerosTest.java | 143 - .../plan/data/time/GMTimesTest.java | 139 - .../plan/data/time/WorldTimesTest.java | 191 - .../com/djrapitops/plan/db/CommonDBTest.java | 1554 --- .../plan/db/DBPatchH2RegressionTest.java | 136 - .../plan/db/DBPatchMySQLRegressionTest.java | 176 - .../plan/db/DBPatchRegressionTest.java | 96 - .../plan/db/DBPatchSQLiteRegressionTest.java | 123 - .../java/com/djrapitops/plan/db/H2Test.java | 49 - .../com/djrapitops/plan/db/MySQLTest.java | 106 - .../com/djrapitops/plan/db/SQLiteTest.java | 123 - .../transactions/events/PingMedianTest.java | 84 - .../db/sql/parsing/CreateTableParserTest.java | 50 - .../system/cache/GeolocationCacheTest.java | 127 - .../plan/system/cache/SessionCacheTest.java | 59 - .../importing/data/ImportBuilderTest.java | 154 - .../info/request/AnalysisExportTest.java | 113 - .../system/locale/LocaleFileWriterTest.java | 49 - .../plan/system/locale/LocaleSystemTest.java | 32 - .../system/settings/ConfigSettingKeyTest.java | 155 - .../settings/changes/ConfigChangeTest.java | 138 - .../settings/changes/ConfigUpdaterTest.java | 158 - .../settings/config/ConfigNodeTest.java | 377 - .../settings/config/ConfigReaderTest.java | 77 - .../settings/config/ConfigWriterTest.java | 175 - .../system/update/VersionInfoLoaderTest.java | 43 - .../webserver/HTTPSWebServerAuthTest.java | 124 - .../webserver/JSErrorRegressionTest.java | 152 - .../plan/utilities/MiscUtilsTest.java | 113 - .../plan/utilities/PassEncryptTest.java | 57 - .../plan/utilities/analysis/MedianTest.java | 110 - .../utilities/comparators/ComparatorTest.java | 149 - .../plan/utilities/file/FileWatcherTest.java | 80 - .../plan/utilities/html/HtmlTest.java | 64 - .../plan/utilities/html/HtmlUtilsTest.java | 41 - .../html/graphs/line/LineGraphTest.java | 101 - .../html/graphs/special/WorldMapTest.java | 50 - .../html/tables/PlayersTableTest.java | 93 - .../test/java/extension/PrintExtension.java | 43 - .../java/extension/SeleniumExtension.java | 96 - .../src/test/java/rules/ComponentMocker.java | 27 - .../java/rules/PluginComponentMocker.java | 54 - .../src/test/java/rules/SeleniumDriver.java | 86 - .../src/test/java/utilities/CIProperties.java | 32 - .../src/test/java/utilities/FieldFetcher.java | 45 - .../test/java/utilities/HTTPConnector.java | 74 - .../test/java/utilities/OptionalAssert.java | 36 - .../src/test/java/utilities/RandomData.java | 110 - .../test/java/utilities/TestConstants.java | 41 - .../src/test/java/utilities/TestData.java | 189 - .../java/utilities/TestDatabaseCreator.java | 63 - .../test/java/utilities/TestResources.java | 100 - .../utilities/dagger/PlanPluginComponent.java | 59 - .../utilities/dagger/PlanPluginModule.java | 53 - .../dagger/PluginServerPropertiesModule.java | 48 - .../dagger/PluginSuperClassBindingModule.java | 116 - .../src/test/java/utilities/mocks/Mocker.java | 110 - .../utilities/mocks/PlanPluginMocker.java | 96 - .../utilities/mocks/PluginMockComponent.java | 58 - .../java/utilities/mocks/TestProcessing.java | 47 - .../utilities/mocks/objects/TestLogger.java | 37 - .../mocks/objects/TestRunnableFactory.java | 44 - .../resources/config/4.5.2-bungeeconfig.yml | 129 - .../test/resources/config/4.5.2-config.yml | 156 - .../org.mockito.plugins.MockMaker | 1 - Plan/config/checkstyle/checkstyle.xml | 21 - Plan/config/checkstyle/java.header | 2 - Plan/extensions/build.gradle | 32 - .../implementation/ExtensionRegister.java | 105 - Plan/gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 0 bytes Plan/gradle/wrapper/gradle-wrapper.properties | 5 - Plan/gradlew | 188 - Plan/gradlew.bat | 100 - Plan/nbactions.xml | 71 - Plan/plugin/build.gradle | 36 - .../org.mockito.plugins.MockMaker | 1 - Plan/settings.gradle | 10 - Plan/sponge/build.gradle | 17 - .../com/djrapitops/plan/BStatsSponge.java | 51 - .../java/com/djrapitops/plan/PlanSponge.java | 172 - .../djrapitops/plan/PlanSpongeComponent.java | 66 - .../plan/SpongeServerShutdownSave.java | 64 - .../api/events/PlanSpongeEnableEvent.java | 66 - .../plan/modules/sponge/SpongePlanModule.java | 42 - .../sponge/SpongeServerPropertiesModule.java | 40 - .../sponge/SpongeSuperClassBindingModule.java | 70 - .../plan/system/database/SpongeDBSystem.java | 68 - .../plan/system/file/SpongeAssetResource.java | 71 - .../plan/system/file/SpongePlanFiles.java | 46 - .../properties/SpongeServerProperties.java | 43 - .../listeners/SpongeListenerSystem.java | 100 - .../sponge/PlayerOnlineListener.java | 222 - .../listeners/sponge/SpongeAFKListener.java | 109 - .../listeners/sponge/SpongeChatListener.java | 83 - .../sponge/SpongeCommandListener.java | 95 - .../listeners/sponge/SpongeDeathListener.java | 150 - .../sponge/SpongeGMChangeListener.java | 89 - .../sponge/SpongeWorldChangeListener.java | 97 - .../plan/system/tasks/SpongeTaskSystem.java | 117 - .../tasks/sponge/PingCountTimerSponge.java | 138 - .../tasks/sponge/SpongeTPSCountTimer.java | 121 - .../com/djrapitops/plan/SpongeSystemTest.java | 87 - .../java/rules/SpongeComponentMocker.java | 57 - .../utilities/mocks/PlanSpongeMocker.java | 141 - .../org.mockito.plugins.MockMaker | 1 - Plan/velocity/build.gradle | 15 - .../com/djrapitops/plan/PlanVelocity.java | 135 - .../plan/PlanVelocityComponent.java | 66 - .../api/events/PlanVelocityEnableEvent.java | 45 - .../velocity/VelocityCommandModule.java | 33 - .../modules/velocity/VelocityPlanModule.java | 42 - .../VelocityServerPropertiesModule.java | 42 - .../VelocitySuperClassBindingModule.java | 44 - .../info/server/VelocityServerInfo.java | 113 - .../properties/VelocityServerProperties.java | 43 - .../listeners/VelocityListenerSystem.java | 61 - .../velocity/PlayerOnlineListener.java | 158 - .../plan/system/tasks/VelocityTaskSystem.java | 114 - .../velocity/PingCountTimerVelocity.java | 146 - .../tasks/velocity/VelocityTPSCountTimer.java | 64 - .../djrapitops/plan/VelocitySystemTest.java | 71 - .../velocity/PingCountTimerVelocityTest.java | 70 - .../java/rules/VelocityComponentMocker.java | 55 - .../utilities/mocks/PlanVelocityMocker.java | 109 - .../org.mockito.plugins.MockMaker | 1 - PlanPluginBridge/install_dependencies.bat | 1 - PlanPluginBridge/pom.xml | 210 - .../pluginbridge/plan/AbstractBridge.java | 63 - .../djrapitops/pluginbridge/plan/Bridge.java | 12 - .../pluginbridge/plan/BukkitBridge.java | 77 - .../pluginbridge/plan/BungeeBridge.java | 62 - .../pluginbridge/plan/FakeOfflinePlayer.java | 116 - .../djrapitops/pluginbridge/plan/Hook.java | 54 - .../pluginbridge/plan/PluginBridgeModule.java | 66 - .../pluginbridge/plan/SpongeBridge.java | 58 - .../pluginbridge/plan/VelocityBridge.java | 53 - .../plan/buycraft/BuyCraftData.java | 126 - .../plan/buycraft/BuyCraftHook.java | 58 - .../plan/buycraft/ListPaymentRequest.java | 112 - .../plan/buycraft/MoneyStackGraph.java | 142 - .../pluginbridge/plan/buycraft/Payment.java | 74 - .../plan/factions/FactionComparator.java | 40 - .../plan/factions/FactionsAccordion.java | 125 - .../plan/factions/FactionsData.java | 138 - .../plan/factions/FactionsHook.java | 54 - .../pluginbridge/plan/jobs/JobsData.java | 110 - .../pluginbridge/plan/jobs/JobsHook.java | 49 - .../plan/litebans/LiteBansBukkitHook.java | 59 - .../plan/litebans/LiteBansBungeeHook.java | 59 - .../plan/litebans/LiteBansDBObj.java | 66 - .../plan/litebans/LiteBansData.java | 242 - .../litebans/LiteBansDatabaseQueries.java | 144 - .../plan/luckperms/LuckPermsData.java | 139 - .../plan/luckperms/LuckPermsHook.java | 45 - .../placeholderapi/PlaceholderAPIHook.java | 78 - .../plan/placeholderapi/PlanPlaceholders.java | 228 - .../plan/react/ReactDataTable.java | 131 - .../plan/react/ReactDataTask.java | 101 - .../pluginbridge/plan/react/ReactHook.java | 82 - .../pluginbridge/plan/react/ReactValue.java | 54 - .../plan/react/ValueStoringProcessor.java | 61 - .../plan/towny/TownComparator.java | 60 - .../plan/towny/TownsAccordion.java | 115 - .../pluginbridge/plan/towny/TownyData.java | 134 - .../pluginbridge/plan/towny/TownyHook.java | 50 - .../plan/buycraft/ListPaymentRequestTest.java | 19 - 1052 files changed, 164957 deletions(-) delete mode 100644 Plan/Class Diagram.xml delete mode 100644 Plan/Database.jpg delete mode 100644 Plan/Database.xml delete mode 100644 Plan/PlanEnable.jpg delete mode 100644 Plan/api/build.gradle delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/capability/Capability.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/capability/CapabilityService.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/CallEvents.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/Caller.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/DataExtension.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/ElementOrder.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/ExtensionService.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/FormatType.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/Group.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/NotReadyException.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/BooleanProvider.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/Conditional.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/DoubleProvider.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/InvalidateMethod.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/NumberProvider.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/PercentageProvider.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/PluginInfo.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/StringProvider.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/Tab.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TabInfo.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TabOrder.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TableProvider.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/extractor/ExtensionExtractor.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/extractor/MethodAnnotations.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Color.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Family.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Icon.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/extension/table/Table.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/query/CommonQueries.java delete mode 100644 Plan/api/src/main/java/com/djrapitops/plan/query/QueryService.java delete mode 100644 Plan/api/src/test/java/com/djrapitops/plan/extension/extractor/ExtensionExtractorTest.java delete mode 100644 Plan/build.gradle delete mode 100644 Plan/bukkit/build.gradle delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/BStatsBukkit.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitServerShutdownSave.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/Plan.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/PlanBukkitComponent.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/api/events/PlanBukkitEnableEvent.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/command/commands/RegisterCommandFilter.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitPlanModule.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitServerPropertiesModule.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitSuperClassBindingModule.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/BukkitImportSystem.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/data/BukkitUserImportRefiner.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/importers/BukkitImporter.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/importers/OfflinePlayerImporter.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/info/server/properties/BukkitServerProperties.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/AFKListener.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandListener.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/DeathEventListener.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GameModeChangeListener.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/WorldChangeListener.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BukkitTPSCountTimer.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PaperTPSCountTimer.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PingCountTimerBukkit.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/utilities/java/Reflection.java delete mode 100644 Plan/bukkit/src/test/java/com/djrapitops/plan/BukkitSystemTest.java delete mode 100644 Plan/bukkit/src/test/java/com/djrapitops/plan/system/listeners/AFKListenerTest.java delete mode 100644 Plan/bukkit/src/test/java/rules/BukkitComponentMocker.java delete mode 100644 Plan/bukkit/src/test/java/utilities/mocks/PlanBukkitMocker.java delete mode 100644 Plan/bukkit/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 Plan/bungeecord/build.gradle delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/BStatsBungee.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/PlanBungee.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/PlanBungeeComponent.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/api/events/PlanBungeeEnableEvent.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeCommandModule.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeePlanModule.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeServerPropertiesModule.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeSuperClassBindingModule.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisCheck.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisPlayersOnlineSupplier.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/bungee/PingCountTimerBungee.java delete mode 100644 Plan/bungeecord/src/test/java/com/djrapitops/plan/BungeeSystemTest.java delete mode 100644 Plan/bungeecord/src/test/java/rules/BungeeComponentMocker.java delete mode 100644 Plan/bungeecord/src/test/java/utilities/mocks/PlanBungeeMocker.java delete mode 100644 Plan/bungeecord/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 Plan/checkstyle.xml delete mode 100644 Plan/common/build.gradle delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/PlanPlugin.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/ServerShutdownSave.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/ShutdownHook.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/CommonAPI.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/PlanAPI.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/data/PlayerContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/data/ServerContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/DataExtensionMethodCallException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/EnableException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/ParseException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/PassEncryptException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/WebUserAuthException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/BadRequestException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/ConnectionFailException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/ForbiddenException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/GatewayException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/InternalErrorException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/NoServersException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/NotFoundException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/TransferDatabaseException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/UnauthorizedServerException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/WebException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/WebFailException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/DBInitException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/DBOpException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/FatalDBException.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/capability/CapabilityServiceImplementation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/PlanCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/PlanProxyCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/DisableCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/ListPlayersCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageExportCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageUninstalledCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/WebUser.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/container/BaseUser.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/container/Ping.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/container/PlayerDeath.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/container/PlayerKill.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/container/TPS.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/container/UserInfo.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/container/builders/TPSBuilder.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/element/AnalysisContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/element/InspectContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/element/TableContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/plugin/BanData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/plugin/ContainerSize.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/plugin/HookHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/plugin/PluginData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/plugin/PluginsConfigSection.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/Key.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/PlaceholderKey.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/Type.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/DynamicDataContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/NetworkContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/PerServerContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/PlayerContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/RawDataContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/ServerContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/SupplierDataContainer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/CommonKeys.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/CommonPlaceholderKeys.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/NetworkKeys.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/PerServerKeys.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/PlayerKeys.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/ServerKeys.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/ActivityIndex.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/CommandUseMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/DateHoldersMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/GeoInfoMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/MutatorFunctions.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/NetworkPerServerMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PerServerMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PingMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersOnlineResolver.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PvpInfoMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/RetentionData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/AbstractHealthInfo.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/HealthInformation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/NetworkHealthInformation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateHolder.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateMap.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateObj.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateSet.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/Nickname.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/time/GMTimes.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/AbstractDatabase.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/DBAccessLock.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/DBType.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/Database.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/H2DB.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/MySQLDB.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/SQLDB.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/SQLiteDB.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/ExecBatchStatement.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/ExecStatement.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/Executable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/HasMoreThanZeroQueryStatement.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/Query.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAPIExecutable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAPIQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAllStatement.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryStatement.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/DataStoreQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeFetchQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeStoreQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/PerServerAggregateQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/PlayerFetchQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/ServerAggregateQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/AllPlayerContainersQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ContainerFetchQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/NetworkContainerQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PlayerContainerQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerContainerQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayersTableContainersQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/BaseUserQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/GeoInfoQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/NewerConfigQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/NicknameQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/PingQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/ServerQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/TPSQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/UserIdentifierQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/UserInfoQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WebUserQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WorldTimesQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/H2SchemaQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/MySQLSchemaQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/SQLiteSchemaQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/SessionIDServerIDRelationQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/BackupCopyTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/StoreConfigTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/StoreServerInformationTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/Transaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RegisterWebUserTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemoveEverythingTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemovePlayerTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemoveWebUserTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/SetServerAsUninstalledTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/BanStatusTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/CommandStoreTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/GeoInfoStoreTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/KickStoreTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/NicknameStoreTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/OperatorStatusTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PingStoreTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PlayerRegisterTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PlayerServerRegisterTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/ServerShutdownTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/SessionEndTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/TPSStoreTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/WorldNameStoreTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/CreateIndexTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/CreateTablesTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/OperationCriticalTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/RemoveDuplicateUserInfoTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/RemoveOldSampledDataTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/BadAFKThresholdValuePatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/DeleteIPHashesPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/DiskUsagePatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/ExtensionShowInPlayersTablePatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/GeoInfoLastUsedPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/GeoInfoOptimizationPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/IPAnonPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/KillsOptimizationPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/KillsServerIDPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/NicknameLastSeenPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/NicknamesOptimizationPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/Patch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/PingOptimizationPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/SessionAFKTimePatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/SessionsOptimizationPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/TransferTableRemovalPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/UserInfoOptimizationPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/Version10Patch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/VersionTableRemovalPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldTimesOptimizationPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldTimesSeverIDPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldsOptimizationPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldsServerIDPatch.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/CreateTableParser.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Insert.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Select.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Sql.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/SqlParser.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Update.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/WhereParser.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/CommandUseTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionIconTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPlayerTableValueTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPlayerValueTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPluginTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionProviderTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionServerTableValueTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionServerValueTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionTabTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionTableProviderTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/GeoInfoTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/KillsTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/NicknamesTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/PingTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SecurityTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ServerTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SessionsTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SettingsTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/TPSTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/UserInfoTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/UsersTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTimesTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/tasks/DBCleanTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/tasks/KeepAliveTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionServerMethodCallerTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionServiceImplementation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/CallerImplementation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/DataProviderExtractor.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/MethodType.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/ProviderInformation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/TabInformation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/BooleanDataProvider.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DataProvider.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DataProviders.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DoubleDataProvider.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/MethodWrapper.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/NumberDataProvider.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/PercentageDataProvider.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/StringDataProvider.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/TableDataProvider.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/BooleanProviderValueGatherer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/Conditions.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/DoubleAndPercentageProviderValueGatherer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/NumberProviderValueGatherer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/ProviderValueGatherer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/StringProviderValueGatherer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/TableProviderValueGatherer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionBooleanData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionDescriptive.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionDoubleData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionInformation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionNumberData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionStringData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTabData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTableData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/player/ExtensionPlayerData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/server/ExtensionServerData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateBooleansQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateDoublesQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateNumbersQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregatePercentagesQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionInformationQueries.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerDataQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerTablesQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerDataQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerPlayerDataTableQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerTablesQuery.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StoreIconTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StorePluginTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StoreTabInformationTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreBooleanProviderTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreDoubleProviderTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreNumberProviderTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreStringProviderTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreTableProviderTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveInvalidResultsTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalPlayerResultsTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalServerResultsTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerBooleanResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerDoubleResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerNumberResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerPercentageResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerStringResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerTableResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerBooleanResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerDoubleResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerNumberResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerPercentageResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerStringResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerTableResultTransaction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/table/TableAccessor.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/modules/APFModule.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/modules/FilesModule.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/modules/ProxySuperClassBindingModule.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/modules/ServerSuperClassBindingModule.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/modules/SystemObjectProvidingModule.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/query/CommonQueriesImplementation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/query/QueryServiceImplementation.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/DebugChannels.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/HtmlUtilities.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/PlanSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/SubSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/afk/AFKTracker.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/cache/NicknameCache.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/database/DBSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/database/ProxyDBSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/export/ExportSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/export/HtmlExport.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/export/JSONExport.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/export/SpecificExport.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/file/FileResource.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/file/JarResource.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/file/PlanFiles.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/file/Resource.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/importing/EmptyImportSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/importing/ImportSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/importing/data/ServerImportData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/importing/data/UserImportData.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/importing/importers/Importer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/ProxyInfoSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionIn.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionLog.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/InfoRequestPageHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ProxyConnectionSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/WebExceptionLogger.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheAnalysisPageRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPluginsTabRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPluginsTabRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestWithVariables.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequests.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SetupRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/request/WideRequest.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/server/Server.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfoFile.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerServerInfo.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/info/server/properties/ServerProperties.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/listeners/ListenerSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/LangCode.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/Locale.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleFileReader.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleFileWriter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/Message.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CommandLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CommonHtmlLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ErrorPageLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/GenericLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/HealthInfoLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/Lang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ManageLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/NetworkPageLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/PlayerPageLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/PluginLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ServerPageLang.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/processing/CriticalCallable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/processing/CriticalRunnable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/processing/Processing.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/Processors.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InspectCacheRequestProcessor.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/player/MobKillProcessor.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerKillProcessor.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/BukkitConfigSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/ConfigSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/Permissions.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/ProxyConfigSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/SpongeConfigSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/changes/ConfigChange.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/changes/ConfigUpdater.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/Config.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigNode.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigReader.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigValueParser.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigWriter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/PlanConfig.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/WorldAliasSettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettingManager.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/network/ServerSettingsManager.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DataGatheringSettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DatabaseSettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DisplaySettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ExportSettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/FormatSettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/PluginDataSettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/PluginSettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ProxySettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/TimeSettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/WebserverSettings.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/BooleanSetting.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/IntegerSetting.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/Setting.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/StringListSetting.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/StringSetting.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/TimeSetting.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/PlanColorScheme.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/Theme.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeConfig.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeVal.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/status/Status.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/PlayersPageRefreshTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/TPSCountTimer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/TaskSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkConfigStoreTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkPageRefreshTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/ConfigStoreTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionInfo.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionInfoLoader.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/Request.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestTarget.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/WebServer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/WebServerSystem.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/Authentication.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/FailReason.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/cache/PageId.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/cache/ResponseCache.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/RootPageHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/JSONFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/PlayersTableJSONHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/RootJSONHandler.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ByteResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/CSSResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/DefaultResponses.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/RedirectResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/Response.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseCode.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseType.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/TextResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/data/JSONResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/BadRequestResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/GatewayErrorResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/RefreshingAnalysisResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/UnauthorizedServerResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/NetworkPageResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PageResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawDataResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/parts/InspectPagePluginsContent.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/Base64Util.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/PassEncryptUtil.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Median.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/DateHolderRecentComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/GeoInfoComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/LocaleEntryComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PieSliceComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PlayerContainerLastPlayedComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PluginDataNameComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PointComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/SessionStartComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/StringLengthComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/TPSComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/WebUserComparator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/file/FileWatcher.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/file/WatchedFile.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/DecimalFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/EntityNameFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/Formatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/Formatters.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/ItemNameFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/PercentageFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/PlaceholderReplacer.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/ClockFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateHolderFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DayFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/ISO8601NoClockFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/SecondFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/TimeAmountFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/YearFormatter.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/Html.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/Graphs.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/HighChart.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/ProgressBar.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/Bar.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/BarGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/BarGraphFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/GeolocationBarGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/CalendarFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/PlayerCalendar.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/ServerCalendar.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/CPUGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/ChunkGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/DiskGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/EntityGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/Line.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraphFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/PingGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/PlayersOnlineGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/Point.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/RamGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/TPSGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/alg/DouglasPeuckerAlgorithm.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/alg/ReduceGapTriangles.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ActivityPie.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/Pie.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieGraphFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieSlice.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieWithDrilldown.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ServerPreferencePie.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/WorldPie.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/PunchCard.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/SpecialGraphFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/WorldMap.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/ActivityStackGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/StackDataSet.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/StackGraph.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/StackGraphFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/icon/Color.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/icon/Family.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/icon/Icon.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/icon/Icons.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/AnalysisPage.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/AnalysisPluginTabs.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/DebugPage.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPluginTab.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/NetworkPage.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/Page.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/PageFactory.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/PlayersPage.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/Accordion.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/AccordionElement.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/AccordionElementContentBuilder.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/Accordions.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/AnalysisPluginsTabContentCreator.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/NetworkServerBox.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/TabsElement.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/CommandUseTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/DeathsTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/GeoInfoTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/HtmlTables.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/KillsTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/NicknameTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PingTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayerSessionTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTableJSONParser.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PluginPlayersTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/ServerSessionTable.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowableUtils.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowingVoidFunction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/java/VoidFunction.java delete mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/uuid/UUIDUtility.java delete mode 100644 Plan/common/src/main/resources/Cert.keystore delete mode 100644 Plan/common/src/main/resources/assets/plan/DefaultServerInfoFile.yml delete mode 100644 Plan/common/src/main/resources/assets/plan/bungeeconfig.yml delete mode 100644 Plan/common/src/main/resources/assets/plan/config.yml delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_CN.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_DE.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_EN.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_FI.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_FR.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_FR_old.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_IT_old.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_JA.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_PT-BR.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/locale/locale_TR.txt delete mode 100644 Plan/common/src/main/resources/assets/plan/themes/greyscale.yml delete mode 100644 Plan/common/src/main/resources/assets/plan/themes/mute.yml delete mode 100644 Plan/common/src/main/resources/assets/plan/themes/pastel.yml delete mode 100644 Plan/common/src/main/resources/assets/plan/themes/sepia.yml delete mode 100644 Plan/common/src/main/resources/assets/plan/themes/soft.yml delete mode 100644 Plan/common/src/main/resources/assets/plan/themes/theme.yml delete mode 100644 Plan/common/src/main/resources/assets/plan/web/css/main.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/css/materialize.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/css/style.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/css/style.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/css/themes/all-themes.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/css/themes/all-themes.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/error.html delete mode 100644 Plan/common/src/main/resources/assets/plan/web/favicon.ico delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/admin.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/activityPie.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/diskGraph.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/healthGauge.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/horizontalBarGraph.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/lineGraph.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/onlineActivityCalendar.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/performanceGraph.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/playerGraph.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/playerGraphNoNav.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/punchCard.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/resourceGraph.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/serverPie.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/sessionCalendar.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/stackGraph.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/tpsGraph.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/worldGraph.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/worldMap.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/charts/worldPie.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/demo.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/helpers.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/js/script.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/network.html delete mode 100644 Plan/common/src/main/resources/assets/plan/web/player.html delete mode 100644 Plan/common/src/main/resources/assets/plan/web/players.html delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/animate-css/animate.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/animate-css/animate.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/autosize/autosize.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/autosize/autosize.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.css.map delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css.map delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/hue-horizontal.png delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/js/bootstrap-colorpicker.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/js/bootstrap-colorpicker.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-material-datetimepicker/css/bootstrap-material-datetimepicker.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-material-datetimepicker/font/Material-Design-Icons.eot delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-material-datetimepicker/font/Material-Design-Icons.svg delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-material-datetimepicker/font/Material-Design-Icons.ttf delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-material-datetimepicker/font/Material-Design-Icons.woff delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-material-datetimepicker/font/Material-Design-Icons.woff2 delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-material-datetimepicker/js/bootstrap-material-datetimepicker.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-notify/bootstrap-notify.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-notify/bootstrap-notify.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-select/css/bootstrap-select.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-select/css/bootstrap-select.css.map delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-select/css/bootstrap-select.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-select/js/bootstrap-select.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-select/js/bootstrap-select.js.map delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-select/js/bootstrap-select.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-tagsinput/bootstrap-tagsinput-angular.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-tagsinput/bootstrap-tagsinput-angular.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-tagsinput/bootstrap-tagsinput-typeahead.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-tagsinput/bootstrap-tagsinput.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-tagsinput/bootstrap-tagsinput.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-tagsinput/bootstrap-tagsinput.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/fullcalendar/fullcalendar.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/fullcalendar/fullcalendar.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-cookie/jquery.cookie.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-countto/jquery.countTo.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.date.extensions.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.dependencyLib.jquery.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.extensions.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.numeric.extensions.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.phone.extensions.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.regex.extensions.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/jquery.inputmask.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/jquery.inputmask.bundle.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-knob/jquery.knob.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-slimscroll/jquery.slimscroll.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.css.map delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/js/jquery.spinner.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/js/jquery.spinner.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-steps/jquery.steps.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-steps/jquery.steps.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery-steps/jquery.steps.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery/jquery.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery/jquery.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/jquery/jquery.min.map delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/material-design-iconic-font/css/material-design-iconic-font.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/material-design-iconic-font/css/material-design-iconic-font.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/material-design-iconic-font/fonts/Material-Design-Iconic-Font.eot delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/material-design-iconic-font/fonts/Material-Design-Iconic-Font.svg delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/material-design-iconic-font/fonts/Material-Design-Iconic-Font.ttf delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/material-design-iconic-font/fonts/Material-Design-Iconic-Font.woff delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/material-design-iconic-font/fonts/Material-Design-Iconic-Font.woff2 delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/materialize-css/css/materialize.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/materialize-css/css/materialize.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/materialize-css/js/materialize.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/materialize-css/js/materialize.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/momentjs/ender.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/momentjs/moment.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/momentjs/package.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/multi-select/css/multi-select.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/multi-select/img/switch.png delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/multi-select/js/jquery.multi-select.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/nestable/jquery-nestable.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/nestable/jquery.nestable.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/node-waves/waves.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/node-waves/waves.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/node-waves/waves.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/node-waves/waves.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/node-waves/waves.min.js.map delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/nouislider/nouislider.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/nouislider/nouislider.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/nouislider/nouislider.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/waitme/img.svg delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/waitme/waitMe.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/waitme/waitMe.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/waitme/waitMe.min.css delete mode 100644 Plan/common/src/main/resources/assets/plan/web/plugins/waitme/waitMe.min.js delete mode 100644 Plan/common/src/main/resources/assets/plan/web/server.html delete mode 100644 Plan/common/src/main/resources/bungee.yml delete mode 100644 Plan/common/src/main/resources/plugin.yml delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/ShutdownSaveTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/PlayerKillTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/cache/ResponseCacheTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/container/GeoInfoTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/container/SessionTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/store/KeyTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/store/containers/SupplierDataContainerTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/store/mutators/TPSMutatorTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/DecimalFormatterTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterDefaultTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterExtraZerosTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/time/GMTimesTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/data/time/WorldTimesTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/CommonDBTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/DBPatchH2RegressionTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/DBPatchMySQLRegressionTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/DBPatchRegressionTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/DBPatchSQLiteRegressionTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/H2Test.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/MySQLTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/SQLiteTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/access/transactions/events/PingMedianTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/db/sql/parsing/CreateTableParserTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/cache/GeolocationCacheTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/cache/SessionCacheTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/importing/data/ImportBuilderTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/info/request/AnalysisExportTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/locale/LocaleFileWriterTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/locale/LocaleSystemTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/settings/ConfigSettingKeyTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/settings/changes/ConfigChangeTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/settings/changes/ConfigUpdaterTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/settings/config/ConfigNodeTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/settings/config/ConfigReaderTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/settings/config/ConfigWriterTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/update/VersionInfoLoaderTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/webserver/HTTPSWebServerAuthTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/system/webserver/JSErrorRegressionTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/MiscUtilsTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/PassEncryptTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/analysis/MedianTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/comparators/ComparatorTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/file/FileWatcherTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/html/HtmlTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/html/HtmlUtilsTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraphTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/html/graphs/special/WorldMapTest.java delete mode 100644 Plan/common/src/test/java/com/djrapitops/plan/utilities/html/tables/PlayersTableTest.java delete mode 100644 Plan/common/src/test/java/extension/PrintExtension.java delete mode 100644 Plan/common/src/test/java/extension/SeleniumExtension.java delete mode 100644 Plan/common/src/test/java/rules/ComponentMocker.java delete mode 100644 Plan/common/src/test/java/rules/PluginComponentMocker.java delete mode 100644 Plan/common/src/test/java/rules/SeleniumDriver.java delete mode 100644 Plan/common/src/test/java/utilities/CIProperties.java delete mode 100644 Plan/common/src/test/java/utilities/FieldFetcher.java delete mode 100644 Plan/common/src/test/java/utilities/HTTPConnector.java delete mode 100644 Plan/common/src/test/java/utilities/OptionalAssert.java delete mode 100644 Plan/common/src/test/java/utilities/RandomData.java delete mode 100644 Plan/common/src/test/java/utilities/TestConstants.java delete mode 100644 Plan/common/src/test/java/utilities/TestData.java delete mode 100644 Plan/common/src/test/java/utilities/TestDatabaseCreator.java delete mode 100644 Plan/common/src/test/java/utilities/TestResources.java delete mode 100644 Plan/common/src/test/java/utilities/dagger/PlanPluginComponent.java delete mode 100644 Plan/common/src/test/java/utilities/dagger/PlanPluginModule.java delete mode 100644 Plan/common/src/test/java/utilities/dagger/PluginServerPropertiesModule.java delete mode 100644 Plan/common/src/test/java/utilities/dagger/PluginSuperClassBindingModule.java delete mode 100644 Plan/common/src/test/java/utilities/mocks/Mocker.java delete mode 100644 Plan/common/src/test/java/utilities/mocks/PlanPluginMocker.java delete mode 100644 Plan/common/src/test/java/utilities/mocks/PluginMockComponent.java delete mode 100644 Plan/common/src/test/java/utilities/mocks/TestProcessing.java delete mode 100644 Plan/common/src/test/java/utilities/mocks/objects/TestLogger.java delete mode 100644 Plan/common/src/test/java/utilities/mocks/objects/TestRunnableFactory.java delete mode 100644 Plan/common/src/test/resources/config/4.5.2-bungeeconfig.yml delete mode 100644 Plan/common/src/test/resources/config/4.5.2-config.yml delete mode 100644 Plan/common/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 Plan/config/checkstyle/checkstyle.xml delete mode 100644 Plan/config/checkstyle/java.header delete mode 100644 Plan/extensions/build.gradle delete mode 100644 Plan/extensions/src/main/java/com/djrapitops/plan/extension/implementation/ExtensionRegister.java delete mode 100644 Plan/gradle/wrapper/gradle-wrapper.jar delete mode 100644 Plan/gradle/wrapper/gradle-wrapper.properties delete mode 100755 Plan/gradlew delete mode 100644 Plan/gradlew.bat delete mode 100644 Plan/nbactions.xml delete mode 100644 Plan/plugin/build.gradle delete mode 100644 Plan/plugin/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 Plan/settings.gradle delete mode 100644 Plan/sponge/build.gradle delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/BStatsSponge.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/PlanSponge.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/PlanSpongeComponent.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/SpongeServerShutdownSave.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/api/events/PlanSpongeEnableEvent.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/modules/sponge/SpongePlanModule.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/modules/sponge/SpongeServerPropertiesModule.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/modules/sponge/SpongeSuperClassBindingModule.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/database/SpongeDBSystem.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/file/SpongeAssetResource.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/file/SpongePlanFiles.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/info/server/properties/SpongeServerProperties.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/sponge/PlayerOnlineListener.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/tasks/sponge/PingCountTimerSponge.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/system/tasks/sponge/SpongeTPSCountTimer.java delete mode 100644 Plan/sponge/src/test/java/com/djrapitops/plan/SpongeSystemTest.java delete mode 100644 Plan/sponge/src/test/java/rules/SpongeComponentMocker.java delete mode 100644 Plan/sponge/src/test/java/utilities/mocks/PlanSpongeMocker.java delete mode 100644 Plan/sponge/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 Plan/velocity/build.gradle delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/PlanVelocity.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/PlanVelocityComponent.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/api/events/PlanVelocityEnableEvent.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/modules/velocity/VelocityCommandModule.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/modules/velocity/VelocityPlanModule.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/modules/velocity/VelocityServerPropertiesModule.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/modules/velocity/VelocitySuperClassBindingModule.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/system/info/server/VelocityServerInfo.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/system/info/server/properties/VelocityServerProperties.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/system/listeners/VelocityListenerSystem.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/system/listeners/velocity/PlayerOnlineListener.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/system/tasks/VelocityTaskSystem.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/system/tasks/velocity/PingCountTimerVelocity.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/system/tasks/velocity/VelocityTPSCountTimer.java delete mode 100644 Plan/velocity/src/test/java/com/djrapitops/plan/VelocitySystemTest.java delete mode 100644 Plan/velocity/src/test/java/com/djrapitops/plan/system/tasks/velocity/PingCountTimerVelocityTest.java delete mode 100644 Plan/velocity/src/test/java/rules/VelocityComponentMocker.java delete mode 100644 Plan/velocity/src/test/java/utilities/mocks/PlanVelocityMocker.java delete mode 100644 Plan/velocity/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker delete mode 100644 PlanPluginBridge/install_dependencies.bat delete mode 100644 PlanPluginBridge/pom.xml delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/AbstractBridge.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/BukkitBridge.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/BungeeBridge.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/FakeOfflinePlayer.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Hook.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/PluginBridgeModule.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/SpongeBridge.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/VelocityBridge.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/buycraft/BuyCraftData.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/buycraft/BuyCraftHook.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/buycraft/ListPaymentRequest.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/buycraft/MoneyStackGraph.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/buycraft/Payment.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/factions/FactionComparator.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/factions/FactionsAccordion.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/factions/FactionsData.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/factions/FactionsHook.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/jobs/JobsData.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/jobs/JobsHook.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansBukkitHook.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansBungeeHook.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansDBObj.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansData.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/litebans/LiteBansDatabaseQueries.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/luckperms/LuckPermsData.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/luckperms/LuckPermsHook.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlaceholderAPIHook.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/placeholderapi/PlanPlaceholders.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/react/ReactDataTable.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/react/ReactDataTask.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/react/ReactHook.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/react/ReactValue.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/react/ValueStoringProcessor.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/towny/TownComparator.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/towny/TownsAccordion.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/towny/TownyData.java delete mode 100644 PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/towny/TownyHook.java delete mode 100644 PlanPluginBridge/src/test/java/com/djrapitops/pluginbridge/plan/buycraft/ListPaymentRequestTest.java diff --git a/Plan/Class Diagram.xml b/Plan/Class Diagram.xml deleted file mode 100644 index 1b97043a4..000000000 --- a/Plan/Class Diagram.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - 7V1dd9s4zv41Ocdz0R5L8udlPjqZvJtOs006s7t3is3Y2tqWV5Kbyfz6l5REiRIhmxQh2225Z880liVQJkDgAQgCF971+q/byN8uP4Zzsrpw+/O/LrybC9d1B86A/sOuvGVXJtNJdmERBfPsklNeeAz+JvnFfn51F8xJXLkxCcNVEmyrF2fhZkNmSeWaH0Xha/W2l3BVHXXrL/IR++WFx5m/ItJtfwbzZJlfdUbT8ovfSLBY5kNP3FH2xbM/+7qIwt0mH+/C9V7S/2Vfr31OKx83Xvrz8FW45H248K6jMEyyv9Z/XZMVm1s+bfy55I2/64V3tUzWK/rBoX+mX//a8LCj8jD9cRHZJOJwTfTGA4kgmdOJzD+GUbIMF+HGX30or16ls0MYhX51dPJXkPyLXX4/zD/9m3+zSaI34Sv28d85gf+SJHnLJcjfJSG9VI57H4bbnMZLuEny25wJ+Fv57IS7aJb/Gi/nd+JHC5LfxmWA/VLhwXyGbkm4JvT16A0RWflJ8K0qUn4umYvivnJ+6R/5FMPTzRfRTzXdU+9U0+2M3J9wvp3h5GQTPh2dfsJjOhnJJbMh9MIm3BB+7deAvXh6D9nM+R2zlR/HwSy7mN/iaPCtPZ+m7qn4RGXkp+OTuL5cI76NTqbQ+Ot881e7nOrDyt/QK70/SBQHIfvTfT993/9F4m/8GqzpvaTKunRW8pvYZ38VLDZstumskIhe+EaiJKC46jL/ImETejVbBqv5vf8W7tikUK7NvvJPV8swCv6mZH0+RsrUfOopzBLveGRP5ryOSEzveeAMcYpL936c5PfMwtXK38bBc/HCa8qZYHMVJkm45oKV/1ImJNfhKozSCeAwTkMS2G8nf+1l8V+cMTmsy+HygOPg1xJ8uqP82lLAnQP+oIlYDPqSWLyjHy8f7hjhbXDhjlaMM/PgG/1zwf5k39/4iX/tz5bkN38zX1Fu01fjf2UP0IGFZxrI3G3iLYXwNUqBcFWL3CVdtm9xENfo+eJlLYLsZz77MWHezLPWk7/58fKRLnt35K+Z1Kf3lOTyqzmF/jz/ItYa40/y/BjOvpLkkUTf0l+6C/ifOq8ahl8FNoqfNKgEdAFQF4g6L5wLT3789e6m+K2b53grPF4nWlM5dPEkVXUTJ1H4lfBFmSv9F2Gd5pe4GlqRl6RRCcVbfxZsFvfpPTeD8srnfH2xS6/LICGP9Dp7p1fq7DL7QOm9rFKrsgzmc7JJjVvC+Je+OlMi25BORromh1f0/3SFXTMbNqS/65p+dsrP9P/s9ii5Djf09/lBqkUIVVqvJC7nRdQvhR4/rGDeuPJQ0yfOYICgTxxJn0i8XQV1U5LxlnvbTivGrik7UqyRc/IpNd/vHInbnsxtD+Diyn8mq4cwDhJmG72bKLu3xt1jMNAZK1qECQL/XIB/TEWFmw8bNju9XwAFwG+5CeLqPQdVR/bkKlz0HpOIcqTFkx8oyotaPp6E98XQbHW6/aclxYzsR5iTovK7onYshVaiGSiGqNoBkwF1n6WIlJp4xicq6pfc4Guo+4gsgpjCvHv23w0FkNo8DzZBwg2ixsPvUl3C4H9uZj6TF4r1lsza9Ojya0Hpqma0tH8Km00RY4jzCkISXeoiThKIg/BJl3b+oEBWBne6NG+uauRy1KNLhsMigZoWsNId8EuOn4TxJJClPb8loBJ/RguYVZCsC+zdjUA5BWJawC1I7kMW/m6WewvOurPtEzXb7vVdBOvuSdb9w2a3plcellG6fqznfzzP31Hw/B1IFoqtMiNZGICef7q2uS7haAZUHLN0lvit10s/yebN6hAjHVKsURMHDxQbD8O/G1r/Dpt/I8Vlj+HejcBFn2n/ui9RW+/5TcVC1/dXMvoCVqnqF0U6dLJjgkMke/T9+/eG1FJVKLzSQWXYQCcmyRPViy2dOvp0OmiLx+sxOupX+/McFVKL2OwMW63emVaQgSGoFRwesjHSC2OJlRibehfllp6wi/evC2GHr/yu091uvs8h7sZxBHT8zbjBpAmHU9c2ofIcWyR+TCT+rkDUulDcGWJAcXlvNgPYm5dg8cDSxurWyapdRbU7URYFTTDN7zPh+1DefLVg2pB/Q/doYHoo73W9E1T4HjidR8Djp2gnItnnMFwRlpNxElxN7eLvu/VzJUypE0wsqDCNpfwyVpN1tRJU3UqMNBK+6mRA8xvjpAUzxwQzJ8UyQznEzJRiymaLYtqt/WJ1nSeKkQPJFsUY8u+YKEaO6L7L9fZBBHOGobiYJNCrK6eT2LDXaTXXUVFLN0cOLs466jVET0FPH72MIv9NuCEXq5LyQ5iliPK053EVpQz7E5F1B+8fef299zuG9w/yoEwpStkvLAWrmCo1WfuOz28JRylytVWeo5COYzyvQgajpfMYSgI7HMsCy5Mqjh+m5W9TQTaS5fg//5v/sNpR5K9oLeouj8qqVof/g9GwIsjewH0/Goz7w8nE9YbudCDrVwfQryi+gBzXTPMMrTd4PG9wVFODo7HE/8KWVjyDAYIAjOQAJ8OW23y15DgvO4dkIZUipEI5AACyHMEZHNn8f3T+Ac4gyD8EZ5CfepbS/1m2OFunzb4g1aWUHxes4EK09pOnYE0eg82M5MFpMTH+xk+IqZsnj3a5pmhJyJ1AJk8NwnqLQ3278t9I9Lu/Jk/hly93NxJVdlE3BYUlbH+JScRyoZ/CSsY4I9cip/0hfU3mTV/GORdzSiY/fredU/ZL+fJtE+4rr2e+A8Jn8NcoXENzyBmU39b+vfkgTQcGNKlnl56j+hXER62B7krBAzEPUME7EwxM1k3dlovGoMexC1uAQQ90H/Isgx5uf7jvfuMgxkiOFefbfLeEykdkXbtTbvQNJ4qx0xEG0IdiIxboC/wsFgv6rh0G0JczEOXdmBKVNCxviwHQeO8Bcbmudmyn8lL9bmLRShCAl2kTIcDkZKWtRnIYVDpVau3mEUOiVZA0HQDwewItvT4C/B7DIdGHT5+fLoCsu9oZnA+/X17df7i5aJsxmJ5559Vick85/ZhJoxYdMIqr8TwrevOZ/K8sPVMeF6eXd1S1tqlDEy93yTx83ahOkbVoihYNJewMLaspwrHEsQ07o/PPcRX1IgIcHTfFnWuG8kAMmtUyKCs4aEZ8w22bOORNRYvVyl601GM2Jnd67eW4QGEGSPr5lomR+MtxlVx0LDI8bkTFnb7P0yQcZzzixyL3IMWGM5kYSBE+qx1struyQsMd+0S9deKvGwDRLgou7FEMTGUy7iywg1GhYWwDc+j8O2KFhnFTYC43CD1hxSskZutnYn+JApxdbrab+vnOHgQ7ufZRrSTAQbiJ+E7k8MZnEm/pr7PFpY58pH1Y3R1yHKiwNIRoC+EwEgT4cCxliAhfPqUf9+KXiAPh/JECGGtVq6z6YdoumlVOasqpWP7oUaIhAjSaQFEGC42M+AfsOXcVJJrIR0s5NMosTK+qTq7BJb4ng5Fs5o9p4h8lmO4m6UeRSMJxWv6vPUJ2dJUyUYzcoOCdYx8hO/ZWKt+vqmyl5tdOnE1VBzh9xxNZd/B+p78/m+qd4+x/wjifatJN2S3ljfi2TXCUpWdyFOlRXqyybw1BQOumnGwv3gF7HUyGgJMyxnBS4MJbe3a2peLZYquaIibbviw7I1rrV1NLDFcha7GFIrbAKA8GiieGuzKVYynWXTHkH+iuAPxDcFemUE7CFeiTHNjWpgt+9vXuJV3589pJlHY1w8qeEmmxDIRjPfk7ci11F+dvi/Cm4lEfkyM+dlP91NoT9Myg1YfgmXn9blyzH65RJW+yW6m5wLtNnKDRsRzlkRvSWIh+xAaVk6oXPOU93oRV7IGZMRg1eqZwm4o5F4nCHLDGQB+pYqw0BsoO0rJAoHBiE2gRJLW2WK+pqH2JD5AXDzXfUaFapJC8TQsilITa5wtxZ0Or51Lqd8zoQg6St/o2yWX9ugbNhb8m63BO2AnquE74FvxSg/oqnPkMUtYJ39ev68wifaUFtbDLYCa98A30nQZtypJgdrd5CeuEr6QvdHa3ditC1Yn/lcpinfBn6DsN2uVKqFO+lr/RoPuV6q86xX+I17QS2uMYEILH2mUdiv43whprVdZTqm4e6Tf/3JGd3sqaUeAbwQSv2Vf6FKmlhundkkSfWsIWIPtp84Kgbhuxtf9XVi8gbkXConNsdD7F6CME2vXiCLmRXbeNhPAZOJWjGyAHMaIbcnZqGd0QwfqB2IZYcyOMHqJwxtT2ZtG7ubr2KSCm85xfZN10UiRXYLo8ovBLgbkO9JhGfQXtrWGqXrOYCB9Mf3eZk/jUutNu+RbpG7T+IYXxb/UGuWhkpWralYBpIJPZIF1iqX1u9x7po2Uhl1YTSh9c7eaECl+KBloRySrGXM6YmJZBQi0SG/KaTV/LWcxPw9Qr2hg5ZhpRwqqXIpbUaem/FKRr7oRAuq2jUU6Y7FGIZ4gM/I2yW2zNtxDot3Y7CuKAfyHQN/E+iiEEt0Ag3cZZKEhKvovYu621X1OQr3oeYsi6nUsCvPex4hLZ0Mv0hT8TVh67zSG5j4VzoNZbxGL87iCiHIIHIaKHEYOf/uht5aDsKH5u6/vOjppOvBqnzVKdpnKqBRCzsHH9I54Q8GoS4o3lGjSgbihOhpvoBp5LV4/s/69EJ6ySOFXDPJ4lGLgDmPI+SA8ICN+BrlzNIu77BEYJize9ZTY/2W2tPTO0ZxhFJmBzhhCyoirUxqywGQgcrewqZOXwTe3mmBW3RIdqHZceO32iVyoeQM1kLW30AgJ7a1FYZdKZLCpiY16Q20wY5QD4LUl/3m5tUxyODIXGrgIWGkB9MlAOSzo8V6naaaQS1E6xUYaEvhN8ZJqPEO1sFS9knVhqHROEBS4EjIxnp2+LV+BzEMh5BjmIArGg8hX13bl+/ZJg+Ho1rXYtaI9mQEZVhVZc8uAbzbLX6XWtSFFf2uLGE+lIIK8ZXGEYJ06LQ4lV4JjHHyxqPGaJjZECaiyqxlZQo4OBGp2GGhubEiNWXAo49+s13He31SIttUixTI3OlkHCgxLLcqBYiEVaZhyEGrlAHMRAWg5UDeMgRFiE+gDL4o5z1RhAwAqUtwEK7pB9Mygt2iKQ4yGQYg+NA5ChAwCQIQRAMPq7Oo7s7Slv4WkdyCm32pik2b02FHUzVha3PQAFEi4cgCInDFiAYspBCKBAHMQAKK7sp9Z22wqrobDdNt+t2HYbe6THVUebRFuRDhWLFZmlXFFQTW1H+71Iq2393hZfnUbhQfgKWi4ocR1X9uYFY2dh1VFrp9bKEg1duW26A7boRAnscFO3J7DzmJ7CUI7sQLdbRdJSkWhI1J4C8JD4oCAnF4oMWORkxkGoBHxHTdgdV655YEM7P5nGgIq2gxoDBXrIuUhVg2HRxxHRx3Bcj+oMZfThgn1nRh6GNMjJSFrJR1qRHZskdIbaCiNJCBRQlCQh1yYJ4XMQKozYUYuborWaHr4RLdKZZQm1CexY6HWuygyqUthVvxzH+9GPSPJCIeIRyWLf6vjlBR1v8jNOuHOy7ueON/3BJ7yQ5uqMOyebcd598sedcS7OlRnnMPDEB6/lTfkxbtcIhxfg/IH560BG4zwO1stpn4Pc/cFjsOzQ/GAM5mu1uoDPhcH17Z+Rg72C9xQ5FitC2rjbEVuR1Fb1iB8gFf0AcM8PJZdqABc6VsulSg+kaOVRpVJmE6kwPMwBRqVNULJQtgMHttImPgehRKqutgMHB0ttliajl1UNv76QC3Eq5Ve1L0AoEWnMrpKUlc2H+k70FpQPBUo9RmRsIIf5RaNlodExE6LG4zo48mRR8KA+bSi1ogZwormYEJXKhkZGFHi/1SVtdQlKMjkkQDgYyCaT43MQwkAQBzEwEHexsFKiDgMjuz93rpoDQiGQ3KGUaRr+8LFWHniohOIG6PtFrUJx9ZjM2EOOtHIZqYNMm/p2Epw5qtfhGg/lIJwH1uHC6AfsDOW4rF7qm2ogblnvLCW1uLM5cCc1S4ViMCpF2lmhrCGUIm4BrRkHgRw4kIMogBaKyh7EnBXb1B7bdpsMpxk8tED7XDUakAgHrwcUoP2jJ8IVmLoCtDniOPme91SC2mORfwpPTPKaQnjgXI765V3LbTfgk5UcGU6cCtunA8WtsKIyjZmakCN5Oni6hpxNW+7O8FoQq42XNhJl3TpVB70PWSMglQGtIVU1pNp971X3+zEaaxYFqa1rgMhBoLNmZ/v9I6jNBAPGgPE7UDll1ropYflkpkfotJ6gNSLFSRKBXO8J2lSvT2LW/rJGzYZNTqUbgYZkcJYd795htLZ4cy5kLyPzLHI/o3AshK8KP6NzL4MfAa54Gfyo0om9DLfPT99wn4GnBzR5GWWWSsMT5l7GSI75XlJGvMW5qrBuxincjMnUe+8NqXfh0DU7GPer+SfKTgfOtsAIzs3d4z3s9RO4eGmZL0bGzx+UKFm7ZWi3Rp3l8KKE+0c2hxefg9CR984wfVMOL2RqDoD63XbuJ6Rlu/L0KVEBtezyLfbXbqPOamjcIvHTazTo3Htn2b08ivjjAnGOuatAfIwNxJVnfPpzzjiX1hPMOH8fwLOw3sSxvYmaFwk4EENob9NFOdw3hvOK1B2IQAj9FfeDm2HWbBqZzWLNmjgCoCShJLKPbd4PPgeBRHaQgxiOwBjy5ERH4AD4j3ab4k7Id1CH80ytvJBktsyqk8d3m5urnlBEK1cycou75iRHRdSfhjH+JuD7S7W81NyC/SOlDgvwQxo2ZOHOftDPvm7w4Nq/dxotighz8ML1mlKjL/nElk3vs/9a9bTEwfU8uXKQyxmFPEHy9kcQ76gC+Ntnq7GXhmDzXZ+Df7R/hZw7l3Sl+gtyuSAAj+4o0Fmkdq1x4tv+9lt/TdbhnHyJ6ejVCVilu+ZsENW/TF8mW4ScHbfUHC7jnsxveYIeSRzTV1aXYzkjQO99V+Gi95hEVL23+Z3X1OaE2xVJWNIC8APBdIZsuOyGPQJx8Fn+t9KPt5CpO4MrRxpAg+ughBrG8kHiqtxZV+yUrtiAlzuvnOeCIun7XLF8wM/UH/I3ixURRhzyCnT7RnSgvmkc2vMB/RVl9YZqsSsWFoklKdTceRzDp5oj8kLZuaSyWbp6maGBrWhmPpkBYZlh4CNKCjqhWmNlTsYvzHlBYx7umBxqWYsq+vmNLcSimQVX45q/LUdUsckUbampZ0Y6N9ixyUtFhCkPBEIxVdhpy+mMVDpjJvS2GR2mHfkWf4VW5pnpUNzwJkjxR6pTlgXBFEW2ovMnIV8RyNwIv06XymLdfyDRzETMF2vHnIRrTsIzJfHsbzZk3noq/XRNtX482BgS+C9FSNRP+yakEOuSSFWM2dN1VdCKyH1IzXw1R1hbz4Vbw5f4ShGFkZ6lNNbhMwaZOXU7lgZE4szByr3U9nQYWvG31xQ5UCVKjPR9Ruo/5iSuqftr+CabOQ+iCPKy10BYx0rVscIpqgI1BB6jBKNtVRV8Fg77QFoKxEOMaDRPgWmMRvNUj4b46kUl1FL9dEuSJDdm/Hr2X6Zpiu9eQmZx/fS1vvlRwJgSX9Sjy/b4yim1yrAPVVzpqs84j/kIMimFvm3E5ngRm/JAyt6IDdQhY4SyeT6BN88X6/+QqKzntidCslh/2pgAt/XTKzyO6uPLiJjGZTBQfeFjJOZxoquT+nsI7pqxy5hOwz8QHJSP4TMGmRtDP0f2+WqFGXTYuxDkVHlTT2cTyk+ogUsXxYGjsOL+j/ph2MawWHL48C3iiLnvORf9K60twFYRV/WfZ85IahFW4SzdddWYVpRxZxXnt9XmodaQEVlQ1pFIUJsqu7Mt/PHqQrbOOAZsLmApelNEDyUzbGIzw/BZ6EE1TrtqizhpSg2ruT97/HF/Pr9NFap2hkb2PGP+raCRtc+X0Bd4Cm9TZJ4m0bR8nuJ1k8cpXm/7+G2G1tuPXsHqRmQ4UjcikuH0Xovj+5RCttPZ8uH/KzB6SwJ3OUJv+fhTgc+NJjCD1W1JfNrGbV4/JsltZsl7hQVvtxZSKpWEPl06FyoxPv14HTBaduk5ql+xmOVomMWDiitDBg/lFJjbP4MzSWkI7zKKUkY9s5KK/CILsuU30WXEb8llh14Rvlc92NQYj6scZJrmc1s5yDQ94dExOSTL12bAlyXQvT1oXLI2YMsDtggBWqco4b2nOsIAPJKCUh1hqnG4yapuRdU91VbdgLsJMr2e1NiO59bbxOcgr9B6iIMYzua0ydnkevzAOaRgEyTqp/YbiCyoleKHcJ7ChyickTgOKegt647dXF37VM2y5Eb+9fv371tg2Kq1Uhg5618WJPX+ZcAbVRHvL7AJNHvh2C9fuCfXlDQdszZa7oXQMT/uVkmwXZVjqx6j6uSNXv34kZDNFXkJo3pBOFkE0YZlleyq1bLRSFN897u/JsJSkrKw2soQJU3V1UuwODSAFrHHrKefQC+7vovSkNFj0fJPg7o0M7U2PiT5g3qZ1VGr23V4Ml+OVfOVEaUpjEk30hSRNYUul7MZyzI83vrIh12tapVhOhyS6abyhGSv3Y5RVyv6kb7cnM2+kFtJdE7RYr6MMEslZ85rvpgFuZuXMetulzgd8L4IcIu/+eCk/BlGq7k0JXv28rJR2rPZukudgW1gZwf2kR0UH1k+gyhJ5+M/728apMOGT44YPnE81fjJCEc24GOA6sVh4t2WLZf4YzgPXgKuc1p6ZlkqyGbDcVwJ8jaa0O7dgc2DVDswbHpg/6AdbD00OhW/3XqDNbxV1KqKGuNMAxwVwciimNojDfgcdBxFfYoQ2Cq6jEiBrdS89jI1el0qxj3F85dk9rXUe0bRrkbfn7xWRwCxYTURs60+Rgzc/W9HojcJr7ejJbvDivGIQzEBxY32Bndf5Wm9cJTiz1JyhlQyAVNK7KUkWrnvqflixl6tEkMw/Hr934boJGsOXg3Z4Cwp5eh2xTvVj24rSeHtxywVqv7TwNllNZkojCUo2dN08LuHy/mcuh4x8AJQXjpJ8vvNhhUyshWGxcnfZtYkmH3d+NBkA4OapDOfWyBFaXay0/VZRtjh+WH3GXAEeQdFdTDFLSJVcnQxpPiR5bDkjGZvX+aTqfKqzeBMmqujMbmSTA4syGXGfpuh8xV56Lc2Ltw2Y4riuWdMWC7bDHj3oDC7jSqxzYjcFFSG1LYBbfpQ6fW6Feyywp6G0q8HQjTm2+fpnpzsnhz2DWy4okNnV86gBJ3dAY9Zm7m7cmrex7c8kmyjxh1Gjet9UMGoMb0qM36KEDR2+zYB68DaLZeG0YktiIMocaqmBKx8+R7Iv4JiR+1D9cq5KNaKHEcS+ZHAQ5I4QEjmdPsjiZcIWfj8b6D1ev9Car1+jln4QL/2YtkePwvfdeTINtUUVN6trT+2rR8MFdcnSv9BiiklzrOYxvyZqWtJWVu1rKiWiwWFDhAwcuxdR4b2FuKZchDIse8M4jnywZhiKzJV2wcwXuU2k5BWV2CxQrMeUrUw9PvXd1D5A9DMYSRCUbNqcagqDuVcOHFHb2c4riXPDfJigU0dveUnhqNpTUzMOnq7zkjSu0yDXi/9hEW8ycZ28z5uCcERD3nlLB8ACUFFO96KXsEoIEhBOAif1RMsl7w3VX4r2xJQ6boHEpuTdbhg/X2CWfxbnTD0nQbtZz8OZnebl/C3guRVccl2CMSxoiNl8d/jNUDSjlGU2XXkbGLrNZhy0IGKMkMsRHEboBzUq1xDiUbsgPsQpjf3LuO3zSzbXGafP3wjexLdrBboUIaA0iqQDGFUUXbd/plh6Vwu9kDp2cqPqa2qoGlHA00rAxcRXfNNuyq4PlmplRJc1bBrlp/4EPG0PAtkzwHIDidyHNiDKqMX/abNhEOOCJ4QyMYkojNXIs0yh9ZCTRwjoyGgzVATlMchBtR0ofimhZpmHJzISBPkIAbSdKEkkgJpNpmcg7AzB5vZ873KJ0ptm1GzOPREKmIiw1BYRaDA0KGFoa1hKFenp4ChcAg1LYaarlyLP88Bf46HgLUYdoc/zyqQ+rWEniwp3oJOJIuCEd8EhRAHdNr4Jj4HIdAJcRAFdO4Lb8oG5iDaTB/pfdgkQfJWPq59SIQq62Cz41iXsq53H3yj/2SEK0fGsw8ZrlU8Y2W1T3eyC+BZUPtg4FnPhlUN8OzpwqoeHFZlR83W4ZxcU2CyIBbTngLTOv1xFdQO+lM1D9XxMECtd1ZB1cU6PSJZQlsuotlli3FRrIx33oFVzwZW8Tl4zMCqty+wChudgzi3+lgeVuVnpbOLNqZ6Iu2gGlNF2dr3zu241veEQbm1P3He7KiGeYYHsmal+/PPjVm2/YHhA4ORW5NKw6xcTw4eMpWX6TELvc8CekP5DMU6qhxwwoHeppVPUaF32m0uSN5K7H3Jrxw3FRffMTiUiFxSNc1AjnYr8hwRXwjOf6aXrtglavzbkOTdKEuKvMaQdYeQAA9GUVZQTzguij9kq7Lis9AB9g5BHmI4RJwu6BBVIYBieknaZDX3glir0VZRf07sn7sg6ZV/GtH6RzD72iv/tD7ZiVSUMwTyrSH5HmM4ZYNOOln+LE7ZxDplSg+MxshOGQ9IgE7ZR7rsrWN2EsfMG44PO2ZQVTmcPZGBRkvP7h0z6wB0bV0LNWBWCaWr/ZCBLXaHz0FgPwTkIAr8byp2BxsbRReAPdIr/7RI+0S6ANj9ACUJZfdjYHc/2gPtwXlUDekcaHu6QLv+wCj3N/GAtrz7IUWXLcI+HsKe1ERqyh14UYmBmfQoFf0Gp9r5sGZQ1QyixMQhCfJQILENieNzECp31lUa/LApIl4zC0Lxv/oab0bIQfxrEMUJ2xpksXHemkq7YcNTmI7Xa9tDJNNSWai+kjxvTPDTLjF8q89kFfrzw0SsxuxuvQGOA2hzeQFtsxUnB7XkHXmLwY6IwYZVDOY4PPFVFIhxZ1HOoRxWUoNWViUoqoRiyRmBKEgCUCosD6GwlAVRZhyEKixDHEQBUfIx9czE1xV7KxQlopdq20ehJ5Y5msmBSCcj+PM5bwpYGcCintOpOMjLgBYISqBhKAcagDpNFvUcEfXUQo2OC+3tgtVwXRSJkCMHDPXMCqkogE/b/rdWd6jqjomy8GiWkkWBRyMoRGHhkRkHIXjUVSXZkXzqOYMFkglo2Wj7EHbiNcAOtK2wCqMzcYPABiRuIwzTMpIjLOB5Ags3jgg3+jW4MXCBmqVuZ0GWERxksTtdZ6NURhhBGlCCUHa6RjZIg89BwCyAHERBIU1BGsA2GMRpiuL2eoEOhdiPfjTG6p7uJBc4ag9J7ghjy2gkR0/gY5cW0ZwQ0QzH8rYRjGhQQmojOIBiEc35aBWMuEp3iGZs4yr4HDwmohk3xVUg42C89cRr/GAAGqFOEBJdMU0I803zXTFMknnakCZJq3W7W7OKWA4n/2csRyIqdaMthjtd+rUzHgGbYGAuGEpUaiwHFRoxnFUAigqgWGDoKdMo21ljKA5hYZcZB6HtrK5SpsfyGZrMvAtq/MDRwQwI8Oocq1WR/puDgS93NyaN1kXyWV1yM8TyMXyuvKUFKcfXUaqHAlBiC2M5tiCddbc45YTJOlNHNVkHpXX1RA4V6MWaeO2E+GJvVk+p+NgZ7Op3XADraT61T1YvGemlqbJoaqYCDTBCVhMo4mGxkxkHx4Bl6SoVaOI2YKeaeTmAn/z5nD/QE3RGfkkX5CxIwh+Nfw2jR581XOGH1XipF3V9pNXvZUX8qBh8/wE5q8S6WwKKPbFRarRN5AAQWJvUAqwjAiynCrDcPtRSGax0hZINPYEDQfYMGJpSmGBEhUAJQIkKTWxUCJ+DQFQI5CAKsmmKCgG63WwvjmppzFPsaaFYG9k5nZ6BtowhKUXJjZ5MJV7aulVA3appzsZq3arzKBA7ntSiQf3p/sJV9QemuZCilZXi/YCtVLWQKn7+/3uXKsfBLgs8tdWsDcRq+oOIled6yGIlQ2srVqpiNfpRtNVghFxbcepZsWovVmeirUamYqX9wMgZIcvhwMphaznkGVmnlkNjsZr0sa3m0IpVa7Hi3PnuxWo6whYrW0jbQKx+EG3lOugYXw7HPhLKNZvAdJr9Na/G8KJzp7jlOoX211ASmKbn1+KT5PKonBKV35+lidqsJ8SY/RSlyDYkvSh9Z6a2yDY+B6G+MxAHEfYGPX5SWNobrJqkA0lPmZnInmid0E0RizIJqz+6kz4g4QiSPozyAV7fhtHbQ+zpD7LnxzAYKsT23E4CArko5YLlVMSqlLJ/cyh7XLECbGobQfP4QVJR0rw+eghUXUO4koH6nbxmB4iuI+InofWXjuoveVKUmCNJMUtkBFiMKYK75PVtp8MDNr9cMkb5hBAHURBnU6dDunbofNM/ZmxZk2KV5w0My4T38kRiMxyFKX16eWGycYigamEHpWEyD5mXVFAf1ELczsTdU1RYQ4T0WS/v3IeNRZohbgFMyu/mfrxMqRU26rsDJi73VKvA5DyizI7Dz5AV1RqG+/spSru5+g8gb856POxpQbM+aJ4CssmN6ollc1gTHHdwoNXnsL//AXNJ68tRw9IaWix/QiwPFZkBTeO4jwHmHTn6mG1CzFggkFUozcFSKqDghsVuR6kVmCrdkdDY7lgVJyX5Ycry6KQ+lXK/BP1MJhsm2FY3ZB5JbYxKGdbWw2zydjgHBuM1ZFuPQ3V3wlrvFMMUFNVpRGTBOqJHpJSBVahJg71HCtVNaLA6dGlNO0hklUgk7Gl24kV4D10a7Kfcrh9f/S17F7Mp4ZX6CiplVTgNSot1dVbAjcRqvbn70EisgvjTthiuOIykReDK32wELrQhMifrzJzxTVmhkrOWq8mIrbMiN+1la1uU89mnotj36lu4DT/bT5bt35OpHRN1QHm/SYM/Jqyb7SJmUvO9qPJ1Knvc6uTi+l66PPF2+7yz2ABG0RAQAHkY++eeY6uG4LPQAzbQOwtnOvL+RBYd5B6NUAUks8NiPZDsU+XIbNUYynajrL1Webh5c754ETEeWaeru1lfEAVinWi022YSJGE2Qb0y2qppTIpaLnfbHFCLPQ5a9Jgs6JC4RxfqiswqzsB++N5ivKIGTdvKMwKN5jeGnRqMFpxtCTS/K+SvaJdyJsntRwZoayWS2cJuQetytcrIxb1SNTT91WJWeTqNgC/aU9kzs03wRXew3XbuJyRD3726XlOkEcSXafSAUihXvy4MzH97SqinzViKmi55BEP76erUVj/dkoT6urF4V/bfFJ7y717YjnjfT83UNz8KmJGW4wEWZZ4SZXpAlhUMMzm+MAMpctu5yqK1MdfjxVwdZ1xPfwISzh1IGFC6s3iOnEEh+KmPjANg5Aj2az9s1MJmVpkoKpNirZq4rKD4YLRm8RzbbA6fg0CdHZCDKA4rVM7rqhrg6lUAp4RR6ne2B6lCznebxxeEh+lStSUgPq2Qd50Y1WlmpLQdUKsdu1tbMtKCjStGCxXP+fmKWGEl+PB09koSBQcrJ8g8duXN6XKHxCLmEyJmZzqW0xQc8IjmBAMxu3KUniHgb8EsCdaFhheTD2pYObuThTPZLS03x1hspJ1RYk+/En8r7mZZc4RhjgodYQTWweNVGGCdY3ML1hE5OAXAelfHM105cFM29KntLqX6pL47tB/IUzv7R6qaBKCqlUNVkKHvQozh95+pjjLdtSl+VKZvBXJ7NK7VeN2tFwCAg+sFA3+7P1+FKSz8zetLVZOYHWz83TLBvlalo15E6vATbt9za6JkespUjqTI2/XWUThdOrM7AGy1OwB0j4vRM9Nz5co+aTrzosTtzYnMC7r6hSout/lHnVxLEt7X85ktzsexeiNlWdxThgWSPJQ0MleuIWRxvikHoTIsEAdRcD5UR4eB2bpB6RUonysIoBenBIklKi0C7ZcLogalm0lkryxQ0VRyAqGQn7kw9Rbi4rWyf/Rm5tq9uBrE2eTQKWmTTyT8lHYtVe1mw/lofah4DqQznAGGs+MdvXrOe7fVkc02tXEmF7Vzy6AjctCt4V1FRK/GGU5O4cR49SO8rltpdnHwgamz/+RmWYoDfgDhjLCMK44vcdqn2duKH6LEZbVpfzyJm45GmBJHP0ZhmIi3M9jCMm3ZHf8P - - \ No newline at end of file diff --git a/Plan/Database.jpg b/Plan/Database.jpg deleted file mode 100644 index 8359507c7dd4cfcded0604769650efa452c8295c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108647 zcmd432UL?=vp)=q1rU^~fS{D1gral=L8Sx|Y61aCKokO!&;%(`#6~Yt6AV=#0TKvE z@1P}>lD&BLvuF0~nR$LQv!DDL{Pl(I z90UXg(b3b>(a|6N(ft~s)1W(k?9cY+=kdeFaFXHAcKYPW6DJu@GchrqW@KbKbM_1q zGb=MABMTb~>)CVX*v>JXVdr2!$8p#{_va+^f8KeV;q>8+=a?Cp5C8i=Y`@;qv7KfJ zI97a|UWo1(8~t%M`d^>u`2S?}IQ^fE?w{?{iIb-pjvu3EJiL7W939<>teg1-ww4#!k2R5Nh!8E?Ov`<*(4z7p_HHLc@ z_VkL#sy~RE5`~$#0_5Cd7&WY4*gQ@rl*qfi%*Z^X!21u{N66FBF`PJl^4OouX|o;5 z@HpKuCRWD7wf}>|KdH01o!}6ZmXURR5mU%6Cw~VDGky?T^x27G45OT>f<&ni^zE3k+jJhb;aHapd zMw}!BMr?UNc#98O$0sE&RcUJHP;UxLy>`Hxt&}xeoa{-1Tu;zp_rIHers9ltfNf9b zW8i+-;L`IyBC2lW+gg>4@IR9Ia-40F$NjNITfI}6@|PpGpK)ry7J6igeKWHIm*x}+ zk>b@lL4^V`!^VV6`}hQIP@Fjc6nm>*BsFo~22od(VmjXTCblEJTrWYVg?*8t7n@=H z8jwRB0LW!=V`Fu_bquml8FKiA^o{3ZKYz1%>NjIABIB@y?&9g(njLWt(ykRHC1Dz+ zAq$Dbv>1^O1tE4m8{DscxZ3JHuvZn8ABtJ=5q}roCQ=T~(~ijET)#RDhzl16=S624 z)aQX!<-6ab{Qh$?F~Kqbkg)8+20o5k7wwUNHp7~x-qv+F7N;r!HJU>DV!LA&c|qf$?) zYcp{$NGpfU(69XG1Wxi&@UACLBD=-$rd`?K*VD^29aYPw7EVpZ)$|cxvOd~T0B?*g#z>a+NomxtCfZX`29iDki^inf9k%D+pMWec z4#*UYIK8eod%8U{aSr~&sc_);f0Op@_*A>TV9?Tzh$?2KKzpS%RNW)c7jSRj`iZpW$Wk23Rfm014~ zN00YM=m}iFEAkmuSr&eo5yxmXeIQBo4CiWF%22nZoil_2`cmOkWfBw|7L zSVi%Lh@yCGD51%(Cs6f%R35h-J4uE_U(Hr;VPZ<5#2d{L_F=!|JGoqzuAF> zVG$wW@g482|3<+>GiOH)AJH<5?0M9BNz||J@K8Yw3dsBW8IsDUX{U5MBB8GhA|%rn z?@-1KCym}XFEMhS5jF{P-G?yTjg6}rjtnMsw7I%a9OS-{T@gI&I$*`(*=M;yda z!<{VIuv4r*FP6)9dBlwU3$7>*oGUFc_>1mGD>2vW7hT`mO=Fn@Q40Kicg}b9o-`O) z27m5B6Q#-HyZ+Vk*lB&@AxrJ?ks>JDw&U0S#vxVUP*2k(^3YgEJ@b3H(2Vw)&xlbU zTlkyi6IsL1BBDYa+;v=v!;b)gnP`!4&lS6VYcl=QgSo&k%YaV+ z(`n9Nl)_}$G}z^tx2|p|j5AgetckKE*{gcp({9G`PL=yj;8vD52Ke12)L0DsF*kyM?l%Oplp9=FP{`XvfoF{ zf#=bGq3Mo;1;TwBwYbIw{dAgri<<{1af>PaIxG_$C_nF#?sv-4e#=uOk@q5$*Im`y zozFgMnKYMZwL7)@JtIrvh;|EAgPvafXn7g@-MT_%8b18-YgyjVH|Lq^RbE@xn6sBv zhd35tBau8QKb*?~)~Y6Bjmgw_Ty`5qXyeU5jp&ZkSH{R&zL)*&neH-X2aI>tOiE|3 zq0V-mWvor|{%B)3-f}7Nn1*)F6qECCrN?r(!bCV+#q_1gS8-OkfSpS$2OT1Oby8_R z>%Kp`bAFj>@Q747Ch+-ngD%lIf2W1HG`0lK17*F~7h0v=URk-9c3`)foXEuBGu}pv z=!{)=(V>0aktp%aHnax%Uwkr6$FxYy13=IKF08?Q!J{3 zXo8y4(_F6N{zZpLvuw~aj#eB|7U+CC7dENnlv&e9)13=PhO~0(&%aS=R&(Q%yt5j(0NaIy3@M zQ}@hs%@{T9AON1Ff~$jK-$zhnEs&)(7B78KY;)N9W+ikLXyc-TehHNc=1ySL)kT%E zpYCWC$?VhDJIV22V{*CA>C>GwCVo&YTL6AhzldgS%|Up<3#s+?Tt& z@722&o(iwlisKIelbZub56}GoWUBYK`d1@oUOtM_{G-#i>Ckc_Er%U=@8*Nb|7dI| z{#otKBDr~`$Q>vq4`@zClJq=nZoUHWRs_{f$%{2Ers#TGA(0N^pjw!vxQJy1H&!Et z|C8F5L?L%pDIOOv^lru!M#zb1=@^*V4>|@Jb6a^kb{<}6SiWBCav3h|;bFQm@S5Kv zm@(@dR%WzClPJi9Y;zoT1wvh}cqp@_CVHf4Wa~Fwu-tPt{Uo;{&Z*TMHeP}PPOZEU zJGmq!Da)COsMiSvB7JLe<=Na=^GY_#8a>aVc9~-zrBn`OLE?rJ8$~Z&Xm4?tlvHVM z^M`I`&8&o8Ef?O!UJ|_jO_3oJS`UvjCCE$nnJu~8#KzJJR;b@^qX*A(4W2J;D3NGS z?9VpD8@IqQ!bRf|fpsC6Y!J9C_)MgZu$W!2_ zKZ>6uGJu7lsevsP&y{=zGF!;Y4R_(+<6QMwGpYz5E4XC(<3v|O?=925eVP*G$i*2r zC)wfZ&D=vGMQn1Uov?TER~}*=ydniyFvaTS64d4dDRz^x6r_ylQY2B+Po8(WB;Nog zmvHU!2nw|l3K)}|klElq>oa5DYoB++lmK))6Rs}fH}FZ4xpn$Xjm3|m0N$D(FS#+F zdKR%JGNa!q7VcD?_#m)mujQlU@ki0R<|6SAt7|B7)c0Oyse*bBX;HWOvW%g5x-cufk?PQ(A5GEx8jC41FJ6?8YCx>Dw(jH5YuuW6@)e zA^~mT)CZsNrxYG2%Lm3&m~n4Ar`3#O#JF1e1T+AS{jttsERqlrcHB#O9yB@DswCLr zh*SM*@*fY{Ex=lI0IlT(WL>6td zoMnHeA}23p#lDZ@q@`BNb^YD@cSIAUx7;#hOu?{iVE~&m-afrzdC6?(7Q0QZa@ynB zJPzQuauPTjT%cZHY`PZ`c@HR(*SntSfw1>^26~AVmRa_Yl#kbK8${2H+P%t)!ww_D z2=;dbuL#2rk~9HglKbuuotl7SZ0Ob`X2%hMG+6F5>u~<(e0dqJ&=Zd7A;0L}BCp0T zCYxR8)Imh2H0^><`UtF}Dc#FUh`?WTlkHLYKKjQP5TAS~m8O`tBaC8VZ>nb8#iqRU zS5_KHyh|-995X_KJ@FFZ@5b_Hu27PePV`>PlKd(t#bOY3aaxSZ&TniN$URA607J9& zr-X#5!S9L=ngSiAQ8?(wS?9({KF-%;z158Qd;!zGc`kqSRZYQ4<}Jd6WV+jpxL)}6BH+?J9+g~n#xz1wn*m4jXs$Zx_Ly*ZTE5!`2JgS;QaYP*c=q_)DML_zlVv2NkeY0vE++ z+QAL~blkKNIO&rIzd})Qs-oQ)XFy33h=F(BWPq=Bd4nBVXJsy*e|OPE(OzOZYOMTX zlG8o2OfFvRXBvC*K7Ha-yU7>aoL<(d(y7c(L(tx^kdDK^Z}^;_Frs(3O7=7jlOU=@ z9NV@CWM6li)OO-aIVmKpZd>jRxrt&2e?-^Q_N7THVC0km zSgtCzaY=i}WlHe^c6mx%Q4mEfIQ%O?d^C2ODJu?n6;4YaMIP_FEQjpUXA0 z*YkE7d1qhXr6E1PviLK>9MZqpCTskfhtzkA2Ls(m6RkQ^9>{v*7hR8;TF1m3tLd%$ zvSYJkhf1uLyq;!dok@+? z&$i%Q#fslw9O>>%?0K!nyQje%gJW{j|BmqcA1?bU-`bQ7NeUV*wC;lE(NBz~)AqR@ zFLxf?Z#CWtYQ}Q2Z1I~@IMH(CWBt$edupu8_q27b`jPZL`Ard3a!dA0ezbQ(TOfR~ znR?>^&#X*#ZGO=$upWH-vA369ed!mSPWB4u;{kAjcuDbAuB;!{l0E%-s@HDw z!~jk8Fs|IwsIOBys3Wa5|Dx-?gi$!ZZn}TUNU42;jf_BGVv0^K{2Y7+;>k)z~Kc?4~7E_m>?F;T?K6u9E(i?@} zKEx=w879{`J|9``(WU+S%4HWjCIDudIrp!m{HAwwWy6tyKjHNdwTCo(9V9>0=)K_) zdPn4Xwv>r&kTD}>M zV$UO~QSni(Xlhi8PjuviqygozvdrE6#>cj=9%PBTK>_pqK28G$$}{Ql#53h1s=bq$ z`cuO4SDIA&R6Qx98QW}bqYGI!dWJz)e4uc>9$9^8#)AQMcxhBd6Keio^5>0prJ-U) z)WtE=azrICj)Hk(tQQL~5x z>F8pNSYOh!6)U``xt3ctR4P^xxrf9;OvtsC@SzQ{)xM#qo0EBo4_cDVI_)%GNap$wbk56B`&x6E)KFL~%Cmq$bn@Hs)` zWa}~}U`P={KQXV}8zS55`49slG2Yp>R^EtOH~#N3*W{LS z*Tl{8Z^LgxjtKmyFu08VR|&~pNw(nVW$3~>G%WZoZ`+I|Z7eu>2Km(g%u{H8nK^Tf zCsp(N>0fjveQiFenV{;mANh;zca_sDKc1(g@K;Ycw5A{vv^;{jO=};8#>evp1bcPF zV}#|{<N`HeDR`9A862jUyADvDOwf8tZ+ptzGzP zEqN6?&poDgq6>JFoNNb9n0Vj-vmBEZ$?HTxPn1b&g_{g#*;&5{ z=~F4LTZCSZN1|5S;yL4i72t6 zXHUv*!G6&-V5YrPgmF>c)^u!RnGWT|8y!wA=3bo!eU^PsZs?{NWiE2o@XA|@Vc_<%~erh#f{?K~5zi9+31Hld?~ zl%Y30%odLQ_)gAIgs{9qBNd)Kl2bOcF?!<0yKJD6yM77Lzu-aw)$I#Fc3d%MWBrH6mt>%nW+ZNpKcJcJjex<)*q5l5Nqh+3ZUOf=yIx+0;dKZfv?Hfh2YqDGBqs z?Rb954eD^qfb+$6?2^%B`A5_wa&iJ*L#l%O(n<_7fzC>TiuDO==x6Jni@kQ~h?6|x zNRB%cuRFcCue@32Q7Vuy#5rgZe6FqEDOo4kx!J`PB8OXOdD5wgY?H_5(9+SbLW@6N z${OO-^9Gk-^)isK(KKy+HKLS6qF*pegKLwm+#*VW=sE^Yw2*|Aiu^S0esV;%M_m(7 z8%U^Rxrq<^TFl74^odD1`nqkaUTCC3UlFTD(2@m;ZxPv)&0Q*y42#c{Pt7h!)DQHr zEKIo5=EYCCSDuQzrplD!(vf{L8}D&eCgWKd>pa-C6D5t!HJ$ZyFZ2W^j0R9A_rfHu7IPr!$(IOqf}tx< znk3Hp(-ItOA+K(Hi|Ff}5it~LwU2!B$wEwY8Uy1j$?NjaET-?>AZoqhStv%83f%Oh zE_Epvsq?Ap!o?tJ>Ow-YvbQd;-*Ov?vCkWgb=c}h%dmgMr_N;c@qF|K>xw3v+10}l z-^QhXYa+xrkXX&&AKr|Ix|joWTeZyz18ae%b3lfTu!`^~Gq^@xH_%nu2IC6+FKI~=64Xq{- zVy1TVbI;L5tTL|8h5EHAWTZfzr?hSn2^n`q1&s(paby@Zo~ULlDTiV5VgW!QB7O+AHS%kfcpu~|TdkgC2NSjxED{)R@8%Eshos-4NbLHO3d zwu-~>_Kwu<&u{!`)dfEh{$mUV4C3jdk}i%z;|G6e4H?#=^C3^$&JcQ&Ua-$#eB&S) z_RCsjIUR|y0aeb4@$t^=r9!OPTHB~f?HmjJaXEPyN#g2mk&!(U(IL?c2OPN4n1p#W-(5gEc?o;9*L02=j$lY!V4^g z+!6}u3dyh0j$iJO^|Rmx#98EcJ#`-X4S}(|0 zikr~tVkGVfA7B<8HJe2=P)sQpDeIM=!wzz@b;~VbC8YHWIodY*cA__nZgCYMLUqjF zMmpIaCy1GA@S0H)3LpZSWf+AmFC{~G27J1fv2+nUX1rkjHVQ6MBD;|jz7zG-=Z_L6 zr`3hkL@i-YPBMPSZ!U9zRr>Nwi|Y3I`NS)His$!oCJfeb1f`u_t@dQ8izGy$wAQ4v zCp?Z@`9c4@3oNY)&_E{jkK3MQ*XcY{W)H5d`1%8Ox)&@YjT;8E9e8D1a``d~jPHl5 ze>&d@_((=_kh3gD;Vs3M~*=92L?o~`l z#ZH35{cLDZbc8}IxS}}P-5xE^?iE*6ZUTxk3$sJux{Ae2bssJ<@>0CFS;99|6$U_<;lqKQhN^5qd$$C@knay5cbP>H-1pPtoPlt2Ke^R%l~Ts1BkqwJKs^nfQNgm>)FA*P7#E453lC^E-gPHU#Q-JDJknXi%kk;3_4R>)- z61ZGwM7|wYi^S-?i6_fC@_psKb@ufhR2VFFbI&#$m4aT5_WCo^@!#=&4aNr+F#Zrs$yZ{VK zJuvr}#6#iTt(Q5+;{>WjOD}lY zY%@UsorzgP3g<;-3Dfow8$&X8))Y3_b?y*FPvB-cPJbF(&d9;UkJj>dci=byPEVa*U`{Y4b{TJi_&=sx#0@ylcF5R z`YGz}k56?HA5rV{{ktDoJ(!`PoEN=z^GRNc4|Z77*5(Trl3A~C90)W|t*vgXt*+vd znnNGk(JIj+{ncJSTO8izPa_^Sgno#A2zN#>>Whc?0g8uwTg@U#Wfq|W(Q1938Kw3y z;;~XAyzAwu>D?+>%ix|2pk~!GHc3)bbVo1?5R!a{&)|O(dj?vst$YSDq^SI>VggBmPtrnM9sQpQzxgMt-FDYFC@-k-(uYS-6sq zS0D^+CatkZZ%qdwZ&uF-Wm#KyR*8sfa5jQ8&bjBT={4orV)vnKh~O@gol5-VuVO0} zoSeDy0fQsdmBpv^)PRvdm|kS9Je4ZrVVOzM;bMS_?Q}Mn<<=rdM$>&$oC+yV2StWj zT$y47vpP>Sx_GGk)WZ1YsGim1-FZ?g0?Dy7E-Ja=yl~z^rATCEB;BDdOSyE~0c(K-iNZrCG^9b(V zXg>gPN(MrO0KVULQVi;r%T*5Zx|rV-{8Yc2+%3lC2D?0>5E9Z5BiI@ngllJ-x*5z_tQo|47%K#D zkS1W>?%mF+;h)R3lu!9xFdlNFMmg-*Had$Is2xLUvC2_N#)17;;he?v7opo-a{WICPM4Q z2k6{&=;;2d>=podcTd93AZqneL)u~KWw^P=M#lZwql1gzm~u8Wb9*0lrs%&i2^F%G zw#PVnra?x-O5Y}{TY?30WQL3)4m?DZ) zu3p|z*JqU6*+OvC%}oNBS^MFj)Ua3XfnBfhT{4xDjfyY>3PDT^84&3qN7TK;Thbkg z7T$>7dd(cH)s+vG9QiDN?Q-fJ(5;#rxmLGnlTv46`G9227IZTUp{n940&hW_-{@{# zw?H6`YM0x&x1wNGuZ!I*u?Y6W?46q2{(aLo`fWYaF&|cHhGZ>hq93kVHtFwF)kc?*j73T|4VW1`5_2_S1uSv z@7*eX##Yg20-FIdw zjMx$)*epIGq+LUB;olgepUdeZZHM_K>LVDu-`UBPi8RIbTA=6RK@j!s3>lbS#Ni=S z4Pk+oLPFi)>Vo_KcGq8cI$AJ<-~P7&|NPYUL~cGa+G(F~YbiXv+V1bNC@|!^YA#@m zI#_q~C;p-fqBX60YD)@id=f+&m3rJV|F~jqQUwQ<>mD1vnzF8^Kc(0(*iVdg=;wKNM(fonmLZOS&&*;vv(wqzz z>$&_ibG9!GOj_`P4eOVbW|IvgAw-SLK5;jGQ}wj>#vG}M?O^q4-5Ljg@whx2AtY3P z9z$(aRXZB5(UW&_G0))Na;E^=ISofhUi)&4ewaeqH=8O5!3ty^C0YOc^eIeP_O?}6 zosfx7gbKX$7WpT9ojsFkeL#2l2(Q;yOsNOC>t>%IQPA*jbk9Bi&ykX*z#rI!48@%; z5H>G^iza#zrqFwU0jaFLv{k$EszAAIWf@rH*rt435DFDLraCRRefdaG`}}aD8UB*@ z1|a3WSLJTKc>0rO!evB%)H58Glz*pg-v0*``8Q4ZizQ^hiw%>=^*ZM#I^lQVzZL4Q zRn{Zi1RmzE=#E-~y!f<&Ewkrh-9%QYLrS^zfK!|GRQ*ZyxzCu)!GQI+g{P85SwBRm zag!3*bdgqN7l9FHALALdsO5=I&eHX|B~CZ?-z_g$#|f8pNeeyW=FnX(Hy`~%88hC~ zQfzQ>r;)N7_ciw>S}ZWKo7~Wi!Iv#fyx`) z{E<>3A?$f=96ffhK8@&x_&JjiDm6CrdVicj*!@t4p3HUTrxwXs$GAA`^Ri*B8>DVW zA74**zONO*DY&hxt4RT9^)%g86WBt9T|Q8llS|BLbv17{q@55{SL1uX(lhJ8GRlSg zRb2^9;g^m})fpQd6XUBKTmFi`Sg{IP)zv0fYgT}cTIT0L}DX$<8d{q#zGuo)ps7|`L9&Wj9@lu zFXT}3J#*r}&Y$U9Qap3|U1l}gLc|})Wewf7co3=&l-2!elD8j6qiw6GkL8V;AoGca z({QKp)|G!$Sv=JlS-<_G%A$EsS|F`hgDEB5xnD|Ias-;aPVV18WhMPt@;M>Ms4@PJ zk`ECu&9;y&`dq$47*4i$GnL>)bK}%)Y!Bowady8D63K`go4vXo4Zgyd^^4AIt0}t_ z;DWytmMs6<|2M7J4|)#$TMp>_C-B;tMqwXYkzMwc(l3r?CW_zG~fZC^^c!U_M zLXjLr)FKE30?8#^p|?&tS+BN~ZeEf)+L^r7PiF1Q^wi_580J%2AJau6_1KLxb%bYx zp$_TKdml-;)VYjgR(1pmgdfv~gjB6a$(@#Zlok=3^bs?`iTB zX;Rp{dABQHukWWArI?jCB7K6DbL>dHq>?6Km8+c~iX{>)Y`(^m7V)sn&gQ{irAQJsg_DRbdct_Qt$jR+UH2a*Ol?{8M?#^GcM(Fb307k z_QFDAu^4%xj!0rG3SRABL~B&fHp2(X@OfOIK=i!xl3+Xl0=8o6)}*;Z`r&ze?Y8?e z|J?e&HAbeK-^y{=JAw(h1^I_uI`=h3u03rRZgWf=#|?&pBHAFFGc!AMV20jB|Q>mQnjf^@lPqzG3#L zP;?tVww&`ClbePAnFV_=oVC6Bv37;a-=rhwzTEOFTwb#Ez7T)^wk>Swb4{l*K=g%C zZfkT_Ox;|>M_XD9;AWOxtmG~G?@(DOwft5L6A;deN377%L$&X)+bR=xCkh$luVpeBH% zpQ{fmlB5w@!Ls0()X?8xmFfGmE7fWn|Imc2754j z7Y~9MBCl6FE0DCo67dfrhaZ1yvGj*PjGdC`HwNFkU3Y*XGv)jxOuWsI>u^acqP1tg z;oIY>!=p66!^FdKdhSfkD@bFR#nM!%0m(4*L`x@7UOv7WK&uxlJEx-_9}8WpO4Zkm zvy@jo{k3Q(*rOxRaje{f2J>=$qA;+pWJXl8>^;L_*wXKNu6M`2yPMguxd&X zmNCO@blO6{z;$onu3fI9MM?I&(HGhk*~<%SN{woIgl3a$4guq!w!89cHNjr|>g<`K zR1`{8v95ox>{Ct)0S>XA%_xwHx{x4~c7l}u$xbD9)b@MPT~v1)QLe2Vhvg%b5P@T| z^bYilHjXzR8@*C4S1-#amomjUN_$Y3*lZfFzDuuxRp>kp6_gTduux2rQRj@uv&R!M z;aFjwnJ|B&x7AizJs7!uM9h1zuBZ6Ilk#&#t_f2&H_s}diX>;0D4bZ4Ejc{h$aDMi z;}5dU;j43kL%Whaa64Sp=wOM04aw*&!0x4Y!_&D?WE-TFrOd(ALVo^LH)gg}KUhdF zctK&M)A((JXGo~onY-)N^ti>&cNGTn<-L2|8L|C4(-4@vER@|H8kl@a3F=v3!DK^g zpL$b{h-icl2=<_Z%1!kw!U@`PlC3w%GLyV9m2GxJfL6=U@_B*&Z;PFFCcaHkci#>O z^&4xz*|ULop6#1Cp*U=OFd$yWaS$r*4P#FD)aTbK%KZm#nRKf{9kS@HRhb`FRWCJr z*kC;!qLEiqW_gEHD#kSCTAJ<61mo0%sK>_v1bY9WdB^?&`TweC|E`+JQqrRMiPB!7ap`E&YwD z8ci4?#}ZeR$WGOe)oRLBhm1bTUVt*^TxLf4NhW=^=u#3-;0SM-g)G7<4e#XhCMsdwytnn=1+*%WeW)#YtG>S2EAZThbG zmC(X~t41XDe24s}qIhtM)+_pf2QopzZIg+#PfdxA1yqDAf}(q_w_kk<3bd7A*}%8vBHLZy7F-_>ine&4fqO>E=<= zoRWZ3!Ja~2E5*6)#$mQkw2*G`YYXnhXp1qKE3};sspcwHHv&Vv;t}X7@P?7+qfDfG zz=(TtLbOfymp&A1KE7o;K-(^)AuCR**;rC=fTc(sHi4pSsO!3iYse^np$l&qavsVy zUUdCpm0*D`t-_luK1Mj>0zRAB#QXDghh4g_6#0p;ZDMn8oxQwNQcL*K;MPqvs>hMf zJ`HGjlJ8N*`sl=C*AwZyhc6RaeHRG@%z)Y0*c|`0^?wWc55e8h_Vp%XoTQ3E7hX5N z1veUuajuKS2@XC~+aPPyQUsvXkqnRlezb5W4u#_vduMzLWOY;kyY02Srw`(ly=j#!&Sb zfU~q2EZ$JdHN^vM5#S(1-4a%1-eG%Fax^bu6<3H9OVTuNX+117lJGqk>xYG8U=N4l zLr{tURrHAJ^w1^i@Pr5jOHo;*9A=D0nJamuNWzIo(#p6!D8ZMPVgpny3J-IN^*f7s^nK#tO@t5-q$97peSeg zMSlmd0(GHmfmHfOFBXprwNctI z&P-8Dp)2RG^HZ=4NJ~6OUi^0e5tf5RrpA9ioB2a=oiE~)=+|n|6@2M{U$xA*-fT0u z=WH35S7vK=qoy%LWc6x=Jd-ye^kGAU8}CzpnU?a1@Vm`-iF*ew0@y|S&i@i#ScOdIH?CyLvgs%Gfyf{1;xvF9p z?9h|5^RrFz9v8qJ5`K;Jcusj{(Cw0~q2xp1NXCyx+pVBKcHkX6 z&DW{(xS!y$55jl*{6FmAhZTaU3Hz-xigjF#VKRKb5mym zUB)^FzaInmd{MT%ll_{3_2ZiX9<(rZ8yPAD(V_aJ2B1K;1GkU=9Q<&%Xr_GAlatgh z!R5KyUy-kUjc;_3Qf0>b6%;>uLvyGgqSj=|eqV?^Yj;aX&gE)-??1|s|4{tDjj&Jr zheJKU|BzNW8tEMFrIXEkAzt}b#WPmFlSq~6;X0GXZ58fdm~)zpU!reLe0h9N2~PCg z9u-Rj$`!a0ol_USja1EB5c5@wPvBuWQk8CFig34LArrhTFqWuor%9;Q^H0_nFC0R% zl#Q@k%5jJ}wl+-2LK901=}t@NCy>hYg$jhIX+q06?WN}*Y7<7IK4tg94PDXW8i9r{ zBj1El8%*~Q9<9;39$>_n9I32( zN|9FeH3DVTU*^>OXr+yot!oK80W6wj(dG&6A!x#qB1TQ|@|Qbes#!8jzvpzp?QKbD zI2{|-F*nNW!c>ag)To?Vq_1G4yJs0Z@Y(lE`(Wquzv##_vu3Yl%2~T`jc%*>XCEu` zl>zNSIh_bqgXArLkt*%RXtw#~R$D3JqNj!T9OIUta&1kZGtakt0F&yOUWh@Ms@v#RcFWUCL-iq}HjoyT zTN57Dt5db}r?k9>13mc-k~0drGP^>87Q_OkVt^`AL?(ImQnX{uNMvq;t0v-dR*qcmhR+EB7R>x~;LZi7gIhe?;lNG(Tacit68C!5Y;Qg!OX6+{q<&J4 zE#{yTRPM6E7qH3^m@abvh+Tx+7mh5qxKy-<0!W=>oceq@vow84=I&5+ z$vZO;kgBN_3;LCqK_Y*)3V%yqNOY#C#V;?iol68VeYNaTrMty2ilV7EPbR)TyFM7$oQya>P~a7ojIY9 zUcwT3a?zP;Te&&vy~wPmAD~ywHkC^TYq_#=q{=WCUX;HY-a_E@+E!Hv;Ss+`!@v=$ zQorcR<_yyXo#EEa8Sel$mX+Z=&VwEi|9tV->j=Y>=QpUoYq4-*EoVSZ!4=cc2xYL6Scs$dwwd=%olyZ&d|Il_gxPh zuxLwGHwqdtZK|!3;qi z@wJFLJ=s0Uex1&^vI=qYz!YpdgnOve*nQ_jJ*;ib56-e+$UU-N*7=?6ZN;!U0M#c1ei-Ba zf4;;EpD^v@*yv|{D14V2&YEcUi6$=;>eWuJ%l?s&@0_l$svj2rw%0+{T*(d;k6T#d z$<7EkvNgvJ4-o#P)B^oWBJMfkky6WHb+D{(>uyKNrO{i#YRB*}l5x(~cX>?Bx9wXD-!+ZA_c?WJ$@XJ8nFGj9)C9U`T}oc8=En`Xr@YQcX}BZiL?V>L^>oqr zPv_O6v%LEZ;(T4ft0&j*Zf839`szO+ay<63`c_`|z*T4FG!_qsv3-g(-S?N(Ne zl-j}EL2`A~(l0u}u8!q)+$?fuI}Yjm0jpWO61Gx#W-LwBA(yjJ`n~IxLLVeF!)898 zBVP`6H_N;Giw<4*Y0^I` zs(R{;CC1!=3%U@WNV5_}M5Ae2YcShZ3J9I}!d^R<8P+O=3$n_2I4ij0d&S0n8v$qh z8R(=4E07rtGm)od#%&Hi-X9)x9H?1@|Dt0gL`3bd-pR3EPJ2bsf*SOOd&3?2pZbqJ zee(x~cGWRHEU(q^(Ktr9O`gJGlz@zTuiig2u>Ti{*;PBdxl&Ml+_0|5$4 zd7psDl6k0bRWJGv+?&4eyUC#ba$Y&5sfgX)Lw`H-FIV?p)fN9W=)bNkF_3?w1Z(oq zMBG2qX}{R1VRY`BovhrAQ%uNAYlDT?}Q$jlmH1$Aat$ zimj&xf{TT*raQ5t=(B1URSXE&er?NKUgB)D%QN`R|MzGv&t8<(*Ua9FGi<--|;4kFr+W~X)D37`=tnF>c zyG*+?Kv0;RF$GPdyhleR->*pArSl004i>6LS1L(k#tH{ycj_yqWJ=(1ZKu64k#*#g z9;mK0_vZoN=YV-4`?G)V*FX0C|H~cRifN&#caAVGHRO!4jm+s)u7xA%H&eF08NvvZ zu9##M?j>;vDS$OGVF6KiAE@{>cqU_Y-}cxGI2Ei`qVJ6>g~ilvPQOjezo}Re3jn2} zoYEAGqGsSOB;^WPFYal-V;%bF^i%0D6}7M}yG;?j5Mw99mQUp(F5oG38L+blf?TTW$7$ zv==>arn;~LjdFA8>f;$R4KE2GtH>%>QaY?#Xxyd+8?&4wFpJit=9X{?|EU1tPo``A z@riXDCzsEZ@->rsvR}0&c3)HCz7T3MlGCbh#Kk&ce_tTAaH`--3|ve+6X<+M%-3AP zsw&X)eZZ)GtU+F9a;J@$A`nL<<;FuCFz8s4l zt927Q>uwud_1UG7H-B7bE!pjXv<>x$PWcY!=2bI?b8yiKjF6XHi2>*Cam9v3{)CbS z9YRP4T4+h^a0@v zZElD-Z>!rI3&eoywZc5QA}Fmh-A}>}QpKUzLG%-;i8Hv1Kh4EA=Z#D?)sLBa+OIzc zK2NWM3uDExKE+!2%Ki0siKbgGRpB>xln!ExM9(lNyB5dKX_whaU`d6HR+lN`tzIB;Ddc;nmy8gcD{#7w! zr{>pOWjKKNKUIG&8g#R%OId$m@>o>R(ql&J{->zfY?HEPv=rDZ83I1`l-8kD3(rFAH@XIf)S0xf2K`WyJ&RA|jb{4EI77 z(Z!;1HUSizTM}m$hbyi{H~zKFts#0pRjNN*eoz{Y(%s=E$j^!L@49o@)e~!cG&>?z z;l&R90qIaYzrv=M?$T)1GD!5cz<3MO* z?A-W-!ho%fBF)JT&6}>-?tZ0mkt4~_TmK`i8xZ4>P9TA_M&*q{@==vQ44S_Oilue8 zR;^tqXi;pYZr<;}n#@!M-83nneFuqXxd6rEZjs&{N1Jw(1mz5v4ruj;D5_L^e%Tz@ zf+z9|uRj|P7{$Un;6Zu4Q-y|ryuIm2^j^uj?EDk`>{X+Oy4hyplaj9e6wief+QJDy z9QbSh-HM!Mtr=LTs6HNwxMN3R9%=J%#b=x1;)3$lSEh@6MqAyMA``BVtyi=D@_wJ7 z7lJ=M)FB=-J)!NQIjxx6<>N(gu*xNfivG}Ts)>?T3fb^*eA;Efics=W(GH8J=?y-2 zJQvD;(W(`@@p(@3-cu3fyuJ~?4-IL}CCycfDrfP>a{*;0*>z*yGk}<|$0A-^M(7<0 ztNHlcxziyDsxD%%s=Me1gCmsbyn!25-U+qJ&%$i{Dv_xiRf73y!fY56^H-ZBWQeo7 zr@Xbtrd53dmN0m1~O%n3`%H>t+hp(@Y*4CT908rt!&&9EZaeHtiaP`b8~? z2pm7bj~@Y$SG398U;}k#y)!$`8GfBK+UfgFvp!!pxoXn4Mg3FD^GF)l4Gh<8&aKou z77`Nj#I?e;beuPkeJ+8ez}<{omais6Ms#R{@VQ03NvR6jxzJ)37X^4orK~pJ;~#J& zK|D7kBwUMuLA(6)-)1R8wX$F8_D8?ho>g0t+2(4xMR^I`>;<|)_QFe4mu^bR@%3wI>wgxh_m7DBQ8}(F^&^AN-4g`iRf=gL3}oj~@t&3@wzJdm*OBJF*p`~OfCmZ0Z*cy=Z_YCV-r%Nd$s*)q{88oxxG zY}${cu{^}1c=8tt0U6Kf1ja!6Qiz=BB&lb|R*yRmgH%Wrj$^92=g?jCl9v(rZz-BO z-sc@ESq+-BcG$Cb81ZY-&i53+)1nGsJny;xG1mX>hhsPC`6HBO`A?>Cd6|Rzd~pdQ zmm5_1llBBm1!}(uQvJLB7)04LC_l(hMQ|4W$r*K+zV_NeV`Q!Hu5lR^-$of5O2^^n zEm#`uUr$1+(k4946T6yiQ-cyXc!RLuz9P#}@e;6XYxwQyFzqmV;j#Fg*z+Li2EWnr zbD+%Djki%$Wz(;2cRQRT+T$aUy6>JI3N@+7b1bm-qBqXK>p*yXbEUr(DiD<=!Yvlg zE_R3Lhe{OA=nT`A&rk?()gHS)=(a=>o{YE^HYC`^W3{O{%K&WxeO=kv$H#R-h#f-Z&@}Uy|w%GL_O?kkxu*0Ws3#AAJ~zOSo{+ARsUm3JHi9!R$TD$E zE6Ovg3ooOJL8wBP<&Ae(VWbMQ5Hi?_iTwiQ*0)v*eNb_AjdTat^P#nFCw}v$pj#f*wT$+0h_Yzy} z;+!#rI4SDqOH5e2Gh8mtf1EetS4{~oy7JHQaCqOo7GurxiI$127yL7;w2V@&#Pkt8{A8445TqjM=o-my$}Eg(5T73OArYzfAnivKWr ztH-JfiNcEWTjHVR;%7ehD$J|bxwBMhHlnb2!xWDfw-DNQ>^RE61@OciW!i=+b**aV zfhc#mmEjUW+ZC-9bqMu1(Zj|()4UM5X+xH0JIt_yqAeq4jE^Vne($dUGz5R2x7FTz zoLns%j@`(uw57U%9Nm&P;}i1+NYxU7L?aze>svhlh6ls%tVqm>HO_yuLWWD5`N4S?pyP zWL>v{aJ*%`+wZNx2N?34kx13m)v;51BaxJF@!)kX$lBl1#143^*7~#T)jw<3lo_8SVcVbd#Zk@ z3k==f|BqJqhLDCWX2nL5^3nHmFEtf-RCDSxqA3)~0Ca3@QhdZ6bHy^5(In^lxgV^} zdzABbJ~>kdOROE#??+Iine)2tMneh)XE=Pl4C@xqxK!@WI0Z);yRH18rOroP5K^J3 z_&HjDdn%AHrPWv=y1bE_TvQO6izEwpRlS?g$cCD^T-(n;A|5=faJhcry1bV zrFo84N^O1bIp~nENLFq#yBqG|^pi>kHky}qUma7<9BU+eZ^R8>7cwUl6IbYFEz46;4cK}O1ttPyp}{=)J|f+qM$O%q%ERv+;X<1Q}B4x}zv-(wy9i zI3z61TFujaGY-dR_7ydXEQUFDB8CmUwRlG~C4y)!_rWAMki~p)2};VPSrZ$T6F-}t zcKp=Acj%M}NvO#NK?@HXd0_LpX$&8C+@(J;Q0nVFvB)NOtqs`W95IEHTdXr3H4|?V zy>{x)jiS_G`qIiEGmMxjjKO8rt($J&LZ{v)Jlx>t)+t$Butl`?jO*Cd#^7?tDDp6q zsA9o%>hB`C_Au@fb1zHp1N1j2Q@1 zGA65HYSWuH?0Y{D-)w8t#qU&3eQ-MZ@B!dQskIO%oYwN9MF7dWM*CIW1QRr6V5)x}wjzDwYnh#zMEmNR&{+?S!c_6k zq7rAhbodBJ9oOIf|J8)M=%=#I=c|=|$$xuk8YXl;*eBc{#eTlvliJ>};#pdcv(5Y4 zceSn(>-%o*x;MSiKxlsRyoO-m+NcGY5kK<3R?z>$4?1%B$Y6bGmF#G>hQsmdTF{e0 zI9{DB9Mo;w>B*f8oqofk7HpQIaJIK5AbmzmUh{7&oT1R%kDL0<7xbTn-8d>tC}k$e z+1NIdP<;m-s^53rY!mj)8>*?`i#I54HAvSIR93}WVf5kVm<*(dd_|Qa2@g2iTYwR`0F1X#F*Z||iQTZK%A%9A7??Q7 zk1wd8SXneSe9uf5iEjZ_Ui zwJiT&E}Y3H)3MSf)@F(jC;Hud_Ij@Nc`#3l70h<2|A~?t=b-MdX~H=AU(~xFcRij# zuW*{GC#=`F#H&LtKKkNdMAmmx#Q3b%(Yc;42f+*rkw|nVupqqC-u7eaNOc-Oad+kM zx9qrI>mMFt!KQt1Q0;xV;HV6y-_AiWPs~T4P-KV7b7)sGVD_<>Ij~Y);EwCoNYrc9 zt$BM@5?5Oty$8n^`;?(Cr?r1OUbwnHWKa$E<4d_0h06aUtuNG;Jiw0+QLwIAq&$#z zTiY-m2%6vIY;1PtGzj@(T2gmvC~WN=pDaok@%9l*=Zl|AjGbENx~`3mha}DQ{=19t z2AnTacTR+U#gZA?+oib-GsHVu$tN@BMbnUTzN#E}vHXq&n-m-g&C%q9 z=(KBV72-6bSA4Eje%y6;sxEex5joZ0Kw^(F_=Z4aOUp4-ySlS|_v*eK^D$ zbI!-fM<=)oo`hvzW^-23>NEkhiC|oejvrzhG?bfj{iWg&jF z_A}~Xvxn|YgEGx>p{n!W&Sgxcx`N+`C{OGW-Q6T@yhPqTIuy0&t6&EbYTcdEX;)Rx zv?X9wC}mh$P@YEP_tCc!4wbItW%6e9s)gh&m`zR2_~-7xCre5Tsg2R7B=cNNaPj2e zn6JK4zR^h5CVLZ;U|z&d`4fDboA)Pk0OID?g1=TFCF(9PYX_jdKFBBZIgXG>;xyP| zAhU@n5gOkV?0_op^C@aak7{@-XQQQ$7b1DoK%%`7nMxbSy0m^Wg?OK1nm_vo9<0~L z|McAKoo>~*bMxJj&}ZcdS)Me$2B%I>3DH`9`*w$7Vn3oqghYn?h3tjqfR&K?+cC?J ze{+rfHX-)ycJl5MCWv*eWKIaO>HlP6BS((?h(c@5J#zh0qV>$97)V)zJ_qlZ6MqCW zV;$Y{x_Jff!;p+E@mBZroSaL4x{bz$Ji`Q+AQJ(J# zzjUU5do^WW-llfTY-i5!$JBSGvzf<*64kowN+&@+AC3k_bqUUuS*#~$dw1 z``QO^*o%AQ$uwbJ4VgQME!Ur;*53%D1F_LCzZ2MEw4e&b)1Upg=UHuRf|!TlZK4Dp z|8UJ{*tlVSU7#?LBl^b4xBKq;WM4^|wwNwo+IQEJ`$}@Mm+8mXYb#}Mtau)LGku|Y zabHO;Upe$?UnSmuEE};;s{-wA=0CW-IV8;;?w16ry-sOjY;{rd=M0j+Tiy&JpvkTt z7#Liy)}XsR#IL;r0%z!8He+K>e)v=AxRf`jE=ktJxqIlsp9{3h^jrOd%!lZw4_sGzS5=viCb#*FhCu?B)}Ux(d+m69q#c)>GJsT3D02X&I9$NhYdYaQdX9EQwTC<=A!BML)Wze zm2Tg42{pW5(w)a$j&u;8l-DvuhNODP#wKo59m-?!Bwcn5e{BnTe!iAk=yqZm`!d`5 zht|%nqgb|{)Qlj6W9t%Id%~?y9BQH_Epn71WV3|O2_hqbg;7gZ zF0)lDPGer9cLH|c8$x(i2??0xa@LVEM^$ZW4Y#Owir?alu`>M2_gnj1f-S5{OD zAt?(!X0HgN3sUV@sV+EZQe>MFlsrD6Zh*_)OxFc;KW1)yl&XGYV@&@|rytiz;A=&a zk;E4e&}&S=f`cQBHNNVLkGX%dgAm|QQdy!!hwo{Ln_YR0w@t*1OA8I_ZR{TF15ebS z3V(*E!nik3;rMI@@qr8Hrq&FTY@J;?^^bSe@B690nZZ|nz0CHhubM3B@E1LBvZelF0I78T9q;J|0uLh@ z@t#%d4%=0_e9a#rn6V3Q4Jep(q--$ZyONJJrYUNsF*D147N#RMX z8qQ-2avc0z;QCIJnR5g~F2r8xVx$okJ}G~hM?>gu-sou|-qnJEuY<0>@}`K`R*#DZ zV*;|)x#MBxn@GY&$kssI)eY(`4P-OItR9{~pLaErT-to6y+)2p+=#84!I7asJ~XQ( zeTR4=tun6` zm=6A-=?T$saC45S7-gSe{KmRX0{GuTL-EYxp5JWL%xo44C*||WPKQU)He!ygcf-c< z3>j)h9>$O9%U8(5+0nJcg~2iMd$< zZKV+oSWQ%pLjI#)1L7Y?;W#0W{*|R|p?X(C;<{qRNwmD%RjK@h6C?92P$1?M@Q;J-vMaMhhyGcOZmAK88+vorb z=eMLY`nfEZWh{+V>L43R)W=sH=);aT3QxWpDMmq;L5@{sN>8fhI+1Rj?=xGnNZaqFICG1uzn*CemCg=habv@aqg+zh+}GH%H)>5{*(wRWeV2^#g96t*R8Ats--4oxpotUb+Im<0 z5G3YNBUkWuiYu*#l6o#QWih4}=r!EnD$f|vZiT)V>)cW}PPKaPIKMT!JM(4F$CN4A zLP7ZI<3LXv`gmvJQq`W0-($lVk88V!MT?+OK|Tlp$}Shha5IGFPhTzxx|kG&>P*Zt zBEPL;czRj;LOq%SnNj@QAW}^YNcq%^>4d9gp9Hz3CVh^dUn_oOA$Pf0y|}_wu#Vzc zqMzNWwPa>_f`&aIXF)U`R686g&IR;f6UcRjdDOsex7Xgw(-tus`N_m-UJ|^SfEINELuD0V-gU>b89jWks zQ@u##C6^h~Q?yU0CJ8+ZZdH;nk|IE|!N*%ChT|}d{rwPW71QBJXs@JGCvgyNs&fe` z0#6)TXV>oSpMv_*h^HJXt4LUaCSH_JWi_Qrk(JtD;@me!TOJG?T#_+!^}H$nX-x!( zUjtnuxR^&)LFiWEn|zyR<1eHdjPY2RIyD4)_KrJJ0_De3LGlw3v;c`_MNFKjAqi1b z`I9LSCV!a@l^9N+O2Jt3y|#G~Kbd8^Q7p;>k313vIUTdJMB3JmY`5wGVjbZ|vCM(7 z#pv@|aCnw-EWuOh5-v1RE|4&uV-xlRR5nm*+3x@htjZqOzF!huvat{+@5@Y3FyTw# zG;;Jm^KO&J8@L46nB<7%Y~1VL@V3{Bez$0}ycZ3P_A&orwEfNZisya5PqnMJo)A85 zfo3+bv2vtBWFR7ipZ{r_^#>>Ac%Z|pO9mGzRPI?IE3xJ1c*tKmC4tvE?tW23f1O@! ze{-FCr!&+vy(PgQoLxs9B>^2oY|EdDi<*Kdt`)^o$-rIFN_l~;Td=5X3aQq$4bKxM zsPE>F6!h56HMN(ZRS4l~a$vb(+RaXRo7F$;HIEx9g$Bx%D3diUsRbu1jr~A3yshc+ zA((1g^gnnWA-fOxhTLpKwtSF3i6`6C1Pvu}<4#G4=SYp?G>-?{(bUltq;s0w^( zu2g!PK3sCUZF?8Xd*!(XARSek1&MFneTzh^&^?-qHQLcAbP@;!wGPsHyx&&&9r$#2 zpM`@^PNlnJ=z9zbZ=e?aBtH#nCLmnTDX5y{a5R&!6C7(3n69ox2*H;jpZ^4T356Sy z&_2^(#+k&aBrQ1hY2!0MP8#l5p`Tm9;|7G1RGs|<>ZCr;jmwJ-bd*ZH`eUt}BO_Lm z$O?-|_pS{;sq{{bMx|KiU9}oyMx$w6Mx;amT(h#<`P-4gvYXMJ7^iP3!5%`;V8bfV zneyH^-5j!OzUf3(i?uV>Vp#ypuOgs8`>Yu2S}^n{tNB0~?ZR`RLft34g`q1WMaXxa zGQ6{lb_^+!=^h$|a_M+0qV>JU zlEM0A^eIep#sQIz-Z1pbLCZ+7MA`Cj>!uaUW> zl)t`)V3UxDkmXxT0qb9t)ZU1Mi4G$fiBSF}Q(s3O4^P*3sb0D>1HlawBj}TOFv(rD zTpJf#&}9b1!jYN4lvv(8dtr<83<{TumRp@#U+%>*Z;FIkNsGs@FhBq&yY9vxze(uh z5YDR*PXaC+(*D=af^LQ{b$CV_*Q7Q$V@XJdM)rHNG(OdhvyS&v(DZ1n(iOKh)25f_~`G_*;WWET)TOYd$mRUq zdSc?0)7Nw1&jRR|l2odnS?(PZ{UOY@3R@-t%y%1|mlEDF9cF#?Ux^CO?zSLeI zmD+gbjq%kU)a60Zizv4UV^yx)W&>k|;)~l-Nfev72m_SY6^YF=ExNsG0jxIT#^j+69wp zuQdoa?R|*5l@R3~-)a;0aMb4@=E6$B2RNlnCc`nGrP^AT4L+eIh%_dh7LjU?*4AWl ze!!ZXx}z)c16im3(wW;PQ%22qd$T;(ViUbUExbghXh%+}&&hI=@3`XH@7&8@FZ4Z? z!yAMlOf3-@`FFpo2YOh2L8vMDW9p3xUz$eArx;6!Y6E6m6;%o769W|U1o18#z4rER zdWQS<{ttERtJtAerd$u5XJ3R_=w3U{#1#D%Waqvrn6v?3SZ3PS76)H4iS6wx>_r|q zmF+0~uOu)0qh}`t(JcV4MQXc}9syv=8#LeMvQ_-96V2kRA1XG;oC^ern(+ReboPeC z{tEBE2c@5~MVyr{=mW)qI1s~@lGD$Vtfm#GQ#}Ma6d0h4z$~3P2?>ZFAK%GqjO-VG zS?V$bxafqaCU^Fw*!}w1|A4yr^=j^}{@1)< zSm6`7M$UJRAZd%@?yB zI>$@A3g?p&@~tHSZQi5N2f|XR1Nl^<-G?-qvaUcm7m(+Ox@ULO~>fm^8e(8SU6l@ioT{nl_{ z7l*1bQ4`@Xcz=R~EmB?#d?Gma=wX|?(ZG>p%-0$jeL$`8+V{meI~(&+4?#6Ufh6%k z(?XLG`3aMcZ1HM!*K;HCtidqC#8dN?!V+FYO=)LkFuE8`vu+vvMjdkLx<3-j<6=53 zXB^c^>^AUqcp%M4cpFo3m7m^=uVI?D8b2+2yT+4*ZEiUoSUX~FaBVTzDytFxU?GW} zl5gc3e-S38C_j<~*q+H;)f0n>hqPKbCrN*sNcS>Zk@5H61|L6lT``H3e9JKZGAJL3 z;eZD7g|dl^$nrt_ObiixjW3=X9jTsqEx#jokg*JBw%4~aU@XI1Gh84JxnNc?3Gw#shzP2@+=8em_!w36 zz(4q(e+-&o_|gBz-(f)CR&8VBUvEENJ$;jfdSBMv{YJ%)Q#xNS3ee+*;ReM!etm<| z&zO$!JW2m(L-sZY0|^C|tTycGSa;=uRV|l(WCz<)qgfX@Hr9m^HrIDhx8i&+aBn2` z3+|*qMU8ib_nm`-nLnFfa36$5syk1HWC}FOUFiPuqWyU- z<Ua>~5Vrp?PI>}9Hh8e7J2qdP3fqcd&!=xb9jhlG^JUy7M*LtP%u<4E6= zTEpOdPT$|+3%Ck5=9~nt!C`h^4R1rJ`49s@`)piI#w^8ikNGd9&@U&2cJ;M z4k1jR7|4%tR^Gy8o83W?EM)Z;3di&_tGvDrt)j@g5e8jShiPq2f@~^L{3)t(JLhOH z$zv}Jv*=8Rv|m+?E!*>qdbsi&55w7-$%}UuRxU-P5Z++lxkop6@{*KhV)sHd3a+LQ zkQqo0|BZ&2v<_>}nuw5VBNpNcY2J&du&WhxMJ{W0M!1QK>Uc_H%ZmF?CSdK0>5U^x zGc9MTK9YqntF2YVZoXMyK}sb5#iU4n_kj7$2lIiFoFzC z`1o);!+)LYVAt@^X~nST_t^&jk#fj>jVjd5cc4CK%HMf(IwENOct#R`CW18D#;t3V56VvgIF9cf?sBb6Hm za=-jaskAQ}5?jz}?YWVvV$3>4ap&2B*Eb&Ev76%gr~xp!g_8ve!OFuHpbqH0e$G%0 z-2qqS`qHaaZvM88e(wq_z?KQg9{uBxls8A?I)-2rDc9;$NHg8PHvDamznqR*=mfS-AaLx6;tA3CH6>A&V{ufwjE8k@q zPQDbZUw*6W`Fg@_`ikwT)Lcjudcejq#}^y31Jmly7FFb1=PL-+Xd|D(rTk&ZhjB7Em(Sv568ksG=1Dl7}k zU67P#4&-Ai76W{(F`vYXSJyzW?cw_Ryv3B*O}>(Y}cxG)X)x|v+YM)UT`^~n!7agDWIA&yN{m` z@#{6dT2Fa~c>gn_2rainxH886l{w5=)r(K$=aQanKxOjug+m*l%AKsF5F)t-CNdgLRfz zPyTSOcN1SUIC$0W7ADG|Kwi|)ff&b$@=5GkQU6OpyqH~?ni1sShlMioU0vKaZ1?x8 zHxs|nuL-d~KiK%Aqsy53sKq)tq@=BdIB^##)OH7X8X4d0Z5z|gKf4eCY}Uo)h2A@} z8cP&_@x?OK9AP2RE980N^)J(3zGdgh{QDec1n~dw@x2wTQ!_myV^N)qJQwO?Nmt7N zy^E)^KmzHhATz{;{-pGnTEw$agA&{CA^im8vGy@nuc4cL@6|HG(?10oE9en}oDp@&ZoLBHK*=Tg)6%(r@3s9)`#*#P?)OP~ zpK`U;=Gd-oOcI%=!+KLhl?n*xHLck>{xiQVf!a@=#{o0xau1g!e>7Fazg<1^;&a@d z9ee9NR%#PX++Tk8VCHJdS?^x5cYn%m&gs4KhuyF$Y%05EsOHHo$4a4_pG2(!bo1Ft zY)$62;VC;;AJ^`kW&~02+b`|>U_?=zNt(+RYuw0tQB_xddAG*zCsPiYP{1();3y>o6cpaX?-2 zP6^Ky4sdq)>T=}rw$KZw&cG8TWHV+`m){%m*c)o{MhzJ-Wt!nKhrJh6Y(TKi)7Guq zuA$h00@-d|<+^LFTg)e%lWwPp~%cI<~s)9>4~-HP2c&vgLds>EEXR=zi0 zYCmSoUHQ7VBu>k7FILC9ZknybCeMYYeT#;17{x5nDhYZW7q!PH<(1sTY+m;j|61`J zq#X3IeWRRS=i`CM9~>UDLB_!{UpwYZHyW?Fu@VPgPr&`bji1aH6T^BFvRsQ^(YyHJ zq2A^auZmt~TNcrT3e0R*EcnENeli^yiXS~+ye-7g#+uZ!$&+IF80i`gU=JM3TTPEB zM13i!MGi$u2x+J01xj`}RBrzWt$(oSeK_XSx6lpAhXE#1h0b2NYm# zjlW>~7X)sw8SR7O?`PW!%dF2|7Wv792mNGXfOQrkM$cr*&K=ikC0|!Mj+D{I_QnsM zS}fJGs^p6!J8_)sgpZ0w#49cnt410rNhKScFv&an`1ry5i28>?`4t%bn86oDY2&Hh z1HdX9z_?qcE%^uyWbu%YtoY)YB7*yc+{MznJ|u>Axud2QIb@Us4&F6tsGm z1f1JpjrB0GlP(u)uQ?NiNfJW$=8`_)dIls;19KaKF7X8g9(U2;)zo!b$#>QCw5mLk z$Ajh3;hbp!a->CqNhNBfI)X0JXryE3G@n9mEklv<>q-0b2^?F4j-WH;7c19XwVIyE zCVL&XEYzl|gkz;vb#D4^WZs;;u#wg5u9_e|Dvw54lNFbIyKNpzR~`9)u|BWns>JyO zYfk3M>2sMga>#pApc8KsEp%)QfJ_vGk>L^rUr-Jh5}!%^AF6yN>(=7KD_z`OV<{C< z(!tgbNT?d{2;9@2V zlBkt^S9GPIhtLd^8zXwA;6snybQ8f9(4Yy54&|1KWX0I@)IW?Ot`qo*xk0B%@4$8Q zl76R-;BlPR6hqOJZKG8I5}QpfPC2_^CAADKG?8kL@e|%4_>3vt7?K-jf1hVQ+jO5^ zJZf7i?_pjkAvaGGj_EgRh)2cxCyB+*-;!k3-{ zIegU)f8WnXIcV>*vKlGts;m?U%YIeqT;{ahoW+PZ9tfLhjf17einsbHWFR%?6tQA( zgNTSA_`s`o&-*H}M>tmb9ibV`r^#<9B$gC*_{|T4B3l|17C^8tGR@S1;C}ZTCj_GN zoQcg=7~HD3pjhX4S&+VQvv)ono+LzscquVo2YS4Ni9yphqT67cwMI$t4}f=5d3tAz zf^}NGNtZOu=5ya-!Tbt(iOYr_0vXQkeC324;`HcrhfyM#v$Cx~>`qmmbi z)u=#aQtE7!NI`Gq)3-K0sO(L?$oOAP&-9N$%?4yAp%v4*5J}sUs;*0l*QuBH%G6)gWC~9t z#@CVF;uJ2KnyKVuwbV@;q{0Q{4MR;%C+PlU8uK!aUFq6leOTpie^k43CDH8LUe-&B zYr34y-VcU~d$6?(tE?d^n%tKcwe_$g>7#Gcb(8GfEJlD0a^N$z&4iwhu4P3EKZbZl<-mJ!g6=*y6KAI&I?C=MInw3xH3 zcI?pbGkdlo8Cu!&fIFCo@As&H5hHry^FLSnARsQ9crf+wT93WJy9;uWS*-23=Gf2t zxC=vL>?6;U#>3ChFf@l67>t}paGJHtDd(v3;-V~Yk{F*Dt0b85CJBYSIV5M9;UCw*!y-$z?izVZ=ExGLcI zT5HOkS=XVtRL)XFkrE(ZUXJth;h|g9#A`RJPCZfKbwyf9@?xyIG-+$|Jmx(T7e{p- zJEX}fFJAPySMEih*mXPWsyH!_ zY!;(D>!^KY)#)kUBP*Vc^hudo&&Nwk>KHS9O~~G)TI9q0Kxp0+IiodYs?Ev zh0a~gyf?Yw@N5bjjJD}BgZF0d=DH{_WMX4FfLrTnuF67aaLdR^S^=l?P&zPq;ARPe zk@K%}x^8XjFKf?OIcZo;cfiLX4*_kW1oVc6)ZId*5EQHZXTQH31@AV)Z|6X~_3QXz z?-na2fUWbcQ{whAMcB>Dy`9oU%Py}G<5Dw z8f?yJa(^0nSYN>^;O6K{H7#cDc7yTTHtvGk;4a>k;=w`&cGC&+lW7L!dqkz|{nwH- z(%0x_*GJ1PjwNjqTG2rh+iexwCyJ&itttt^J>lAJm(C-ES3MPq-1SOCygs>?t8hDs zG!vYhzeGWx*%KS##tSd^_r%}F|DnbI+bI_Itow7jF9Wv=U;z;9;wkYy-5 zVD)m@SMj0Zj3uKos|g8rzNKO|^~A@e2K2B_(nN_RPdIiuzY_@x4_f&vAftPQISoGz z@g#VrN+@@Q;oRlvybvh7Pj8~-yz8>LrmPLtTkb`+))O4GVYY6|nO{lEKQwoaLtjA@ zrZ`1TSN$%&<=nQ$+s-Sq*T&$O0F5q)E>ue!bjwbc2uJAtm>)4Bz2ra&Scal-ErS&tgEKuz15`$&fkOVo(ZDBeBK9 zu@)c}*)R#xi}rAANJsjSpt`R6i}v|M#jAXw`}UnLcx6kZ~W7B>4@hR26&PFNvEyur4cPi|WcA6Fbbm6cs)rPvH% zo=glf;|U;luz2X>jj|5=2Lu!*w1@!U7aeOW=hYjKW5+LrqD!p}X;I1J2a`Z4vRd&b zZ?rOiYz8P<4n-)Yq+`}1#PPX9+==x+JbLiBYuCjrH6M7M`P1HO*^G=V!1$pQ;^@Y* z4aEdJ2nVDXory-?CdB7#MX8TSz|NcLy3CecD;IWaqr9$`Wgn}z$W&^FOL4r{oe@~H zl207%S@55)Li8(=Ahwst=ic4p_ZS|!Sh!)gw0!ELOWXBpo24z`g+R$Gk z)n^@}uFx4&{PJpxJny|Mq3lStnhSF^B#82)%Bg#In<4I0f=A=$bMa`Y5+(`TeO-1} zai+A$*J8S5a7dK$f8tbs$q#MpH9ps)=FSWvAu6~uv@AYsd>vi%Oi#o1Z`Z84X^({8 zQ>vwSA_OZcFCi8EKS4CrhB@ab%t}u!ijP03;+2J=!axoUCrNP{k4_Qee2E_ENdktC;xwP3gcj~ZXWLs|SI{z`7$ z=aM~j5^vznTR#t-7qELKMkozb-%E@v!+ZuR7eJ?BfqH@gS*V)>#`|1feBzoVPT8_;DpxT?mYjOs0#OXUUM~Ov$X$!ZgNaZ;NRepnYQo%bslV)TXI1L2 z%>tyelz!d7;Kg#aUqC<;!Og}dEc@I&sbYj&$Ph`!ip^Vo?klPvhBpWon*a@a_tlFN zIBmV=zHaA!XA7zmR(Y>UxcSseLSpYOuadgkh0niY6UCf1cZr?$_r!A>ls{L!3d&zT zD~hY=@yVT0HjWlBn#p=E1l5;NI{oV3=cK<)CjHdbJeFfJ_;!2y@VO`Zog-OF!LL8~ zp)8$c73)`*P2d%e*-qQBi}pP_Px|6%GF2;gho#1=P<<)ncNK-NswHaI-fz5oFL&qf zDqlyf{tp6bg2D+09qP5zifqBQm%jQd=2@rLxdUiVGY%Z#voDgtQv?_@)r&&)Ujx6h znZzqE&+ea|6mq`N`=|`l{Pche=GXF3Z?m?DbbD^=;l2P={#Vr;<+b-}W5!S&J5LK9 zJA12N4s<$#YS0eDpD+_^Z&33_sy-SjK(iUWf&j`A1%!0Oq89NzlS=;DYL3&=LW&5S z&IeWV&a19fr|MNkZ6^>>u=}lJAaT<8z)NPyA`7J`h|V~Hu2yuZ%V@zn$VEV5)XTpb zj`VL{0c}mF^bu~@pBC5AJSp{VSYqvIGKUQeq0cjP$RJ+j0R#TA+kaM1(EqTFQjaY& zIw=UTm1m$=gRN4pLZfsW&5EBRV`*S+s|mFFOn*_z%N(C-#wV^?r~wjEpWuu<{j25q z@#lZSsOl*&j`nnKCZbeEdhW z^7jtuKXi-PG+YOQe|JB)CLFa|sFDEHSx1? zjJM7&xzeM=Qu$+BNIALs*Hy`Vh3Bu;|8?btEAE%)EC*pJ_poV7{-(uJ+GHsT{kJ(4 zw9dO>EvJZI95WvPuB3}i2CIl+WX()G7LPosu!wz{YZ%1v%6P)`kt(Q7%@SNBXO`aj zkHPrQ0!l=tfqUKW&1gBEvY;J6hz^`-{Tkq+Bv<8BKzHGd)u=v!MChEwLSrFQN{SK# zEP%gTlv{-0xvrL>>dF@C#YV25Sk==kFjAqZsYt(`X+#!gsMsppNb`};=8@_#N+uqd24HctkVLL;UB^w<5z-Tddugx)T z_G<#OAgK~ukif@SOx++FZ|>FFzi#%|_|o%c-Z{#1;f3o|r%_(j&B9g>D~fHT)Q5^H z0fM+NcXmX{=?>NG{OPKYMC!a^EvQX}CpJ#vtjBAoRP@x?Y8;ipHPNu$dWoWDYuNak zZK;yArwca-e>n&F)TvmQ)ZxHH?yMh)`>mO!vso`TCUD#NulwZ(-21O#tjyZa-@sUJ z{Uqc?!SyM0A3Uzw;!NnufiOnxgxx}hBN<+X;o!+cM_Ex)2GdGJj177a`PtpvykW=| zPmlXe|8cARUs$EFuDSkHZw!k@FrTG=!Ufv0rhu9EYQ~h79%6(TR%3?ub+VC7Z*REj z3*0n50q4+;lRD{yO^JaKg`m!7Q-bc*7T3l{PH3)_z=&`;r1KzeM zqZ#B~6VLBKRuLPP1jTiB@M36u65!yn54jbyo*3H~QUM}^gnbKwYoxkciige!u0C#* zJNw224!rRNq-iNg-th0}J}OCniuTq67#9d z$AnTv)92E}I^x>>AqMw~{ApR$Ly>7^8Rkb4rX;+y516E^N|AG`Ho*_lO9$N^UDHQ* z1RrFj@MIR)UH>@zsUhARWAD?XZXA&b)4sIKVTW0ZS{3oRbs+ z$^eModg>cI#!R#fSl+7GS<3`r*J{!7lp0PUo76f>$wTkt9jHeR2dg9fk%3Glglo|g zv5vU{lTw2>RHKcJzBC8L(WvpOh=hZ~O>1_m4Smqc7X{~i%}`KFwP$)wD1SMBCkbiu zBVu&iku>DI7_d3WnB3c}ppoXN#%J#~O^~2SwFVA01Ib1hCdnqU?!_B;YBm_^yTMLLrib?p-eteh#LrTZ_k>%|sihjk(mN4HtjN^l%>>e#tW! zmQ}oYdK~3=ejMJbCjLtPe7TlIM?hYJE!3>mx69`0SUM`n_ze#Z-R+ZbeIUHOa3D7J zg>#p%3GB3-G$Jtjz^bU-xngLleFJiH%+HuuMsv;|qNc^fDV!Og9=ofT!7Zc?*2mG1 zpCztLzOkzhpx^bdFMn6sXk?<(ljkzdX`TSGl6Z!x@klo(inYbxm1YO4ev01{+7#F6 zc>VOatzAqlzpC;s*#dy5C8N=kcw4^D{-!&i$!+~2Qd$>gnD7YZk>6+C_tu~?tv%kj-6OBf}PX_B?vso-B6AIX;!Z0hjXwFKQ9 zaHWnowEq!*S9zlda`H{KKwIqfuh$T8V?#$$1#xSP(O+qGR!PlvR?%>2Z>+>a3kc;v z&Oc6S^FQrZ;6zq2b|Jy>Lnf!LZD-wT{_%8STlZms1~Fy0NZH7nuM%Fpjn91WWA`7g zq*Y<(R@vun-eJ8DQ9;>jIZt|=cB53!NY8BpWoY1BWxkG6NX=&MJj-a*Kw@mKjZo*$ zF!+B$fcyV>*iPrUXj{Eep>S7A+j+-Gexczl3DoS-K2U6%5?F zy8DmB8M?c>5zqh8-K-V5AeKe!rMpjB$vT0>J+JDiA}}VK{PqPFXif#oB3Aohcf{+* zKb&hbr(Qf_TJco;ExcdH0K`m?{3+-8=Tg*-wbuMq@47|=8Pe#h4sR}W(ir7GD6t}S zz~xgHvTkJi3ot^cUL<7VaIzl!G31`OY%ms)xrA7(j?iJl+?F{#(xh#wBt0T2U$;v_P)}!Wu zL(Y~qI>pzCy$Qd{4UxboZLhzes4dI3&MaER&xBqFKmAUb-DC- z|GvM5Mx4FLc8nDz5>$q|Y5S>c24GV9>?_-Uk5dVai}Blim?*7y7AI7kGq@$2XozD5 zmrVJ5x~{k|#uROFnn331uN8`o?Ux{XzW7ac)a!l)0&Rw1c%^|>j#^^OXIAa=>+dF#^HgtX6x`f447&x-}yYG!aum8!O# zu^)0S(K?ESW99RQO{{vsF3;*}90PFGQ!2PP^a65TSl+dho`^Lmu#q9q21QFI;k(Uv zp{q=gx?$Ra>uuLp%3n6J6azIq^t1O=@9)V63NHHG!vgT)Fg`R0U6wLf z$jo0WS_gbKtjvas`f0w*oDV4%_`(3<*5D2qpnWoB2uwR$5KZdK zCn#?SrcSfj@jfA)ZLShaNh^2MF6n_z2E9VcSX7YBw2C~z!{6ELrFaYHHHoUL-GRkz zW%?!X(ltHe@N+Zi*-OXpw7e?lzplP8~X&QXH zvI8D)m!2dt#+2f3Q9eh0D}cvXG%V-Z4Klhd)se8^+Fv4@RI{V!6-g2&ComjEf%E~p zrr~G=(4odAKsTZ&3kgpl?KB96!DEkH#KP37c^ zTpq6$z|G#kqCow_=?h2Jc30${gGVRk>Zy9>9 z5P`ASfQD+m-)GPn5*C-Vj0w+T2B|gn)XoGRC&nGu0&kQ?6B-wuU31uNP9EkH+NXitK&L*=W5QX!^%gddR$J@mhHJfqSp- z$UkMFczy^`qe)k!Wic(ViYWG%*^bHWPxicY-)65yVvWK7L}EN+f$uw;PuG{an2d3S zmJ|Q32)^^#YlraUPjYlDkLj3F56XQeuG)@;>}CyQ!FU{6eSf~C(DO)veeE0fka~0D z8gwJ7^%u(BKn=;*DsDgk-#DL|uq3g)d0Z+Cps7-njSZxH?yxX*Wu_hHtR9dG*osIp<{&%@e2hC6(DdM-?KjB7?Rr$ux^Mx=mE0 zaQ3wI>tC|N+kjUxjyt>6mF6_A-vk_?)jK?#bz9i+2^P&Q z@y2v}#m@6{NY*wCW|y`K*Tn8L9L*~5H1uc#6f?sQf9HT4g2y|3HL@KK?xe)*cMfpb-xf!e6Zr zAsgJ3ca&7Y?`%8VA(=71k5aX6j5VAEUCe)06L;LbTeX72+xJC&7GIman@su!C$XNJ zE>V3ft+AkPLkL3CD(TntrR<%)bW_Fl0Q@)J=9+DXJYVZYj24HD073rkJ{lu=K_iAE1hy7`%vGRZ!i1RccqS%KT3_mmRfwIj*!E|1IaZMn5iLP!# zG@>-DhS2$s5|7jk4h%1#{duAp5CL=n3Sw8ll&d6EPVxp>1J&G*cqEVmK=G@h1HMKY zG!rRibYY#}lrWXpc%)uj&jb!y>p~zx;$$6~OjTd(OHf5OO;TUVem;D>)-FnQtAd_Q zgnzLs?HigKln}!%_zUVe*xnNAyI(ThAn67q z2+XHH)7Lze1p`LOj;-h4v{x^Kds56*m*P4Y(tO751Rjh28r8EDH=47bj<1uzmLlb= zQj~ewBO^T`y0#EAXINAno4SJqgGX%p2 zZa!B;&$J|`P|K|2dTp$osq~^J2FqYn@%?E8*qCX;WK@xT3(pd%w6VlCa+_v%U7V^G zVbtE~+qSMv83bqmv-tK>2XwPlm6Jm;FqQ1*yWIRGP;^)4nct*N4ufM=m&h3RJ)boe zkh0?jHqKdTY`D@eg8^BE38D}wT>ep4(E#1=Y~{1*{<76J+b1B0m?% zN##S#`f1sG1m7})mxebC#Bl%ZgTj;bwo%y$sz{WNsr~IRIw>iAX#sSd^qoz7 z{uKVK88Tz8&k&hW`x_2#lYl7cEYq7giS&|ofDL%5oc_*ci#R3AogR(YSa8>I;pI2Z z6c1c`%(ic9mw9#nUr5mkmFRb`&dEu`SWD$a zRA0t`$D=0X)h!9(3(Q(2q~)(M9!5+JYL;ExbABG$kbXNOOm;NH2;v^(YMPl#4CH

<8R$dOC4=QiJGMTjEp_%znO0&E2uGkz8_Mp3kocVztCLUx2dCZ{&bo1a6%)1= zh0piK$2m#yv;MQNISuuO<~|`8&8In&bfa0GTR|VV)RS-0-)qz39hx?L_u6=6Ce0vK z;R13IB?+Qn`wchB_AuLHR8*^)1w4P|Tx+$v$4UB-Js=7B~Qsrvmqa(2xG3S0=Y!tm->8s~bN zz1hXIszWMo!(O==*&iFjgb#*D;vH}~^ivFPS-BGv8D=Xr2ZgaB!|ity=QZL89_J~I zq7vn~UC1~U<2El9V-Kt8tCNrcFeElbWNcrCtVYNCi!ZG~sHn9$inCosrayHovE4A! zf7E;?!}EMZ^t+m(Nbi-pdl7dfB(rVEYt}&xhB2zwS|?&R93rf;rE+0v-G?4`LGec-jSuEpmMy#dOWqiJhl$}X z`p58>#rfc9R1VpR97_+0s?+vT9!wLgds1%`>m_u|ebJYyq;Rh4J@fj88gI?AP;DI1 z%gqZ2ZCmb?;7l(4f=RV!t(fU?uG^u*E;bawq*q1V^%qMzpgbo^^$R;g{e-a;sGnpp zcX7%R58fvZY*(VW`NzEaUv^DDqUu+#Xmmwk29>076Gex|sbQa5M`3+o?;A%Ijaot*;H-7a$UKzGn(~dbE%L*=G$!Go|SkGU+*WFD${y*a8OO(C$ z*y?pot={#o&L`Kq4K-Ur$eRci$q|aJ6rV(}zC))A=X>PbXkfx6*<`Oj#^c}L4{cvZ zm2S;OG72HC%3H7S99l1GeO04&K+f|p)2c(P0#|DO$CQDBn-Vp50f1+-f zMOF%umA)hn*5qNzkZdgA&wXbLX<(@*f=99=Xo??^{ZUheP?1+zOdAWYE4!$WB$CB|>A+yHo*~t4}f-=Olw`E-^}dnD)W$YU8sBQWX~xcsM$9gUuzPHE{(;ZMs3d8@b+bFHlO<9 zaWl}3@I}j9Bu~YbWOg&{lgoO*D;G--Uaj?4_m0S1W>e<>FX;8KEasxFvfxwax1sM3 z{^6J#@r|hweic$PwR6+qnXC1BU+)cm$cLumhC$B0>05fSE8=*oTp}Rdy%Uy>x)aHr zlg$k>DcImB{gX`ikvh4$W}DrCXP3B^bV5XEjC&)|z)!)}%TMaqI4%Dl?BcXo?Fq6? zy%6I!$xGsgT-V?~wC)1)c#iSUgzlcPPx#d%C)$Z+Iy=KOu_K)Y?yB3SiKyD2Vnbt)cr*KQ zF;9CwFJ7R*CH4*&z`gr{NjvxX+Y&?1z!6 z>`2`ukN}8a+F+Kyb#bHMASA&+S#uCKi~1G?Ff3$>!oT#q>=bGfxu;suTu0)7srx-E zy@<&&Q_nN~>N%BGoF8rYg9dNt&b*u1*tF@uaDLSFY^=W zE3aC)0E0smWCb~WZzqD9QOqKE9<2Fd1kM`3f4GUNad%omV%pP?P*-6vN0%;G@F++< zF>#)G)Ss_EwW07&Zihd=^g}HVYuzB9C~aCiMR4?VN@S|#!HMps0NxVAi(Zf62kjpNMmhMCJi`lhc%K*fDhp)77OEHEcQMmqZ0CaNe9K^&QMcs{u@ zUg|RT0+;k))4dy|wsf<-H`YPp+se+MBO~kBk>fvIZ!WVOPj@gV{pri#wE5|caj#rB z83gle7Cmf=Tk%yUrF7Tx6SPET3@T+gsUWf!EOquMAQ&kO6zLWnsvFC5EG=A&^M(&w zd2}ZHYS1HY9RwSDt+~W*YJWg(TDhFim2Y+G;$Qc}^@SXh@#CJ*djI*{EL-EU0aQ(V zX#=jXQ(52U&~#$G1N53OB42T)dL|`ra9(FdxOF`Rr0oyEIfB}V;OQ2Pc=isQVDDOHmu>^-xiu-1zGZA= zSZw^A?d`D!&;v3kCyW#xQ7!(;EPT&?4WE;@>S1gVGWv8I$^%1u*j7IO@;Bt)*w_4m9ubX@P?(Hu_{hjfAv_eoD zf7dc;?K6+Lq;ZXLf*o0DN_o?YCG+_Y$))`t0ekYD-^MRZohXQV3*B{2-m8ApbXNWf z{|iehm)fV3>!Tbe*f{cTvnVl*vDP|o96h*QyfuiIyD?phfvm9odf@U;zMy^sORaO` z3t;E&AI4D3R0`AWzCpbCr&%0GpPQ!KQ_E3zB14~s3YL7kvF|I;S!Imcol2!S0(^ls zebtU+CF}PM`G)z~Wrp`kJ?hR2Sq2GS$*zO$5GzOCOhr4qrQ-G$y|)@T#}49IHlG>y zs?9Z1iabol@qh{%gw#ec!;Wviyjs{B0QH}IrCB#qpTPn4GDgXZQp5q0eX_3BH^wy- zt1?T~Y!e)B8^&>sl-U5_QbR*J)uErQ(kI-zbq9BL9Q@r|%?~sd#_q&Mx3Qcr*d;x* z%>7XqV$b*2Kx{e}))*D#_3HhTC=ovOMXbC;r3z3-lea1^>$>0(>YTbSU`Uc$4X9-% z;po!uJG9gkM26#wo14zmtN_32yMj&@Dkm|_l4Xq}@x4<}ND`8H+u(X_QFs;KsWFdy z)VRWQ`Xk4fpI!0#tX*0{vLHkGB!*YWIry;ZGbs@<{tFebOcc_@g>xM?QG=UdcWhcK zr71`&q;2j5c~eH-$49((YRyWSbd38Fb)>(Tx`Y!7Jt{$4B8;PuN9tnw*`*MA+^W+h zt$e7$ou4ff`S}xW4O;$kG0E-i*_v?|0!$`tL3#Hu@;*<9371)LQLEbKZZ`q~6yD?R z1QUJp*Gljv(>ZtK!+jfqvE&r;y6Mt}R&**wOt7Q&y*L(nYvTI#5xC z2SMVT;N$xUb@l zSfFSL2@XbpJ!jI0zNx426;b3Pw4(=}7kNavm#mHX)HV)zJ`&0^RaXS=-xWx!(dd|d z4KZ+BRF;_~PC0lD&m^XMkB2|#)uvZpY6ab>=UP#Gq2iPA9(sxT*!Qt={?E-emR~0P zfK!@fll6zLuv)CKbR9Mb6ZVPXd0j$u{%L(g0l!-ARw3phTJWvYwZ`mmUa*YKoW?_U zl(pb}d?7!DnLll#JZ9S;bEPq_@|hanw^O`Tl{ueR`va$^nt-H|M>So_LyT`82fGTV z8~2^a10A=`wZ|L;$d^-c1`j73sAvy~*YcbwY0A~%+`lL&`+|Xk)PwThY`5`ETB+yi zc0crc8@xFh9JWA7Z@TeH=CfNXp~^P-vVJu%jo^ebsuCT^0}_EY3peDv^wgsTL*Mao z)}KVn3!4eSAdsVJ1NhS;f{f_B^i`=S-h$=|9 z$o1l(ht(IC%!Ntqe40`m9Rhp${I2{=-lt}Stx5@spQC+zhzsHJi1V=j=cAxbSmwq( zG>8h(4~a&C1gu%Gwb*ma%RxiyxC!U`~vCffn0^a#g3K;x#OMg$5=n1j;1)%=DQyo;46$ zp*g>nrpw41%3*<`mxKPNpBj|gdMbYb8Q{g?Zpb-J3*}lJMMzw`tlXYhYU!Y%(K?~V z?qtS+rm)o|JW}ed@|Qj*6)E@UzOe3Yne^RL(w=~4+(NkBT#0YDgos)?lQs%rQ&Fgi zt_JS_`M4A^c6gc7;7Dt(H}X9W~Nr>krf= z7!yUvmiLQcI5OmQ7H$h5MCyg*f$?wRm$*r_kh8;IF+ zud$RqdaJE2vR=eM^HZr!lnq$cFz*n(!SG6N(?z|QoElZWd)%={5l7VoOMPveP&yZ{ zv1f7mHS88arKT-C9{6f6HCVpC-;f{<=1ENa{aRgCjCpx?-8;t7D*L!g@Z*K@*0`6Z z=E_SzN|tbVJMJ>}q|Uj|ci#9d&$7=udPAq@J80RfyeCJ|Y9jY*E*9BcBw08fLc@wA z?(CL4aY@q5!9l=^jhtCxZPMEC>|K!yJx^`7L(kgv*)&=tOfEiGvTLoFSr0!IQ+YJ_ zW`^_Bs)ou?3hG19m8Z3zc*s5og$l`1b|N5)Kkh}LBwteuM|Y&7UfIZ+?)qSaHNyZ#kdx=cW&rGvcO|p2?4<)IjC2$V?_G4+ z&PzamoGiIVhD4%2-H;Ws-hEa&&O#Oj-q+ah?SY9q@_Tdjc9|AU1e=!~9BjzMo2+zO zb|j1Vr)}DQ>XH)mkKrSb+jaA1Al*zwv{kII&Vyl$k>|T9uZ?~7-N!FyEu;b1WwO^* zbPbO$-ej&{ne}2}$AeR!N}My`$pPnrU!Kk5ac=gV*kmY&(0&s;H`ZV0*PD9wOj8{q zaompw0T5WvHb-z)H=9??k1klDMs#{TX}4<9XVFzCyXGficZTbeha{zr{>WGA5;E=~4>EwLonc-bZX_HfiElE-S-d4yY%hhW zvz@ON=uz%ndryAFBgdy_3hd1fD!YloF}^=eW6vpHJtczZ?75N6$CSPWnHC0QJ()tFCNUNuSQXZZ3agd%7q{s}n3bggR?Ns=@ zSab5kb0X=UKd&It93Y1{=ac}`nW1ZD(v^&*^6-krXR~MdBL_+qfiG+UgJpxViW2KC zYf42`7m*(U3Mt(OJxI#}cMW?TWlg)Ye#M%5HU9H&u?5Eb)wcZC3LI-5igm1gXs zB+1lq8-(vT+Wc0)UEcRNxPc4Zq8gZE`G_nqB40~Z&UFh)lbo&+<2~yT$LI#8ch@~Z zwriBU=?ED_tewVQ8dMezzjB7i@s86goRL z8J-_)tZ$hJyueh$3-@))UhQ^wP{|z5^s_|{0w2sgoNIGo58b&Qpyq@~34flyUf%0G zyAen0$I8_+J!#y>Mx3;@i7)401l+#Vt`j@=CRDe1qdSYJa|^6F08 zmnWzJ3lnT>Rw+&zI!kNUW_sdO>*k_&I1cUxTdSU3atG^5#VIM5#@~JeN_tq~aVc`g z-u}l}g+SdZ%d+g>=+Nm;{-^DF_a#9R77%US_JAtqc>3lC=u;0^kvRGCsI0Z?v$deA zletcDRYG30Fz6xiSJNu$2=1g?KW>g+w7YLYtC$Am_B+NhuA#VZ8E#D2TIE_IH0#;5 zp=AT?x8JlePovp>C0%CCwEQ1XX^S^+^{aT1dmYK=@J zoSt^~y`N`yNjLja-*NpRWaGtmwoj#x9y8w>7|+L+>g-;;M3zhOafxNq{dEqf56$c=qKr|D{$eTc9ad5X(VW6lIwPNE#C?2Vwcvf0tAJ>RiK= z@SZwB=B<>&ncpCD%{Gz`lOe8J3Z|Z%0fEMRGZJ+}h7XSfb@g)=Cw9FsH+yFIr}6k_ z8t2ow z^&dz3lT3C@;B~&sA3MoQSKjZtw8-`IBj1OUx_A>D6UpN@yj)A4eKEgbrd9bultjMQ z!g;gUD>LAA4}96xMxa6`%08BYUv^xhr=A>K#094|dGr`{_kO{M@Uh$-Z-eyrcxyf> z(S{yBn!P#t4mryxTR1*jleepVYU87B>*%{=o8cGJ2OkZp2$!^`P&9Z?7`Luurb!Ve zeT^dPP~bE_-Ao=2*@Iy5DREDUrQy#i;Nxk%jteZg)tFL}yv$U|)Y)^NgLkygG*+qj z+B&^3>87G(gWa=LUSZKr;joqy=AH7T*>?qUl#Sq*47k-}Cv9D%1!Wxj4>3 zbR+Bz*~^hub|(%4U;K(9Hjp_=&M^%<_eDGueh7p!4LmipU3IjH1siwkA{w@)`#-I! z6P%LGf|4eSFxOKiFhV6M{~ZtVfPNV#MbYDy4Pd|ns3 zqB#6CxDzsNu-_D_DHC^+V)sTm)Z4C1NAssZpj%M&8L0h9#|4^Clfw}5$it5-2C`gD z69<>${k^<$VGZc_vX0au!_$pCX{p?tQa}ImvaXs%xSZGfK`r}gtr+S+>36oT-`;r! z^*;E{2L874>AG&;-X-Din0bpGse5wX+g?Yfe+wOh6qStLh2_$<-!)Ifc?jqW`t4yC z`gw3W+#Ci~c`4&O_?E(Hi`tyZUtDt-Z^9NDLF0pcOzsgW@`eVy_F24{;L5dsDCEjsUqy22O%>!GPD*eRMyFVMwKBi3Bfccal%y zl61=cJuTS9&R?uY@4iz)gwafjp7?sxff!xuVSy!{>Qv3_Hb!-c*%ZXBG)_*B2vt(f zI6pM1F~*%sF?MBU7^6%*Vz6&>0tX!z4WiS822IF3Sav1x(ZH6dBG^@_GesaKx!$uo zEjv=^o+n&Ri3GLzu+w}z%rGW>DaSkZ?Xq!^57t}f)rqYw3O?H+v?1YJw~P~d#(kCD zb5W&rx5Z+7v6UpX{Wg1J?c3v%i*QDcwB7H3?yIxSH=M%N6?6@3T3Lk&451EYF$0)&KZ~nL=O{lZ_q^ocx_C>{^K#&W`9xyTAifJoeOd z(#EHb#Ahm@D8bZDF*i%N#4xb=$-Ol=mx^Aj57KR1g?N{%$_*!!>J?}%G=Ya-bC_&RA)v4i(Z-d(k5tQI*jJ4mSA(>crx5J@YEH^z z4wzbsd)O(8?~t9de52KU`szgVz7LCZNRDh_Px-8$ zT$9ItX3%pg7}M!g4(mxWgW|}oj+?qgG%y{O!%k5~( zI5`ZPvCBl2POz_JD)P-ZhMqj`G_{^>Ep&1c5vpP-)8k}6&qHsJ3FKg0O0wPTTR~DJ z`QRFY`HI>8#)ZmMbHF>^LbLh{!8V{nglK}>Fq$$K-qcCzpwO+26MU)hR0pe~65+%C z?dlMeT#ro&Nm+3K=dpLt>7j6^a9@AW^=2)Qwad$*lhKzFS06bCK)>d+zwsA|A3c)J zNFS^P2<3!6W!83YwY?0AA<=WwP{xtsqKQ z$0bo(?%lRP6luh1^vhQ!N4vA9mWD$&($fKa0m?IO*qtq?SF|f&>>*C-S3Bf`pGg7+F?$FblEdf@Txjnaj*5X$)9G zVPDSK3rZlFpa?|eRk&MQqjM9N!G<98eOD+{04$3`gs!q=0ZS6xh@&y##@&6(UeJ_505iG4ko= zz&rSma*h z^V%F%()r9Q{z#IcqP=U~l3vtATW81lWIG6@yKPPn41){sdiWnClU&ynMraLPF`a+4oaN2QK4Y8d# zPNLS_)e8{zYJDD@GA?jxinHWJQ|V4W$+#80;}no_k<>{xaEw(3nQ1ee^vKdZc;+Jd z(u0mHi{~R>ci#-=(bm+jTFj=R#H#?A^PCu|wAv57nAva)N{=Wn93EXHnT2coZF}s# z`x&&)%k?b+a)KtrS#ODjkf0Q2g_^T(1(BcvOR=Va6sV%5{9@M4)wwf(!4YF@BXByPerEp3TA80k8DE7NCrj*geDvk^YskS{7 zbn3vaPn2nlhP*l>cO^}owuEx1t47pMTsW$S-e>5vQI}aQPx4)R9&kAQsbjQF&SX*? zN2mo*&*=4sJg=SZj}j_O;d?sZb19nN$0jR7ELA@~UWF*?l(whMO8LN_g4 zR1rG}bx@pWj#aeY5ET5DTC>Vcxjor;>9|dB07*lmH#ax>TJEc)*d_M~_0HpWpCYR# zr4GdoKow5ep6c-JAITl7k&Ov*E+vi>b|hSVqOsZ%zu{o<256I1TOSA2;}P&_7}+?4 zW0E)ZYGx1jki#BV_E4($iGvjgnjkKTAeq+gAcv&Mg_=9Mjuwq z@GvGnBc78TwnYtjE1Zl17-!6Dlbj&IFvRJ!BFWSx_lr!r+KYdcfz2}U{qGq505*s!=*n%X#IclxQlGm`Ue@xitQM1f8~{P_do8{$bCHqyklQ;Zy@yBIN{qN zQEzvx)+loLo7$=`#yiZSd#QMiaYqwz>V$<3!GQ=XgLd(R3wgjY=k?_fj{I#GzXrWZ zqAlIA7Dyr)3CirmVx|A2;<#Bp)Ywnn3vjKBCWy9jy;CJ^b;myxf`@JXP_|>)#S1yG z4=KTb?0V!@VQpaM$w-P}l-u}{O9xlP&B#cV2`0Iaz}rF0i3i{#=&CjXO)z-~vO zxWdGJPCu3(&)O~zYTs6@JTzdq(V;77Q=syKPhVk2o^4`ZoZ;K3HhuM&hckB9RRB^{ z0pokJoL~Rc39QHYPyO@%=Pn`JSK$6*iX&X%5|_4Z1G0nLhiRg5UQnWL#+Qr=U#dkb zERAp)2bIuMHTEpdU-!+D``={`6?knvE^m5gO#s_Ew}gPz2Uf=hQ5m^oJWPSOb{c4J zTbQUD>D4*|60swTD@`dWr!O;p%Fqk{38413ROEnCJ2BYYP+^Z*Q2<%yP3P-&%p5*) zDCt|ODHv}$g}k8^o%X}FcfJ6)(To{5(JVf;_F{_KM>=Qgs=$8b5q|~(*{QZU2@?2X z)O4jKoRKQXowffG3pt3Dm-9b>`20`k+}`eywvKJSh0OwzD4ZX3xa2Gkr1aWIdk*?9F;#em2KXR_)3TW6x{pYA5DM$%YP+XMLh*gm>4_r zoo&Au=2)4@;LJaS{0{w_2Ex@0>3?8^mY5i!^MsXmo1!=CJZ|1OU#FJJyr$=irfvUr#UM(^rrcsrI(tpcbd@M42Fqf1hy%mmK_pQWKu^-%)`iqm1(xLdhaXcsjP<3FED^C0s%c$%C+|&kKvWk1Gq1F}031 zqwwm5kqGPjmE|fI17Mg4Q*g)tdcYbvk}Ivw^?|dVvmIXssqb_ZlZ*uH_jJdJ&nqc? zXIr~oa_;<}I{t4fZ*0tVAKGRTj?*O?k^NK|r?TnqY#u=S6fBdY68j^67u_0NL+E$2 zT8%r=x@4GO!vh?EytO+`<>x3VC>s5(0kGi(k#7f#|i>Kqd1hY#DUvCN@7GClsP z-&W7|mmdC>E7_HkrDfYHSj_=X^L`E=`z!Fv%~FR!jw+ebfOeCJ_N6QviBz$}4%v2u z8_#e$U(UHK?d7DQd!trlCms1(Zi>IEfJ3fJ$5ZV!tnB<2+RFT=HazCH4Z5La8|q+1 z@F}Z5wf2vVe-2~)<6Hmy{a2Qhs#W_>fLn%A{5#S}jPO^kkmaZ&YzHhJv&^SUVs^>I zXaA5$KK5@C$#3K>{^1`x%=C}FEjRvRL7SPS?O|Tq9QS`-y}xCTbG>&#UHpVTbK_+z zQ?!Hf_o5wgD*s%x!`39f$eJ`LyMdx3U%t_c?3n}O#fIyKIK`xhRB!84fGk)rD{H~f z*i%D6hraRI1DG>{Q4lu{N=4Mirpyes@3a z829#am~?-R`EA=6DQ6Wg!?BfzghoNA9%%oJ>6RXugXyqV^23$YZA?Q5`RZ`%obDG5 zmlI?LP5IS|)Up?4Tg*yWN?9_)CnO@H@>I<3Mfvx~@$tHFEjOhpkahy42tRW^#&a@x zpt~velVbWC+q_l1UK$*pkG?&}hizF^A;jCa45l2JmF zJ?v8Bf-;yR9ojLSaP$R)-HR_~8gWR79tj2hFZSL8s;O;V8;-q#o6rOVl}-?l(3>bF zkU%J*NobqitMq20_l}{r00~WLp`%DI3ZWAMQk5=95fJ^e&%O7UeZI5z+4sBm|Hr*! z{9z2ng1M5p*36u9z0X^or(W`Pt=05K3(-oEg}R33-uR{V9xZM$sLdcwr^Rkmk}k9- zXVG_5ihH02n=~CteWwwgtlXHEEA&7Sj-b~wa?5?KTHU!Fjg}WTik;+`D12_*l%696 zqnYry?x4-HGnq`M1@#G?bV(tU6^G%gi|c6;NiyF2@@zLvvGZYCJQKC=ibhyv=(G(2 zGy2x0Cv!V9R4ssU1=%2N2n3?k3z4_`k2(B@l9*3OKJq&`Fs#WH9XA;4>i0-fR7_Y&M{+e@!x}`|p_0_9K9%7XOMaJq>76o}= zx)sb4h==ChwTo$7^v%tfIX;!65*uxhXqkybZ>JCWNq{?kt>R01Vl zT}R)x^8p3aICJEwSS29cDc_yyqLDs~vl|*>yKT9&unWn_bF5qC`?>|%@vGIE;DYg% zVa5l#hjJt}S$T>c6KXi9c$%lft^DS5jjS^EAFLCe6+O}`_9zXQ&{Y03Vnr?fB7MFV zLD;??w#7V7)7Ko|5R^*QJh=8Nb#%H6v!L|>D3nxQb0@6%Evjl1>~U;KD3f_u_e$s9 zhYC0nQ-%>KylFFyTS#Df;A|I~Is0L=Oiha>n=OKkvf@<7NYenyZp1duX0r0BuAPzR z`@$N7d|8&4yJw0=FH0AG?SO?}^PT_;R~AnDplynz^?p&zN=y|<_Y!H1S<`>87QtmD z0kuo((;iNK3+Ep1%mmE8;$dt^bYJRnohXE{C&CN*O8m0(*+CTA( zHJeIUCy2^`t~eSC$f}uk{Sp$L1xhFyscR3jvw6XJkYrG(z@x1io)qssY+qG*7L&Ac zXjf**Oy&O7HX_2_7S#qu>T`YV*18Bbp?Ak4c|bDSXA1BC$6N#arJVY|pZ(7d$Pzt5 zxKINBE_T{ppP?snuUdTe!=o-kQhfl(^DJm+x9)F3u5$F6mq|jd0)G>74gNPF*Gq0* ze`E5^0o>BQWc=>&gOA5ndS7qpkf9jqv2HKFD~N-)w&wfMo1{`7jXw$@&8_HTNkL`u zqOuNca$@MeamWJBs9;T1#SDwPOLbrIp)|4u-+C%ww6B*p?Y!?rm%-DLtWP+7qdN-I zObft$wvM%Us2nK|h=*T}m38NrlP6@uLFVcY)+W2E-*|pbt5hXaH!O*4c|+{2>#vF!#K*Vk*|wb4r`45>dpZ7b^{ z9#k}ASrz9%%~9#phL?4}y(UK6LW19-$1~$XcEWLli1=CzPd;J{%}_jI_1jCj`s%HoQ#z!=UA0N`bT!b)KvAHwH6NLbJ`@beJRTrNAZ#a(agi! zA2KVuL^E`b)78GkF)^FdAoqGRBC4m*^MoC}mTLK?H7W+SVRfn$OO9%Ku6Q0+CI_31 z_Lvdfr1`jB;1s-zX1+hHns2Fi04BR4BqX$hdXf5-tUGDy+K0=-5v`AGXA^!S)FkhY z{1Sho;e6)VcVo&`Z_`m~N1p5wZ;{A5jmhrr+S!d1iR$@^=_#+p-}q(8@9w{&J0>za zS(8M=C#Bn&t5{Q7VwLPXWa_*xBAI%rF8<*xGNrjQojq5o51Hgk4@$D~FEl5YY9yO3 z|K#xJ%IUcJGujsZNW9!Pz{a)p^~abxjn@F}^@}?BE3SVdLkZ%~Bl89P8yO04af>h( zgE6`fxL-^b^u>~`D4(*p&3!ubRtUapgK4_juQ%t9ChuE(l@7@&BhTcEC?+?s&xgJc zjcG1bnJS{2G>g{EC3rMYFuv@?faz+-WhUAS>LuJ5EK{NNj(ilg{fS^jex2{&}$8)=9I#Zi9 zrqy}L^h9mI$}I3fnGg>~p&fUnReD+*kx$u^eLcq)#zX}>2RFS0Y`piU%;r5tmEFpT zoRU^$qoRc)RsQkqB8+s^3~LxPOyKqlO8rJ~xqh&V=h%Fc4M{C$l7_MWq3)OA4;}VZ zyhDs4JlrYhI*VWoPXO-&$;?GerP_|pXLG5=eh+7%M?{f_sS3q=8JTUPk8XnrF1*%^ zk}T>L;=$nAC<}Bhr0)_;vo~4%qvo*7%t;@cdOrMwN+okb5~tj>K9>$=q;^Wz%F3Rd zJsCp<2%WC)x{Jg;s;ik4g(F)$t{72_nIo1&E)|b@ErScBXqNaaz8Hl#aqS+7hf;UP za(`2qy1==k|B{HK_v)+|=W)7W;A??TXUuxBDnX&JUYpQ%rHT#RA#*n&nE~i^@J%Iv zn%-Q>>Wq7dGqV9rF&wT4tsAtZny>{99VJ}4_<%|>^NQk16VmPaH$6c${(6FFxvHbR zPTZp##f;XP3oS-T^HAQ$ia9?3$^~e4`xA3kR-wgHHzyzQ8Tv#lml8*dQr?QFunb}g z(?-zslnC+1^I0VX(t~}D+-yio(NO$G>-iBf-zrP|V)3}yZF`1L2$bFPxW*E*B zv+#K`qBdc{Q8Gw8Q6#Id8Uy_Scrt{oDOBzldFVPg@KjLuau3DJwJ{=p8h+Na%4N#Z z-}_xrNU-E;f`VdhU9;@Nz3&~JG$_p(vy)wVNgdloPor?{l0RkyOr$CiPw!F&^T zyy5BgK9XgAg?709YDdYak9Hnc%o0K7eIaX=EJ1i8a$da13BWsxKxYnHWum85&{Au>p z-_H0i{vt~Ypb;d?XyNFeuV2~A?fd~alO;JP4>+auk_=ikg#Fyl1m1j@8Of?sN&K4< zjR#4ICg-Os;B+y0$i7y-aRQmz!lZJu+SzSr3q;QSL8~d-=e@JqVpN6Q*CD`gYr2-N z8`iC{NqV4oli9+7XSFGPZsr1eTo{WyuXtrX3SxfNgYPV)Q9l~b`-##RJA~rO)bvXFzw?}C=cwCP)Zf6P5;0pK9!_%PyUP3?cd-2 z^HKRP5>v?BPeux4mgwJfBn&xv{zk`1qTzn3K{n6+G;!)afaG)f3wLp;#jcm0U({+S z+y+V07g6CgeK}Xj46W~mV#u6wpTv4Ni!sW@wm&OKfVODqyT$)faIt(S8+JEU85sDm z9I$gRKBY2}CHysBw)kyJ3*NY3yQn?<1S0y&sS2m$G8~WAY6<_0qs=qUT$eH>IdN0w_f9we%@&hblEa=26fzM4GV;(Hru$MRVFtd ztMjatr#Ch=&c3|RNOrZ%d;1A{T+#Q~)mH_Vo$r`+6?fN7_IP4f`1`cas>7`WyR?%? zvHTv1)&?hP8^i$PDioTPM)l%7f|n-pSvpJ21MFLj)>3{ri=i0)ivZUT0GRH%aB=H0 zqdp_mSG1ND)GaJaYcl`^bCnX)nVKt7Dp;^&J21z1PCB{%rh8Ru! zG5oGov!Ny$>GTOE#5NcesadKt#nKnAS2&~v$L=d?Vuc3ysv?dRbV$iQ=6Z|)%DSr` zr0sFH=D5^ zb~>&7@^kQws4~@RS8mO;Yud$4juOfwNo1?n_QaoKa(AnuIu#>ryUqGoGdc+H7n=l6 z3aqc<7=HjNH<%8nr)YWumUQBkojh1~6E%H>28ONFICw&B}W%yIzDJ z{!6*$uo;(~udZ>{o7iuHkeIFk;f*Ro+n6?g;#X)YwM>wfBv&Pg&tc9yytS<4B=Y-* z&#&5N$40-C6u@07pM0#H_u<)Xja;+u-d-3w8LGH)1AgLYvTkxf!Aou3c>XPpeQ0g1 zm?ji^O-22@=#jTQ`{vHt(&D`b!*ah1fAP-;1O$K2_$=@^^#>sP8}i|<$`KRi>g$OK|iXnzw2nO%S3TKn? zkx&hOsPN@|hCg&;DPY~y;cAH|CXd*sDLARHsk$SW`rf2P4iQN z(5=bW>c}_44N9MSuq2cWtK@oo!Sut(Hbm3*Sg;ND^P~ zi>DCpToRi!T@p{pGzfUwltfB^NGk4AWKyHDZ}2^L=j;zat4GD26zCgo{SQDK<;hs< z$a=}=@{ix|pJx)mS1{mGcrlYH(~|9J@Gh`cPeu_k;;l6_ZIW-CU^{HC!^Z;~xXic5 zA?f{AK_+9zP}02%qeF0{mDoKDnZLmSk^);AGFN+qct?pV+wzrl8h8^Bah38Jd@AnP z%;U1hm`S}kqxavQcx~2vFS0ZV_LAKJaMs4WAO9wW=No+l%jYXF5iBoa(6Q2i&f8*X z(gL>_mVa@Q>hwsx(jf)NI4}QD$-=?eq^oH(=y*;q6wzrGA7R-e$;#%4V(bm0GZ7 zyvz+_Av?K+eJzDuI$)BxQG|L+ES^oCpNg^U*<EJfZTOkFAdBRHPW^87YC3pj4QxHZ$cWNMQAL}Xvy`ni?m9gt zX@(6jN9yjcwXQ|Bs8f;6`6m+LQgOjrEBb+vm|;!iimNdLTj)bSQS4 zjLMcGw*JcSn8o{-!Xk|kV;H5TJGSHJy7z3gkMK)xxXjVzo&NK(%xZKiJE$s-T^s+j zJMViHEVqrjiB(iO1X=~#u;Ie!0U@dxtaYGC^}?|6l1Te|SwEESsewlAhtM7gSqdcf zsdYcs@;LLHQOZYWp04^cMtamS?{->uO2Q0^`f?9R8_q3r!y;P?EJg4$hDvS`PuDWj z$zW%^lp^z3qb)@jW6?{P4;8z#@2xCXCu%FSL|&{MpY}UExuYp6>kP&mS;(8$8o?7# znp2y~An8{u3=8JFq6xLq=N<@1N)2ywAG6AT z)YwYa)JW;Hk(m)JB85{)(p6e>ZpU?Xw7Iv@Ey z=`=7ui`aM%3Z|6qHH3mnU6-Y>hPLcQ43?L~C?+;MAJiofg@h;vPxX2RLVLwdw(nQ+ z=(|0BPP_7f8<%&VpWGs!j|Ax<<0iPcy2N-=G6+He`6X&NjrAl{ z>mNQ8VaWcsB;P-O{U>q_6gJdheZv!iKL8=zwHGrnEBd~E=Vd>4 z(3`qAt&)TSD@ox6KMn`LsmpPH*{R^1RvFwEjjA?7(glO(ONa-ji!~=Ox`u@iYtKwk zyG(=fST_$p&#GB`qp)jHb%BAfsDCQsED zpBEaz79kU+K|EbXt`hj@L?W`B+94r{eJCZvugde?K5K(=$o>94pi7N%=hL93d}HxEVgiR13O<9#H_ z_xsmU{{SZuT#33J*=iddL|6Q$IPq}%N~{o5)VrgaA*oFUF0H{`K95Bf#t@~hq$GT* zPOIaDZ8@43oe_~wk+fR^A2#<<>|mQwOK(_fGQpoYCc6Q01b8GC`0(Ad`V@t+JIAR(WV{(y?nV;I&B_##D=y$6fQl zej@Am{w9~t+aG{n(5X!_m`08O0~va}=jBJk)-A3$b~%n2#Xpn-l`>)m#44!VE+&`o zsD(D!4@Sz5_zxw$idcD664pJ|fT_l5w66r~#W*Os8ivc4J8$MHVQgSvp^*!-e*m0Q z3Px8%Rvml?E@OcCr;(Ssck=F~qI_;1##N)xiX=!Zxb|0l0$uy@8Q^LA?|s$I)9N-_ zJO|0Tinr@WBJps=Pw&OxC~=ZTS)mdv&Nir;Au-6p9{S1mI*CHZ+h_94>}+@|?>MPg z3IG^()f?(D9!~yd?#Ac@I+Ea>a%+upk{2^QmK!VO?ps)0BDbTdq`!Q;3H0+Z@w;wt zA*W}TV(b3C zQT<^)$G^oC|9;*-Ir!^PI(#ZCIko5|sSfa}rUR9f7QS+K|LWtp2>!MY#F4B9EeleZ zXCF2JI8A%&XYR?r$ejAGKokMkfWrr_6Ea(o%*+LF1Af=EBUa53w5O|hDUA|l1iRsB z*&UK$?v}p(awkJYt*qts42-Uj1*UD87hQC*hA4B!u{B>AWj5_H*X4RJThQ-VnEn9c z#HU&u&huL?6quFu#tHOI{k<=h8yJxZPhuk|(RRqj zP>DqFLAw61>oX?Zn#6t=9!GuQhG!tUJ*Wsxy`EW>qx9I9YeKDb*5*6n3M&Z-j*`K* zRbUAQ?Rl9aqQ7=mv2m~JfH-{NW+SnV+8P_4Maq%%LAz*R9nHKg^^~v*(LjY$ENQ4X zDFzfSszwIyq{tx#8FI{d>UQz^XoB6uJf&!$4u&cn*;_s}5|IeZ*4neSdLv%e$anq? zjYT%wy9AoUvNjI7^rlAR`)^X2eOI$x2H6Ia+E(Zmxn0K*D0o283Ld0l5DkrZuI&Nj ztX4K&E3ioYrS?D@B6jbOZk^?ulKu3)M>O4YZ|(Va7#yehnwuayK1qtBOCy+%PgtFg z2MJY6R~Dmz=@;p+G=^m#{KTri$8b4-KWU@j{QRZrd21_mpkDbk0dll<7YycO+#C>x zrK{x_zch5($vUhzs9d87q2O>Bi}VnHM-1B;W7*h&(GZ1v)*%p>@)ZC;zN5lBOq4kM z)bzHayRFt`ZIGkE4E_Oz#WDU!rtZ3AC+>u#acwIrUn+W_c%>&Eb&^m2z4CECq&B!f zs{|JVM(gAiDnLC#ANrsf;`wTr*b7!kNk^g;7cxZl7zL(o{s27O#j*A;=o2{2-MsR+ zz7@T{isf81uAfj)TX%jJv+ILy-v9f@O4+J@ABrTAs>?15tCM|%xAa^^@lfF455Q47 zF-9O-FaIWn0RI7?leAu(IsW-35hjwYE5?!YVkgag7@>)}ZBZtzet3=k`8&p=X!?z7 zBvySpF*S+G^()6LJyoA<3ME9V3k!IPGVZZn$_KM?aCcqJV3HVH9%xwRa`Uo{zDW?& zi(U>ObT`K8SsMxF`?>i`WnGivs6HR4OPy__l}PsHFVTae zp`f^4IocA@;JW2rf4-;X*m;83C823zwof9kv-H$5M@waeX2XV29NOBw|5^~eP?rx#xYJE zFsE8Ss44dwSi{1_0zyCu<}Mb^G)exa<1A{ZD>#}*%J9T_9?s?w6p8{y2A5=9A7xhR zbJj<#@nwLb@0Cy{tI8Wf)kjixIhXj_ENchgqC?^eI2x;hJVNb^x{Va4AH$B4E%WyU7 z!sQ2AUxTm)ng+3)Y1^(U5yS1Xw4iM`4uRh_o=d1XmbGwNqKD}Dv-EDLq~Lcq)IQSJ zTvL0be$ds}vA!Ye^zoX>O+ST@12$V#0ZIy3iRh*;-@Vk+Mw*Wb5LPvGs>)NI@T7zZ z6Jx)zy;sM37*IFQyd|fU9tlkO*EZzNFA@u1; zhZ9eg#AFd4P$ja(z|oc%Dv5^7O?5(p$?>Jd8>d|FH~4*;@+#4mO4E^hCH9=O;O+0o zV_7d}hpai03LwU&iVNnO$vIlE;Vf>MK$QQlN6~U}*P~g!r{IkAKPAz- zjpF$p9|*Dj0H9F69Ab;}II%?v^82h-?s9dfyP18u?+Wi9Y}hnoF`L zqeb64h4$aUYD|Y%aYjv4pqzqj_PWB zB6cR<7j8FRu4OcHxzq3caw)Ywutock*kM}-iKFCe^&K;b^lx)!+0MM*kaU8r@$LGH z*+~5{Z$ieaQ2^j#(lgVP!1M)mXMs&st@gKfPQ*I1W=y7Elw6BhE*VX|nk7I=Xix{7 z;;kc35TN~?TGVgcHvjPYUkf0}qW_>gou6FE|FZN#wEjg)XR&Iaf5T0xLw=r*dXoZl zJ0rfRPb!1;s^6ZoIZy5{l@^W56?uY4;Cy&Nym?-&A+R!5o#*hp#XpQ5;B3CIC}Hx# zx$0G5HUAI5i)0Q(3phsnul5;S3pV?*=`e;jHqN|Z~h+|pApz?KOz^9fMrQV zBZ2 z^U0|a$pqSA#3QqUtaAg~gy>(9jpwxnfr%QKWE!>1*`3dwv9w=wN@_YIu+dDJTNk9{ zrt;d1JH5%kcC{{sBlflq23Vy4KBgc!qIFN`*ti z;m$7u@efL>qU|aBc?098xHoGE%1+{=GS9TS!*4GPo&6H&k}kqCK;uj08Fw+MsE!gH zZTF%);yX8bzw+6Xp~cE(&Jc*Enop4fWsxtkk1*!CG_0Q%J+Q=>WZmT5_tQA~hor?a zPm4RbD(|A^9?~jBHuOe|e#jqzQG>W?xIf(^K!k*yiod=>Iiyq~y4NT+vp>hcx#@xeEBy zrFNdnLadq$EFl(;zdz?koT{)09j9j|f{`kA2EzL9*fSjYZ}q>>PubCiB-8JbwAl`? zhSC{JaMl}j4H%^A!t4m1G?Awo&gG5XqlS;?G-zY4!R5RS%~|6X3nO2Rg`{z3fmNgS z))}qXYHUR=j*8dV4>>D(@YkZmYV1@X1z80uwv#Z&_8$P4b|UofYLrvX&sF?kk|$ZkzAR>hFBDt%tz)_#Z_0)i9E4W2PICo?d2mi)4VUU30!}#rpR3{Yl`x@>R=k+8h9dXQe&6q<=$_I zwN_Agw+P3Y`I^!mzO8Yx%flA>@3uR?i~ip0o3)W6wDU6KST5s5t*_czB3Ra%m}+9f zGbDc1)!&CXnoUPw50Qx{$zs}!8%=EzYmM@`ZsF{4EcN#j^`C-A>nZD5@{X*9fYRJB z@%|e{Sz6QS7`{;s#a;z_Q1WoBAG%uGbJvkoP>}=x#`b=e~&1Z>UlH(X6@T`RJR<9BKUB#A~-~D;bFo#cqG-Y>j6M#isNS3LZ++!2IzmFGVMzv4DUp04ay|E03A|RrPa#+qD9m)+6sH+^ zTN~9*(7fTJT0=^~&SVASeyNmC5VzH*!wB(fvbOANwFtmb4*q8tP}<0jP#`6BWCbqhoxS@n*eHJ9n-5J)4>^)$41^J62UR*)kYtroFM1LD2of-C5D!~wI; z@9*zi>l%#jDc&*GZmQ4NymGlhw~hW>)WhYqSod5JSQ)FPj+lA(uM0WzDlSvQF))$h z*lq;{UsRmsP_3sx`O@(vL*q$DH`+R51-J zh}}Jf?E91=9RzMmUb=%0N?9YW(rLI(sd6r2oK8Yn0huUJU9Fsy8a1P37_f-pWK`4gQHsJOTQPYg;MYIsC7E$f=@c}kr; zR?&222mRrvsocDAe9gA8p~SWMcJUUTP3b`ugEPw^j@ej& z3Pl%wPc!$aq8{spa3?B_s~l*lL$gnu}Bwa4PL3c?QMrt=@Cm|Hl{cr*V055JR?)kU5_*AwMAs z_0_7~Sw=sf$8Kg>VglQu^;}~~balOl=2%ksP~$T)tVlw~{aLOq>dMsjbSnNfKgbJ; zeqXVF7dQ6q;M{;-10}J0yLd!utX{cpO~WL2-{N^XAUCHDD0REi7ROlBDVI<<4F)3; z3bt(SYBwi>`Yk{r+eSUE*e<1FU5@RnJV|Upr*&si*SVD#6{K<+5BD@D%CVV|b#A9% zXz0nA6sC!%$!$*t)IL^$sxD6#8i-sPRej9pSI~a8tnlVDgo&#li?#;`rR$~rq*{EX zJhOe{I(T{1;b z#nUsI7>Hk26q(KUd!ErpP9uJL77h~nQ*=bLV@W=>L??pI9ajeTLT2R1Ttix7X#z@* znFkCxtZzx#T_i5CBuuIE;cI(zg|NmY*g*~>yL`o*p%3k1Y>L`Oiy&=%s;P`54h4Jd z{cK;slpyHI^D<7eW5!&;!<|q5N{e+xnI;xZ27Q{V*0}<5OF}!>VtrNp_DBTt^RuL= z3gwxaecV)5k>w&&UQIk-u@2TK*-h7yaPi4P%@w4(4x>3RUDA#*wjqx=*OzeE1W{3n z!%OvDQfi8i=1$xq%qxyQ#I{=%d>j9@D-51KaND1bV0uZN;=FZ(-HdVQ0(VzQGpEc^ z>kq)T^KW63ahARpZmY%n_@dJ*rkjig#KM`H20uxv+z;;3u4a2c%k@JYx5{{VcM@fj7b`T-!-*8Ttpz8t)><~DBdP6I=X z!kkU2^S7pNQY_Cd%^&U!ywC7+P5tS5I-efV5(C@Ms90c%BTGnNXuLK>S7Qn>xv2;G zx#g1k@rt7RzQN0(d+2lJ;FgE0PXK4jKm3_N^(Uh6B!Y7Iz;*e%?|VigLz#!D!J%r& z*EkVKxZ;a0(T%Va*8RF3JHF2BkhX&i-RP~Bd?B`x&UBMWb?(~^oyA&CS3*?N-A>a6~H3eJ~#Oh4TeK+BZQ!a)cdlHbgGJQ|>w2k5~ z`_J(_D~=uVfyhb=FNXMuFa%6@gnbz1paFPe%pN4OBY;Xi<4Oh>=oaE_b3U@wop2KwoT*)?JudI}WRx3LY zkO{VOx>jG(SM{kaVsgk$fG7XFm$zogsp}WL(n{&ERg^EM3x92Xi&k-C0~*_8+J;)9 z^J9if9F-9U20{58`EuKdtRea&7bKD7+Ne@*A6^aX>$ZTL_WS2t^H-CV zq!+?O7@L_fd(cP4D`}}(Ea4KJEb+9#(%-BsI1(*C;)A#cQpSo%+(KU3D7w?ZH4wf` zO9Na$z)>?3&Rv&FDU zC|BElHAMS{0>sD8UgbHpBquYv&lL2udc=QC@5{;`ICzeZ#+q zHH1rAUN>wQ);!13PS5(z2u`DDl(gJQ39kaXwSYke4IV5n&6H>(@C62XMk{I|B_(Kl?b z=8PzV*<2+*-2t4|A>)|85L7F9RG%D3O*At6jpv`N>Cy?k=+w5*#*%M$l^d43#^Bx* z`fcJ&`Nw;AiWBXfl$~92oQpiD%~=W+66b9ag568{&Ro-!=wKM_9NS|Uxh8bT9NfWJ}>YU%-8;bIJ)2F5Pc-lobc)i zAY7U2h1930S%-JW!=xhQH?s;>$5vi5FWUMy-|?eoLmJ-O5=ks#8ts1+%3>=17mNqs zmC4nBj?{&v>!}%xdY5z6(`w}N(rI<7uE#f@{Rlp`_2q4h;K1Du9Z~p#k;6k`SkkT6 z)s?DvuHZ1V_99_-KP7S}^-wHKxnU`*w}C(p9s#Dz%!VN*JNDcd9zLtN;{K=x8^EJy zqR`^x^2UI*vFW6tu|(Zi)l~at*2q&F^iPySnR~iGjC-R4`y4spFij_?;_j1|wYpfX ztWcyi??Ac>-i&}&!;Ibn=_fVlYXhCSp-n1rgn^MvhoP3_f&`@wM3dR4Tc>VRi3X-R znGEh2S?wtz>gx9*&<4*{*KKwR)MC$rp+QU~qD;1Femv|LH4Mbcs!Vn7cmi(t)viB( z{_FMLt;Xv(vpiN_Qk`m4`}?mr{P5n{x@Zc62JXnDSh$M3ViSGIx#Y=Nw^vWB`*6I~Q;I8$ z9BSx5NXuMbJXCBV<`~S@lybvTAXoj?@lE#;HBn!IM7V^*um3hF|1>s1A@(!0TsU8m zpU_;y`?YgX$n$13pIuv2%e`{#pE2R0a56Z|l=?N@FmVlb#n96Kw@C6Oqt~Z?nexGS z@QCM4DF%K(zbT)kY%k6P;=oDYLa6SSbgRGu*~%L0J57_*pcW9vA|v-x&Zh=47abp$ zOX$s`-+%k+6<_ncZpkDfRrbpVN!1IYWPi`iK*o<2k^@18KLGEatlYgZN&b&eA10Hv z7@e;eQrXbGGX<|7S(E>RnXC)S#Q(`%F3^qU%*gg%4_@=#?xtj|@_-kPkb)Ntqlh~% zi0^e~+4-e=)T(`@n3Ll-S78oOQBOR?|8VR1_lCbrx+>w|t3Gq@P2~5hk=Myh$!RqT zqKN}%_iVnwB=7a#QU-jUw}cJs_ir@|k`%E119wN=dAB~lYV_5^azm zC8uU+2qqOpocc2zjYoVR!<}*a3FfSX7bjZ4C98y;)zJ$)TkTe797RWx@9rP#aI2xu zZqr!MguScqfU$395=pf!f|iUPK!2uZghuoFHC+!j&)#1b=Sqm}^m zBOIQ02{elvrY`sQJMVseMO2=(}=C?5(Ek*M3&ZKJDI5BU0po!Zfr$%e?v z#s;N0ptQKcMQhfmcVo#R-EMHRBrv6&Fv!v}xm;&H04yg9J-* zP(?(Hi*(pGyA2~DXBtBq0yZ0wE2ajz9G6^kGsbmX8v$({%&_2o;S%c?_DpjnSgjAm zk{GqYXc=qQf!hqd)3Cw$F{ORkypiu9m9~>jISwD~1nj}3%ZJZ$LX~n0s@W(TgFOa8 zVj{ZlLS@7C@;bx8?oPnIXZ?xpFLV!6R&g;>)8Rs3;u7mfO<&l(_Y=!H`3aR20~aW~ za5&zPsk6QwLeXbBeZ{Pjf?Z6d*HnK1TI}Ou744gkIxBf!|J&65GaUQhYIP}kMjdGe zHQZ0!>2N^?k>!{JEJ>GQcPO{7E7qmQ@huHH@@}@URfAjM5bQ=#%~)qq#m2r?n1*6` zZo^os^(sEmwYe|$Msd$<~W^H*mM1?WgvoUQ(<@2_?SzcTY+t8t|dwagWB zbk<(d!^=TX*@^QrUnmmZOm{3T9^((%>R-F4pR6+15d+@64)Y+%u(5GY}( zTWo&I^InDYYKACb)_4t4&fr|4u#;7%z1|ZX0sggoJY!uKlVCHnAY)uC-v1B?gn9~5 zV7{nOFe0829TF7lqJ@ckXC%yLYZ{-e)RmUxO@u3z7;JxlYszD8jIqQDM8UI;P&W8V zZEGl$2<8J?VVDDxvVIsb9eY|nuLcaP20mF8yhezdm(FePexp2 zl&f24G*Yf$)X8$x{9OUUK3UgX0i%M^T2zsHa(lQr|@`nRcI8j&Ixs+2;MlpQ4Y79 z=uQVWVcnIXC>`;BoW!bqGLP!LN=rM3{7z00;aoed*aWX%pd#09l;v%%E+nhiO}?C$ zFG1MShU}B%{o6pPT-+93rQ<-E{HqJD|84evueG4Yi=)QE~kCoG@KR+R^@vicu zEm%I2Q#!;>fX8Y*q(F4u*cPJ3caIgX5X^WnoP~QA;j%22Te%?I=z!wFRN4w~FSXP( zGs+i!`KE}mLf0)|5hJTn(<0pcqrImkbl%sq21>6VBcho*G!~H~s~a9G(X~GSR%#%> zt;D+n!J-TPmj)7&>>awNb>~$F<#RT}YZxu7bc^u}rjtXzwtUl_bs;!9p=%f~*^!EZ z6E*1yp}N7x*SdvQW8P1s6|Z}77$7cD4V{ucZ#S%Ox)5AH5gAZOC^gnFUIdP-9Vx(-+zvOwN3ukSM&WkPi!s+9S%|x;R=qX;d%iciW{B>69z6OM12hJ43W(t>>y-A`SsVz(5bgYgi5jE z_2Gp!gFXEOnm!HVxLsjjrU%5<)-9XJCPWJF-@wQLGqQb4A2(kgcdDI}FIB6k4!!AN zv%V6oY^M?dOR~r_a9d;_%oC=kj%T;XJZ%n{GG4(BVm%(U>Cppacp|E4L@0~i`qVTL z>>N9qPoZ6ZNhPt(OR}#LoEXIh*poH4Aqvi%1WLW02z&llf)nau>cttI3Dq|KSS?5K zV4DI|?pQj~V@WLp;{C}$*35?HP`lHyo?nRbjyF_-)~BMLPKpw}%owo{%j5bBp;&G( zh2m`T?ej=Rgk{x~D7@ZWKKb%=*sBpp)lUEbdG0>NgsoU;W(M=g*Yurc7m~iyzip|1{QG|)kokW%9t2cf(G9;}@sRc? zTxP=ks4rI80M7FkCJsSv7DT=8mC5>W3>Oq`UWTs_ptLq2Oztn|idPRE^9U zMNeLME6vYtT+VJNATg$pMa#rbE^zg{S7-dEI*zjlMnk z0Wj~!Xc=ZRl<{HblUv?8zeKM-L#QZe<)U~yS&1^g3+SmeRyr2NRqC>sO~&($YF6;j zUh?;Ls)U-lU#?a_G2#unI#b%*`Hg6-7uf_4#q~)c#XMh*V+K(xcSTM7zE|;-%D9#A zS7+IZGtCgZaibt<+Mjrf`KP9&cj@@q5yMTVahArbzFHc$hG$mRI}aeY55>9Iu#M^O59^%jYOa zQmD>Vu;rs8s}#7){Il2BTbk9W<^8swXC510UN31Gem;4U?v7yF$LzDI&kxu#hkZHD zpd*f&4uEA81}nox^W$Cc9`Vgrx>yZc`i*+YA_bL5Ok1>$>G%iqg@&qt>f(_h z_QR_qin%-2FM0V!7c_gCtA~6!`Ybi#$gx(%=r5K%{w!q1>g|?61#x}JUZR&q@0j)| z&;FGfo4V7M%gFxsdA-KI2J7;SeA}n@D0Hv-qWSHqZ}-~**}7xq#D@p&ghP=uiC~0k zR8$m+9GLACHQ9Y!AnVb3)3H!cBr}%KS}qlHRjmgt^)MW=QE&mI_0ZX9J|^g%V@n`U zN?Bb2NkaA)?33Vwe?ANNpPZ(j$+s0SdNDlL^u394j|u9#-kDADaqmL|;Gzjxhvc{T z32-~$pAYqw8~}M&=SvJK-H5msE69=X@? zSE`QA7Ih`zXx2a;cIsATox4ac-E5`+u7-!u$-?zKi;KD(U$Qf6K51;Kq$Pspl7T6G zJ899tOjeMQ#{@B|Hvtn<eE#Ejj z5LKsJVc;;B<~-DfST^<)78ScJUaf!pN~amjUK-=MvA-;VD;nDPQV4;SuawFDKkdDD zTodWOKhCZd6qPO@D3DMMNLLV12qmGW0FqFYo-M#xg_uTusfBfdfiww-kQv}$@rqOJP zq)zQZfE2#}yhz8=`fxew?sn5lo61qD#Y%b{`{6u+hu%qM{2j0|A(`fEEqWD~92c;b z#K(`jIIin36RFadGxeCMZL6zAbwKmxn9_#H=4Z*~`G|%ayN??uLP*saVorvfh8SF; zdR;rN`ildI?HZ`c74>Ux`)_9TBv}qXm~Z$${(f@rHz57>?oqA86pxsD$oiEf_a+=; zjhG0x{Lat!V|-mkJm7j$*TqJ}h& z5cK|*Z2oe!jgy0UDnuz%`GuE@E%Af^60(u%bClJZ(X1SqK;32nz+nY&tm<*lr`L3; zh6QYp3yegS#_5|J8aV}lj~j1rR=|KzwZ7;lsio{oUMamgfC=Rwj}IBEQlT- zuV06Xzh7-x_i$h6W=_6-EN5;9i90SDpRbc266xlot$e@?79dE-_g!vOya@Gc+XYBW z#a)tDBxdTJps|OXo@$N3lc&FS4Hl--xk5nOGmUeGpUoS8!#4Prsz&I6;vsu4N9FH5 zOSIpIr$9$OYbaa^857)e4FcM;{J@!Da>2i!zj-Wkhs<EPGQxGw{9|sG8Cqv;2AfIH0HQ&AGvTzpL%T6Hf2OQh+TULrWfX z(^U43N1I2iwNDK{?^|*dxCKE(`Lc<5p(9~=u&s*flE9zqPPH0ZTI-Zb8^M)OAM9Rh zyDS5moi@YIhS9}SJ!e3YDDjI9q-q1Gvh8uTgGT@p4L5AI&?@uTfy#MPnLZa&8G2`t zc~&}WyKvfsKiuQeA$Dr37Z>G7T>qMD>nzBxQ1i0GyoDKxX9+X-9{tL}%(4f0y^ury z!Awyl6Vx%s57=Y%LWeC*YEzn>UnratI{l-1nBwL#$(xRgn#>d)DbNldYbs8J`&YZ= zXTGB<*lF^Ip6f;iCnnu}sMwdO0mm}=uD>pSk`O+?*8I2=2q@=z4c zWL+O++FW>1$_VbM=W9e_^gKZ|a09K#_DZ;6mDolcp8}3iSVr>?5D(0GRan`tCUGy5 z@SRbsyBst7Y&mx8*RapcN!Xo4l#Knu+oqG>0Bw; z3_+OMZTYF}q-MuO(XU=={$IE@OrM&l&rMDh$e!Jez4yq!yP?U{N^^^;%_pC;*?r}n zZYdtu9IpxfLb$;7>a)K;?O6D?Jlpp|8>?$bzLQ^dTY9dfI=`MD+ECfO{FPbSKDyEN z{=y0;hz)To&2EaB4oH{StA*4#b@^8Q^Ram#u7k z-o`IP>gDBDSJeRhB_KQ`zcQv}7`?gOUFoH_efrxaY zlSl^=N$R*#`89!z2}S79on}G<_kPWFmCI^dWpVZ|QIS1eKfyuM)i!yPmv$-Y9GDL-5CY1-@sF0cZ6b zcO$d8w0u)bYahZsWvC#78eW{rq?FSeM3*}Be{vqkwKOjZ8ZeX1<1}$JyV1RzDsNv| zeiz8|s?Cuc+a@w?mE;*&-KkC%vO16=bICwvqN-h@#hd~MExKR-$+i8VaWpV0BpL34 zdWHCKt}kCQ1J3i8Sf*e_cNTj@xE2OJ$^r&f0YvmmwJVFxYD0)T<=i2BP(_< z>D!?-m3!+zoen_lKU4Z&8A`wI^9L(`U94h%K>S~Ut@thPaNm^bp7S>w>HU3*d1u(y zOZW|HezYr`uHSm;jV`xIm74c<1V&Ykmd&+rV62>NSC|dge@(2`Z<>l(2j_<&uoyOa8E$6Y9qTWa|ykI1*ICivGpdRgZ?O5XYPWyYY~{t|Q!@kH)se@vkPolr_Z1t7C&8;mMQ={{vmNu< zF7N=6mx`_GTVRBbQPgS(Kp!3LIb3x+l1^|U@?#yGoJ;0el!7GKX72bSb?gRnq4B^7 z12T9ys;Cb4EUYRA8_QEOi4rZxV)9hRpj^A+-A1SIptt)Q?~jrSZv}s7vGPy5byrygAWxZM1%E-iWsC$X_((g29mJT<8j}UX*$_oQ_cm3o`gfHT zAXsBI_l{weto9*T!D5lKNesR-Thx~&0ziSRs3<}eXQrap`!hf< zrGDM~0_M%_?(v!%KTzOavths*(dA}WizN98a70;Q0>+7MDG8I}6ukKJ7|Pl>Jhvv^ z$Rx@7coQMUF}8s3V087v_+lE)8s&Mb8MuXv|#rD9;_0GiJ&{(srQa0?CV7T zs>d#SM9cXA)hH_b+{B3iARHiVAXoj|T4TmIONXEDQ{+YgtpUNUn>u)w&{}6hW@0Yo z-!9?qOJuHX$dzEj>zV%I7uN12-o1s?7=HOVKC^iZpOtnG@zJfcHM{$L&OQi$%88xN zd?U)*lWzAOrJ91&nAf?IYBj1|c1$IVo6KIku=J$no+poxsAl7)Z!$&Y6#$!JC8 zy=HmP<|oWYN{cr&O|#tp%M|O!`l|;&Hht6C>NVX#pM5X%{Z!;nyz%ceG18>!j@d?P zru6R1?1cw?iC#*}S*_OW!PL@TH%Xh%QWgRf9Od)rbJb+n4-{4dgEXnY!W6T!ve{2= z&P~;AwVz+P^|av)@`CJF<<{t)7brv9Q$oG92$Q2;Ozg_P_Sx? zX_L8+_ILJqeF*O}?BJLE-e~?U9nEz#;U)VoFFYD%DdcQAj`%6*^PSN*`&>Q3_c?*+ z8vJe}T^L{eEVV${`v0r_drmI@@2%a%7}vNVBhbLRQ2r!Xvu4S(W=|l`p!z15(7wwZ zx~evgLHQ?C0XDB73pzd@e>wA48bwb&pscoKSMe7XPC@p%%|NF9a=-kSgGy>8(oL>} z1@5#G>uga#zWe0?YD^+Xv!BX;I(KlI`zXg_&R$1;f&x@wkeRJUE&ReVe>SgYJm$Zdm>F_WozU>BOWKP`1C+yFUVW#OpYx@r=5hwHstsvJl)j$nk~AG*)9s?S%9TNhg#beTRF-1@$SYvmYGF z4+7)@No-;em+B9sE86qldcWw-2)h6C(HHh%^J`CXtj}K`lnXq-2gt{d<~6__6*D1; zsRGxPy|{HDutmrQ2UF1SlTO#^0XIgQ8ZWpSU{I6hwb;OJHdEYn3zrpb6@uS#lu}So zvp!)I6mzI8tc(>S+Le4cfag|$ zl~RXN7f9t0O2@_sE-I3NiSkLc+2N*#WFOo_M`|$xJW-bT&I{#ZOY(Jwmk{LsIr^ho zb&N4HO1Xl>tO#AslY$giv7hL$Om%S~^30~A&W$i%o+-<(iRU2XiCZ$&B=a)uXqWm{ z#~hf*D!>L0C^YyIDromaF6q8?z7qtj)J<%;^go%4>cGQ z4!VReI>gK9qU)q35DJkTaLy@+_>$-RP>si!JCLYi&pB;?Ir%c-MaYbMb*>n+FMkmV zVKUlNL=q!(BJZyWn8PTJf~n)aHJL?L%5{~aC)Jirg|c}MI;F=QrAP9;wqgtDwOA`Juik zrEE(9q~+W1)4$SDx%+~k7+h=~*6jh+;%uTbIr2b$88|Me#G60uXr*F@eZyjWl3O5% z*=y_&N{h>2!3`se1&PxV-aX%{w}#qwDL;< zX#0?5y%%XHwH+PP<+iXF#z@mJ-HTKPZ1EgtzcEziE?6l)>AQHV>R2$LhyNJGgByW5 zru~kygP{NIfr6Om56$=g@l^L`NRWLGet)?7FNR(|WpU5>!()Bla1h}#UOrS-5+mU= zRiiBZCigkhm0COxnKq$c8OepzMw_WKQY5xzbqyw0ybW5fubxBjDu(FPdV?3rc zUf#mt$D1F@%vRziv>1J#SxME_;RM3I2>| zx%f9r=)ZXG{{x460d4pg%-3n@dc?Hsl}&jGEs3vn%>6~K#kBF=YA)9iP6~2dRto$8 z-j@VRPAdlP>HC=O>t25|sQfF-zdGpp-||;sr_0Ixfky337J;3A=_X}0A87|E9%(|m zC^%x^O`^ySYc&H0a3U4!f z%ej*dJ-HPN2HVzLTdwgytE?d_Q5HDf>H;<>kVh>DZWJnGJ#Z^5Z&I;uQ*6-s_>t^C z5TxCzl@kD!UCCst5Gm-Tb4b1F3`88SeBm{wYK8g~2h_zg4Qg|wCq;+Q)Hz|7I(0!K z5?v;toTo}OQ-5+Lq@C73+-kHoG+mTZKh;ukyW8}v@gK+{L&I%ztTx+S{f4lIP?=&u z4`q)Nu5_pIC$1JB#%LU8=5jX@<8QME{lSSox&K!;X;#L(OP;aaw$2Nl4$?|BX{41) zvA@cY zb5&;K*Aum@MJNsi$-7xh0817PMRy{d{nFFkwJqM}Eo)}uEuUGi^0a20K%>p~6E93L zql51nUEaKb!k zvrIm?>KtPaxgGV|M;%_{gH-=1K|XxSZ1~FOCtxsE-ji^==hw-)1dQfLbL7ClVt(#w!#n z3y9z>>f-8mf)8pZydbD0-2B4d>|TB)2HJ&vXPlh2%p7Z@H~c(exuV|4G}b&FwZgxd z$LjNw#9Y+ds-v<)z8%$b2JGfeFKFFPSFQ#Hq*+UwLE$yU^$Y`VCG&}ZUUsl^{lk6$ zR)bU5u|Blo{-21={zi!QK*v;HGS`qLx46qCDPKviu@q4Ouh=e+@)uoRAhqhf0|An# zM*&i>n`!Ot&AF9i?R%PganBnn_F5wVE39SQjj0*9_q<3YXePvI^?-1-I& zLIDCPg_I^L;tx%3bOCOYj}}YI&7zvB%cG%nQmsqAmaL9LNPD$$DE63_ppz&Bd#xD2 zWV-b1&@o?uYV74j&i*=0SRAMe1!A+NB};C0Ce1Pt@6GRb4y((+6dj^<;eBlqfT3y1u6MPrJSR zsZY%Q8`rYo@SV^BBMKXrqsq87a@HwcqyV5vS z6|yxyzI?GtX)qFZf@GkSDA|40A9vY}_|QJPPp zNDbg3BcXVEMr0096L2y>ed_S`qgqs>D?vIl9D&sk-JqeLj74)^PUZ2lGqs|+mpjT| zmLQO~AjN_-gIE;|G`6i$=;)7f-Yc#VD{0=?wO*q50XjojSE+i0|Ix;Y0{4uIvme(~ z7(xiQi;J~UTBpWM*K8n899tCT^Y7GdVcMSF;!fkj~s358Y#QocbE1p=0^ z+pV?k3um=H97<}%_vONosKmrYU8YUL=HI8={cIPr{ZsbuNM-(Ze*U+=j((^Aowxfz zrNOFdJEk6sOjpVC6x_TWn{GDi41-7_^BsCMP9*c*Q&w)fiUe)w@MSaa!P zX+@%5U&*W0uR_ewWlC!B{%Y_2<^;%-DY1b|U5`*e?6X2NPNzw{6Zg4W3%{4yYo7Sb zc;Q?1BE8whNYHe$katC1**Nae=N$4^9^;6?eocw1_djG(@}|rRe_`Q9sU#)Y7@-_* z%ngn;(fk_V19Z^lI&d(drcrx6Qk|?DY<)TJYD=Nz8t)VmZNk?leQOc=atIr<8Hs|ht;%r}lm z^;%NCv}%x~8sS8`I6cxu^bn|Wid_3)+!Ap58pWqki%!g0${X6QXj$$^adcmM+;43s zBwGiod8Zv!?i8SfPwuN;jO`3m3hS&|Ycv2`2=sl?p0t_wy?w&U=FaQ&S z`qgieqLZQ#@jiKmJ|c3=YxESYJj3L89)28^e=chZ4w0Nt&NdqC*Qn)4r|HLwVlA&h z{M4l#DMEnc-2?`qLd$SV0aDDAfD?%CI?#6@bTM@eWVLt6dTrcySEFj8IR0>+tRdw? z10s2I@D6^~(v{e1@0kY3ah;*Q^iQOz`d(q;&3|3?cLm!17{>mGmVa_WJ*-O#l~VMO z+VMHozK~ag$~;W5Bq5xXdY~Bvk(lGPi?Mlk&*t3>8&1x|$%^EY9CDR8W-P}TaNp6AAa5f{ABvi<C>v7*D)1K*y3nAkBF1NXX_mA;m9H)oJstpyoAR$WAyji?dn9S{-k3YNc3qOx!bYH8Mv*`{P z8(d7m4J=!_CQR4C!)Bg(5mX=myeR{vx+ue9jYI-&uy;eGNSJ?2l4QNMPmKU?|n=GD!R`mYa< ze2PJ|KL2Tf)pzgk$@SBPf)8(5jGy4!nV;K+X8ld>?Vo|WAza2(kp_9J9pwddS}}(I zM-zK(8ghct=8v|kHF%RS&dD2l3aijh!sY_97WfNlOba&(=mA4Vl`)kC-VzA*7ok$a zoHcgok&~Vb%jAM7lc*pvDn;Z$0o~V}!;?llzF4e_1Q@Gujj_g&fLND|!P^N~EpE(+ zwo>8(^;EjQUX>=b(QI8dkA7`ZnEs8tZqZsF4`a#g$1NVJ;-5EPIgt&G7d03Z#&SDc z2nVQDpi8KdqGG7wJUHPFO_90CtL;-3+E<70&&^?1%rwP5Y5GrSBVCpG`FTSEnXE{wT9uGi^T~0x zuJk*wOlpfLnk%8#SUM^WmZK>@;>=MCjT=)Idd;uX5$KwObv)lwdqCddSo2$=4sE;* zOdFO|*1rR-j0$)XaV%;kwj)+pv_ZK|Ry{qg>0BqPS7nmpbI_VjMMc|ZqgppL4L_a~ zmBF$lRqi2^OL8R?WHiDK%YNblnYDVPN$Rrg;Q34?k56IXhsTOhyXBHc6XyKZa|U6Y z0@4aRvX8p~Jvyacaz*sqNta<=yyYkIowP;y@{fmsKk0^gz3Nhl2{bY~QO6ckRof9S z1uDQ#r+bdnmqQ77SpI8m7{_Nl&5Cm6oeAhWv(-^w^n*mt0X|(6HtB}APLsaY*iWpV z6Fc%1)=8f^xtAQ8MkeWz4pt5Bs$=h4Ty3h`J|JSXVtf`xcyxW7TzRAm3j%{+{4RsC zUevJ@p3{X9?~;Hs^T|vxt{zGGkHg|gLG&W-H{1?Lj1Sh)cjQcgp1}#7tdFsJN^i(m8#>NJV+G)El*R)C5m=byHEoV08UFPO!}il`GafnGr9o^orm93(RZ%sPE4)) zMTxU@63@RpdH&7ON_)KQbghL6X9X!MKOqVX=rm>_L^o14<7JIH&9g+yX?$BNriN-p z>S4yUu3ColnMfR~@h(2o2r4I)5Hgy6d1M_oXi(=4s6gg2l+%U+qSBR@9#F18dY5w{ z%DUGw%!L6xC@Zh>pa=*o$wgH)v1xWO-)b`6b#$sH(k2o`)ip?%C}9i*I*56tm@WXv zPJ#iC2`-cL8e%sUsEcA@aAbJd%R8Es*s5%u5aY59p-07fAH#LM1Cl`PgcJh0{>q4G zjX8Qj84w9k>_(IaD;J5A>vgrOoyDV`L8)i3mHtpJaVFJZyzq*^aps$_dFXWZCaX^7 zPo+osb$PYxjHgu6i>!#w_Imi`Pz7JfK9m+3K6XuVaP&0^s$ddTIj`54Ptj*4?Uqz| zEzKo73Owh~7pGHPyS>j-ja0=cYraI1W%v%M9poQj5_%Ex zt58zFE5Y-?%Jf03G_by+AH|7s!{fE?+*J)VWKJM|8WR3K!TjOc4;LN>YFP(Ad-z3{ zsoDDL?c6N(SzX~u__4iB?>*q(JqfUfNYNZM(MDE&+<34(e6<0e| zat^-m!T{9JG>}mRjAJpWucISKPuNLappef+TE}U+ovmSh1i0JtNGZRCT@Qwdh9cZ$ z!bRvxcT~}e69M{S6ZEQe-V~K0pK=#13jH=f`(l)i`%~kfyY2k86Tw3yZlo(w&C)sBXzi(Eyb({!}ap1c4&v zm>y?y@(V01r|bNUDoj!spLc|0l}gk(Zl5&7o$z8(-li6^8dlv4y{?$K1iC&x{`eoY z{nNY9f4CyQ_vioUb-LF82klRM^Q z4a@u|5$rX{$RC-bb^vf?e3{yXUIx&Y;#8%o9X)cM0T=o`d5> zJg*q5V=|2Cg>V$Y3Af!4{hWLWAT%mWZ#H00uw55cyST0^${BCjL18DDG}-{EH1ZI#xvdQ8r(s4IbKGEU1V^onO_quNx`xg&Az@9r$r|>dTaJe z_#RbMfFioIM0`*?xU(*W4+=d7)_iDnx5ftf#8urgC>lm?$rI(ui5U)fB;?Jt`CP~n zc_B6X>cs6l-YFijqRHCfq2kv{z&s)>PY=JIa|OIs`_Md;I**Fk5{}icp(f5(vLV%Q zS41y*O>5sgU*6?A0v0(4fnc3Gzy}hGmV=1m1IrE*%3o@YnZo3qSKg`0Y&n@n4Jw@D zxm4xy?u`F!kM2pFdf0-BQ~52=9=n8M(&CPg%H5Zqwn}M9WgrX5#J8v|h|xuZ@KcLI zcry7VMWHB9y>A%#A|5M-p{*V7F1C*5)*Xv(g=w}1tNQvsF z_PYxPrn`*`{lq%;2H|){xHC1cS8B&_B2hl`y*WX7w7w{&r|0M7_It0Zj+F-{p=u6z-&E zCi0?2S6b=U0zS19FDyO5FX;NZzy+14xPp%HYfCf)dGSDa>2Z=({R*&8#4-5OW`Iva zU>PcP)JtH6-KvDmj^o(%V%6u2?rDp&@Cq{xyL1(t*Dy5Tvm2jXai#odLpLOmUwAFnTO3ZbeYq9%@Eo*It4U71 zej*9#m(5<#pLf+71~czsILdi(rUhYO#ce=vRn~%Vn6<*Mee6%?(0|{H=nTF4X58(j zAHy7IzOoAaIgkpYz-OO3S=iNS)1FJ5y5(?Tpfb>2AmtRX-pN7lG3`F9MX+IXue$VJ z*U(bJT4!Pa#nCnZ)#Uv*WxY2^q92XBnm4KfXEDh17SPpRK6Bk5M>m2GW3KdSt{z6& zz&0-BZFk}2#pJB2!Hii%>l-q|Lu5t`xPB5!LKm14UbsnzBEtxz3yTWEaQf!3enk49(TpPK5dGiV zr+`v&0KeP_V^h0lDo zd9=ZOVkJR#YL<4=Op3mkA1EjvB-H`GDHweb`CiC8rstm4G^c+|OvmPbO^f|6I?evg zTx>`3fg{VOHCyen#JNxE8>|_i-ZrliC@J zo?mRq6ybw>Rg>czWpyKeqqlRiceT=axi*4$xKa791la6PR%Tj9yrR5NcF_epQe){d zr%w2-YM%c{?F?S3+I_4Z-+g(}+qQlsxZsEWbCcM}!F^`q zwOU5XYJ)B9z`nhNI1gktd@tn0_q~`-*8leo_0vqGob*_L1>dvGEZM!>6d$WwOyC&K zCR1BmRv}Hu7{yI&r94?QPsu5FaCjdE&Q(yjASAuN4gZ_#`gtR3g=x7T44!H6P}}PDLngXU3@&&RwIA#`w9>(GUH*<9 zPE z>|Lq9Pb^d^ze8hfMGzzEQ>k0M3h}8A+6;3VM#Z1W)sx2aBh6AlvyJ)L4l2+IoNgQf z#^K@&EgrJ(a~WJpIyF5?(eXo5-6DovaEJ2%iK)Ex91GNh?6$FQucO_~KzQ2lM7)I= zKU@giv#!4o`%?RGl6WMr5r$UY5GIq{R~NyS{GDAX$1m}I_3o+?LrCLF&b*wq_O`l9 zJ|m_z%-}HwP#uyK0cjC29T7dzgu@h7i~xFgg9an-QXt$d-+bf zN>4G|!971#7F3mYS9-!cEa}_So_0yPz0HVDw!?^{vIjzD6|scR$>{>8ZnoPZVoSqz zgh1=|wQo3FaL1GcOe>Vdf>bS@^5UF;SI*Ef9VN;A=lTRxrd(oS(_MB3So7knLgn^r zlHFQLX_caiVsao`XEe49S~4y>rRo;sS37xALMK)}d0NMhJl;WAx|cJ3zGt?%vU+0z zbIfL41zj+CvIm#D5*R8TYxx*W-2I{+*624UY^Ge>-fIjO)4w}%8c~{Oe#+~t+obuT z5oAccWBujxs>)s}xJs~Ls!s z;pgXnf8%ZXl~iwVtyB`NOd!<8sH;t$A|Pq>dYSc9rkCWqH9)32G`W%l)}7`o@1wu} z)`A>!>MZCcDo1C{-QS!p%!Q63fm9sQSwltJ1<{}EHa{EANi27{b<2lPB>>Mosbj*7 zejJRv8}2gctAEM?Hr)gZ=hbA%qydv25R&3aLxNEW11G`4iv;vIwO{+4HG?9IhFKZ~ z9@5RU@FS@t`veS1^`FI!Mq)e!vV!5Ft9S=Jh5nCgK+apIw(nKE>(9;=FGPD$ z6;~M1aiI79y$pq1X(?|do!nPkR$7B80YT(g1OGkM1L#$Y>;{(_vzJ<>4TyBOj`4vq z!jcZ?(TaYYen7YYLR!*mD7TNqIW7j|4LQJn1baNll4dI9x6IaN?a!_Tgb{U@k?CHu zS7r{DaFynK=skvcC8DQ29+GL6Bc(RdN}e4X9;?qmPiF)DR!wRR1({W8(!Q9jbLP=+ zGK#5REv8E&h{Ac?=l{n9rCz{R%<10>nfWqkJS;Yt=UF9T?^{KjW$Pz84XLJ~P$M$r zAob;t{H2AWN`g#fLwmWI#tckAKY}n7R&1EmmyGM0dxv{bcc!{fi8CX~tJW;cw5L*) zx+>M)SM~EwQf?%h0tx~)fO6~N`*HhB*Ua`EHym3{*|Lpl7DWcem`ev}3&7lKlZBi` z(HCT~VQY3UrXYKjn(ofx&ofkq>8-D6fUUE`3c*TAp2(GpV<*P^>U138(#Te`8Jd+i z9!2#~FnEIl=uy)mBJM*P{@{`>IV;}W8z2eCIy<_mHJK(eCgXWit)rzrn1+a8;inkA zP*Lq-$)4y$*>hi_K=)XCZ{r+w;0i;Ja+!8gFvG%rlWMF%7$Zt`LDSHoGVSCoYi?Z| zc;CUnDl}rZw9S@7T0>We#>gHDmi`n8Ta-urlqBC~zL01S-#ApGFdISP5RGdy3ztwJ zcd~gVKR0&=3>d3mhc1UyF3pLoH!EoHJ}+QYb~R#7H24pXKYp%~756}U3G)(SAd#s> z$Q&k4R~pM9K&KpZ9XOkZa3+f_Ja@naTc`aBvG>eA6;1>73fdE1F*xC!Vo|dNxSORJcdv$UWdC6v{PM!Guvf93|Tvh-5OUd{1 z4=jJsn6^(39@uw1lxaoh`vnzl^31xbbmb2kZ)O;2g6rq#ZxCO5hIdTKSrlC;tfASd z+_NVJkES#_W##W5Ab$}i^w%bZ?=MH(>)!+G((P|2hPGdXe%-xv7f-p*LY&}|4i;~a zj7$`MNR+r5^(DpOXAWZwm^b{uZ3KABctMb~u z+4D^td;e|w)?y5#4uvw+4HSrfkk{9ezbU5qHKP4Q zx0`atd6$-GvsbUAYx2ILD_XoCWp+3RMi*#`uRk4O=27ETGKX|0nLHQ0- zf(@}euQZWonooB>jb6_#K==>PxBK!8;7CS7*0GXvcv5xdEYK+zO2|A+`a`Dv2gCk{ z-o-B~?=%u`3|Q!eiWlk;)gF(-GcN&I20{ht9}+ep(JFly$5~nFbTN>BOqGV+(=qS$ zic-rh{%ZRneXlq5;)62f4i1rHCf}Uax6;_3VgCcF?H2XY%cs6q7 z)d)kyuHBqhKBu#)yhJTz!q2s6Ak$ElPgEd>-sqDTk?U2%J&nXIx+@Jgkf_N=&bb9B znDxCd*9n!TU^K9OD>~0=g^Hf9+)~=gD#=N63ro6~2_;nEJ_z=|Ig`?rtGRiZ#k*NP zZi=-*p&i;#)--gCw-q#>yg+F?sI#|x$4$Ue`fI?Buc)Y)qQb1$;{6|FzRY@;S1B|7Uefc)^jBYQpQ4(=A&`-)@dWows9bcRQJ~0?W=%nHvoi zUJu^EtjvAwjFQ7iWi#aOElGT79g*se6#vvtjhCVr78WW3&J!u~CcB5Od&&E!m6}^A zh^sW;UJ5lma(P8Vc%#_%Q*M7{M%o5;Q09niR__X;ijkb0<3Wj(%?NFpJ{!Xn^i|wg zm=iek74`ad^+qn^cJoh&Y`FQALZtKHM5BZi?x_+zHyuA_4es00g`(gIFAM-2)ZQ0L zkK+S%PPFY8sfdj~(d1^(PGE~ozl~g_f#)MrgewqPvvrEM!?1`r&>gDzdZBp-KDnoc zGlUZYEJ0@xKA+6nQ(YH~IfOhS`XRGy?YRE8zC=;I%7kySdE;Cw$uvoy6jQ%kcdms1 zz=jb$zwZG=wbrpT21^fLuCD7qu8@XeO0bSqhkJvU)y)rf^b2KCxiA~9NydYYI+rFe1hKo0N2-y|AxYb#I#yK_ag={r3CvWCr6$mq> zpuC8;5Wyp6e`sKtIg?r$`Z-21*gDTt@FDQk*i1uU!koKL+W^&gr~!1M`)-!X3{JvJ zyo6QBRbz5XMoVFG`*P#jc=gY(5=)orHT;Y?ca1JR{7LGA)Oue8$4(+ojd{h*!%cI7 z;JisxGOAz;7H)9=*S`GU4dDM;(4Vd-?WJ?fq<0n2hPvJ4)vyW4y>s=8h6C9mE<_IY zr$;6mh>WbR$Vb^KGw*3qB}!%jh|(h&%3A_*jI&Hw!|luON(=gf`+i~BZR0-TL3a2I zt#^DqKYT}jK4j_H2ll(V(c9t7ks*BYqU)lPZKdY7G98v(Clf*;*(A?$T`ZSte`y0A zRyc?2mt@#AUHSwlvc-X&4=?o1M9o}?4lDyoYRn0TnCRZT!$gIOZty2gwIW=YnC7?j z7cxbY{LFBv-UvbOU<UTf93`0OGBIBgz%G|dwUxg;`_ zHt7qw#vw3VB|ylVgQYT;$f56|Rz*S| z)R0S1m~vOJc>T$>hsKJl-OX}#ovWorQ&X#YD{<)!^?oMDB6l0Ji)UxgPJNGO?l(9( zk}7z98mwPxpmT2E>p*wnQVHR9Yki@ChIypkv!Ts`FZoT=nhedV;_M}^d?mkc{rvEe zhe9EGSSGU_da;*uC`SMaK4NZ_#v4*RAPPDfp0}^M`@*R|eDH8`6$Z2Aqm#=lYiB1o z^4dy`X=H&n#VYMP2gzJsedDdMbME>5^_eDGAVas&!4spSiFG~K>D3E8NaVn*Lih1< z#xR4mQgUE`Q#V)3^nv0CI0s-AqJ7|hDa`uE@!ZIL3RCLe4O7{r*Ph5WSb%OUhWe{c z)x`MAMHZ3S-GMx0K}*Kg3kkd@W_|LFC?ua5y6MLbi3gDr<{$s*F#o4E?tk?CPe_LS z_P2I4p!s(-gddWNobOm)t#`7lLO(z#OS^SkkPyHqTE((|PS1==na#<&iT9bj1~jnb zDA@6($3&laHE^3D#FIvPX|5t1u-IG#e~gsAbGq{LtJXk+3CY%K0ccvk`^At-q5wXH z7Y{64_q_qHi~DwEvElSuTGI(8=DcHV`>bmN-{!rwW09@PwsO%8EwknswF0ueJ7&r2 zLtfj+SZHB)yv0K`tA=~!0|kT912m8z`?l6alP7g?IWn+X#uu7v2Uw83rqVa^I?Y0I z>yl)sbP}SV?Pl$S}3i8aPqP0IFA?RB3az7$I&hVzrUT zE2N;|FeDwTrjUQ_Zct1M|A}%URBI#`?uOrjp-CR%YN=lNAnA#KppyK}3xZNBViEYT$gZKAbsj@QS~|+zSaMqA zD@lsn1J5{32aXJHRk+jCVp5l`{T7&^cg%`|cqKbP(6cK^yf!sSs{CEMAGf23f)(xq zL+gx+`84PBsXR0m2E;IllVU<{`CsGjwl&)}E*Mjz6DoC#%lS*6zrC5?bKze#mH8C578ve{#8iL%`AdCbzvM0K>-L-7fff9+ zw96`)xBJ@@y4b-FMOC>0%w1ol-w`Gx?NGOC#2^QtXF+fGGY_+x{=^r1{I({|8-j5V!yU diff --git a/Plan/Database.xml b/Plan/Database.xml deleted file mode 100644 index e53531deb..000000000 --- a/Plan/Database.xml +++ /dev/null @@ -1 +0,0 @@ -7V1pj+O4Ef01BpIvA1GyDn/c7swkQWaDyU4W2XwyaIvdVlqWDEnuY399qIO+KLUOF0nPdvUOFjZF66p6PN4jq2bO/fb1rxndbX5OQxbPbCt8nTl/mdm2Yzv8/2XBW11A/EVd8JhFYVN0LPge/c6aQqsp3Uchy88qFmkaF9HuvHCdJglbF2dlNMvSl/NqD2l8ftUdfWRSwfc1jeXS/0RhsalLA9s7lv+NRY8bcWXiNc+3ouunxyzdJ831ZrbzUP3Vh7dUnKt50HxDw/TlpMj5PHPuszQt6k/b13sWl69WvLb6d186jh7uO2NJMeQHdv2DZxrvm0ffxTRZ5ix7Zlne3GPxJt5L/hJt+XH+7e4hTYrvzRGLf19vojj8St/SfXnhvOAvQny726RZ9DuvT2N+iPACfjgrGrPzl8rPFsXxfRqnWXUdh1nlf2e//F6esblWxnL+22/iKclF0c/09aziV5oX4i7TOKa7PFpV913+cEuzxyi5S4si3TaVxFN+Ob+pxpDOHY2jx4SXrfm1WCbeRf00JODfm5fKsoK9dhqGHMzNUcTSLSuyN16l+YHfIKgBkN3418vRG4nX+NDm1BMXTSFtEPB4OPPRC/iHxhHancKRnIIfkVxhQ3flR/5IRUTjXzgMafJYHr0r0l3zJmP2IN581txk+Xkl3jY5eZt13bvyrUUciT81xdsoDKuznrpIklY+mO/oOkoev9ZXcebHol+aq5VFKT/lQ1yhbMNPxpLybtKCFnR18N5dGiVF9crcO/6Pv8R765M7c/mT3vPv5Pid/yurZ8V9muRFRqPKnoy72Asr3ewuzNLdv7lTMfG0p0hxh3qH3e4dwh28Ye7gAHjDXPKGb/+42htWp3hrsexQpzj3ADAH6LNx+ZiN+3Zas+mbmmscm/xTKzvtVj4xq6PIqq5k1f2+RLn1p1//+fd//fr5z2oAb/XbtjrZj4t2AHS7A9EtWoFr/MCT/MA0tmv7/+DAdicBG8KgvmTQhG4ZotkYmgNbH5oDRLMKNPvG0LyQDPrCVjQM+cSmZXaGmNaEaWIF+kAtSBFENSyqF8ZQTYhk0ShfRvxxaRwzPgrn13BI7auHj1v6utzF9K2Vl0Hk60K+Mx+GfBfCT2R6DpEPgHzSwb31QB/EpDK5VjGu+xz51lviWwcTrh4AGUNkjg0ZV92MK+kg4wxQrkRm55BzBWv855MafxC7ymwbsq76RnY9CNdJuxKZpjON7z/GyM4zN6mTybeMPUY5H7IwRZ054noIrnUSsEQm7BDXELgOjOHaluk3VFTMIlor/WrLZB1CGgDSJ+vdtENa5tWKaMvy5VO0fsLO2ii0h/KrIH4gk3EIbQhod3DoGqDtyAOwil8tdsiummNXXWfaclbbhVjAKA/g6vXNSyRZgUjWwa2/0yG6mljXKo/rviDJCtQDzKcN7kDsKg/uQlrgfE3loK4H1jqZ1TmO6dQg2tyYbi7Lo63DOQS0LkDrpFTnshiKgIYA9DQdFMSksg7arGxbpkkcJdhZG8S2VnJ1jjqoGnCb00Hnsg663u2X+7zcc926sjWj2/cO84eKiojl7UfXm33ylC/jlIbI3BptN4Yyt4RAeBkKrWoajmlCKyHup8XZ3/UmFtzfiUVZ+MgE58RfxiZ9TBMafz6W3lWxF1jYvMNNsRUkLXuNit+a4vLzf8vPn9y6fcnefhPVyi/HYxW1+1MZUeIE0mVZyaaKsyWhqLGOaZ5H67qwqVKe9X+sKN4aTpXui7R0gcPtf00rZyzrXVKvD5ecLfPW6+oWsvSJnRwJ/cXKsg5HRNAK++AO5ZvrRHZTlKf7bN3UEqRpIZqJWedu5YzFtIiez09/leFlZq7i8NfpdkuTsOoqkM2fwOY7Q5v699l8xz1n84fOBolrAziHTO+VNH7b0ABZfkNLqd0O/xnJ8ntzAHeR6cByKXWbuyD7D7b7fRpXCGJvmStsug2cGyicG/QgXkQl6tX1IDoI5AvVgHrivgkIk8p8Yb1ea5/jnN8kronAVu/QLwDwAuQK1QB7GlcIYlIFAUsQztPhPB/YT0O06UjgqUHzxJ0S11tUOAqC+UbAPLRvBlh05eEmCSVo9qatowMxqWxBpN910e+C5YSk36uf8ldF304qNG59PPO3sqCb6yXNkO1LV33nuvq+deGj9Q0fPfbw5MOc+J1wK8soeUjlVgplhFmPjDA8pEa7x3a41oG56e2wfIjmTSYKT/SCNn649hkUEzRvGfBg4rJAkMueTC1+QTFB9RBoGu8IYm+Zd8SQDlrmNj2g16kneEg7qsH1NNoRxKQy7Zjudghpk5DWKiV4SD6qwfTE1YMAJvWRfbwpOGuUEnwkH9WEvZ8YoQXAorZk0RXlN4w9tFFID+yhbYjmHLfxqsG0PQ3TECadSxb8SIKCO5M44JCy4KFVUPDWAVs9zK4TFE7Fg66ot+PUg155wCHkk3fy51+wMLXG0ZzkHVlgcUENe8En5/TPPz9t/aTSaa8VOxy7R7ywrqsPrXb4LiLMmGQnCMebk+zsxTgJbmx9YCcOZL6tkux4h5dHaSKPAlCwm+kR7OQoXgN3ikPs+wlkzq7LI/gTFhLkm6aodwR/GwP4QdYKOvKSjVTGQPKUdWzZy9l6n0XFG6L2ZlDr+AOZGWIBSGgLeSZf6uitEZQ/Cm4XMNvjQHArT7NzGhcsXO74uGy5ofkGzdQR1GwoGwJhJnmxyo5l2ygv+79lzJ5ZjGZqN5OvMZrNQl4fUg9dI9qMVZY7/rpS3ndghzi+Q7SHusS4DnE+dBjrA5Bgi64UQB8VvR2Zsk30hS0TzwatnZNPNJP+vrAjwvdLmsUhhgUx165epFCcWwOdQkwRrsuRLMv/uFRXd9yPxe1E9yaWzEhgDkWwdEyWufjeRLQrJ5at2v4lpmVSvECgB99aEyhauEBAEbTtSdCGMSrGA7glQA8O7AbSrOOaXEWAnrgoF8KoLUlRq8kaXRd8Oo2zNXOztctVAnOROKM/4z0ADUZaEqXi9kuNc7rBXQTpSr06clLnAoiJpCUXK27AVN6BkI5RQk8HAmNxeRqP2ZxUp+jsgXwwdGsHxJRAjAJxWAiM6q7xgY55Xkvi1XpEqKyDR2gPgjaxdHI4trysAbENgu2OhcdasC0vgqBhGJXopnFHzB1EuD6Eiw30ehAuL3dAhIMgvEOQ14JwBRExENJXQNoduIAJhNKzFXD0COkDrMzwtCIh+wfdOWbPJIZY486xAxl6c1vH5v64rWBj6wNvHSMCH+jGmrYY97oxzL7ja/3YtcZtzB1bH96RO/dTVUv+UTi7HeHM84buMLAhemoxfRuX/wwFtZtZJNlg+2pBLYCQVxyZiH0vPRoKbUpnADW2R88AYDyhLR5yvb+s6hPUNBM4wx/UJhCiU3JzMIOaInxPC2UMY1SZiRX4Zpgc0Sy6HZ2im4PxjBWhe1pAYxijyqTsdrdaPnFTtMwVEdv6sC3S6OjBNq6hVoTtiVnVIIwqIumeLoFjtNggsI0COxhI+0AErCdzDHGsBtjziRsZQYzqSDb84GqFTtFNmNC86HYpijXTAVMi2vxjx+k1LKK1ueVtiGh+Xyo/67r68I7cEY6pY1aECtpMj4LmXkR39uyB7OZhMnVdt9vNhHVJZaXHvKOkPUfrItqilqZ/c9ocJnwUiIIyl4m19zQz1NLUDuynsXEwniCzcbhpTfV8vacp0CuhzZGIUwRrg0ScKxNxL4zu2mLSI7D1AVureuYiEacG2O7EZGMgRvUkGyLjoY3xEPMx84yHe7m0M3ifwZDqO+MYj7H1wRkS10fHR8eXGRmfjHP8sfV/PKAEuoHyybK8c7DYli0KvrEs4rdfEnQ1q3dTGHp4eLA7VBxv5bmecgx1raPVCyKvh/++jEM/tr5PCKyTt6RQPkbWXhbc45A1vx3WPBARjvXsO2lJsnzYQNJGZdZO07015Ui4I2WulTLvyupsgjJvyfOMlLmxKbg/LSIUjCe0JKLaZ88R/171PGqaCaTYBrUJerlzX96JZBrifwyKzTcYFcqX12KsM1aNxhHfxvGtlUL3MSaUInwbjAnly4sfaPjM722fIcDNA1zrLhQfI0QpAvi0CFEwRm0J2L4r77hIMwS4cYBr3Y0SyEQhAhwE4NMircMYlUg2/OhaoMuCsHKiSx0jsFeOB6pjCHr1TMfoyrKmWMewL4hmb3HqSP31F+/rGJeJIsfWF5lKwHSPQG69Prrna1TBWz3/JlTwoEd1vlS1x9b/4VTwwPCGRVTAh+LnNhTwvpb9UtEeWx9cAQ9k6rlSwKMdKt+3E3FxIfJG9O4XE+nnrhsYy9Q1hk40o10HHeMCEwmmA5nGRi0abCYcTOOyYSwrc9nRTg3Wkd4aBGytmaUDpK8VYdogfR3I9DU/T5yuaZmYCMFtENxDs0yD+MECqWtF4J5GXcMYVV48hog2iOgm5bimhEQLXC+mBtKLaevFYIzqSjZETl4bJy8oD/Oc/CWnvfDcUz/Sz4Ev5Gl/RREm0fopobhF5paIQmINzoxHQMYhMnGAOVgUD1im5WBZdEQHGkkkgqS4X8h8A252UT+4mUZGwFhcJiNE94HzFpXzlh7Yi3VtOpgI20ImQhGyzTERtqUgdQ4iejqiiTWwJ4eYtNoW7mxRAukGVkaYCJt8PCZC5hGuj9s+m8ZEiCmV+Sjt0tyyZ7HSZZj20T8AZi5sMcVFR76KZAN05NuI606IPW5d6egfXOnK/GuWpsVp9YzuNj+nIStr/B8= \ No newline at end of file diff --git a/Plan/PlanEnable.jpg b/Plan/PlanEnable.jpg deleted file mode 100644 index 552ce7180411cd138ad02f77f5d87c7c0d14346e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84105 zcmeFZcT`i|wl*F_5m1yOAVrZ9AT*_SP&_h#tsD=(wRC<>rfOP3KAiaaqdkMWu z?;yP@AMZK$+}AV4IluF}<-6ni<4(rd*<-c2_S$o;J=Zgz#nt%LcK|U&4lD=2!2tkp zuKxg6QvhiI?u|d>k1OuA+{C;2hv4Jk-NGZlCnO}mCm(u|CTzv(Q;NJ+vt;EG)0NfzK!6m`D zY5_dD?&@`CasRmdo7~2`b*<+H4#9P{9x(ubhjRnxCedwteB9f(H*N!PZs6X$g?F2T zl#G&o1pfg!1GnG{Z5`L>mVIe8C*9dgk5EHKeRNeSJmd_y;C~e~SAu3fy zBSXv7+$jK=mR@q*IL)=r8`qluruh07_ZH4gyc@T#Gr=T)8`p~Q@CokVUZ?(1>RL0& z&0D1O+%MF~9*{#{BccWw)ZZgfsm0hIcoaOm{2GoW--hO;9MTw#7x<(haw1*|E zXL`@s!hdD;`mEYWrRVy;-_O2w)PH^SU34){`f_gBkq>~yM8KdwQQ6#y*hN(C= zId)w!<2BU+f)v8J+h&nV#RbVl`*gJ_0O9|Orof1zxn9m8I4pUc_I5 zhzb^KHswnP6UPS@knr)7b)4ue_@1-4r9$}+A`U-%f-YrX7d|%Nbt%>n+Vp~7aD03! zJbF89Lr!RiJys@~p?Wp$qZx%~kShIXqGCAaemm@uEf@w(gKEfE-)%OCglQzY3{gd^ zBVM&ON6p0YbTgJDnOeX0MD&u)eXO>nQJhiUx66Jnm#)&5&U?ckcC!tvnnR?dF1IC; zdq&P<(vBFNkJsJtVPQi=qL zzy$eHGzAfxd#TUt<1$wpoZ=5pTTto^-r6!?xC=$pdj)}Jg(C3SImM%Ssf*b+UP7s)0vh1-^W zKGyb3X3!=9>Ah#&^6YZP1@(tGSIARokUnG6?H%5Ce5}W#AH~V`CdFGlQO+}NkNTsP znuDp;uAt^3V@J;3UGHwTP7LGdu!gLQ%{r32Y1)MboNKLihL4mp2@YR3CkmRBu4-q? zkV4_*J_ti{Fy*EP_~%+mO{xb360t#h*%$hW_{YavK_lcINQ)^G(3cE=CRl(Q%%RS4_p z2@2}z2%u5Z_K0*^?<*J)vD&xmu#=4;z6%%%lKM!7nvp4wA_dnA83B0VXmRr37umORIVkgHZd#`(bu^+9t?{4odv=|Ae zF3j2gFbOg3r&Ax4KY_d?DB?XW8jD+PtZWRuXR&8g#M|#N_$7*4}6?5 z0r3ZtAwS)d-(I{u{qkGm2l0Bi2DiBa5L^K|F8x1W z0Y;d`tgHK+1|sa_%~y0o%7>WYZ4gfDs9)^CW*|F75LYxcaUiK)zJ-WO%KiP&`&#bh zWRWW6%RD8Tw5q-zFiD(IXh)j0@Wiw^X{7BMxFSjgXCa)KZ@gD2kiK%U!LMcr!+{PY zPMcwagnsV$L)_(G6lB6%C*A>Yf7?3zmu?~Ds5UOY^RIC~Fh5*$ekoFSZd?KAFRFix zsy?hC+q_}XRQYYfGBhB~W}fs~BKV zvCW8o8BD?mwiE4~=LI9D)IiLpn2uwBx!I=IBDw3qceXTZ{@C#meJVDy7Ie-r$j?qF zZISB&&dz6BOwl;#c2uMpmzZod30z-Wn>-uZG;KM6ln${O zMaSaM5yZ@BOwEiL$*5K*&09sM+Vc^azhb;dg9>J+!7Z?Jo>^$T$~ zSBI@ZQ_gg4kM&-t%%lm)(~Y={+(f%J7t>M3vStjbu$nan?a=-#W_1^Uaw^mK>MJUnm@%o#Ry+@-lrA{MGNBBe*1#`)f#{K za%UuYYQ$7|N-LW8&F1I+KvE7a?UbviU& z>rBx$9K39`9J0?2oJwqxXI4E?R!zjdNjNJ}6R#GWrF5TtC*mRbX>PT~OBcEP@G{R@ z{>(h1Ey{omCs(;9t8=Lx?bm>%WkLl@`?sJAf_i!?#j@g*?YYMuL55)}l*LP0(AQBb z$V#Q$BL|E@yzQ@;DT7cO>bk;`b01#EBgf&($c)r2*Fl+DWoKl?J_!%cnYN`>$4Q*k zLJ~j79wGd7GLawD`IH{Az*J=hZP|lyFj5z^aDT%0*Hoh-Vfd1qOo7#-Sn*<0J5`p) zn*T)ro4-$jyU7*_jq+?<{NbZnQ_Ll{DzX9D!U8&`k!E1zJV}C0Mo;MHa7As854_Vu z_K?tm|KBG_*+mHT#Rh@!(8RR`Lc>5yLJ=RltoDUv=WCD}X6i ztr@H29_TsqZ$*VuTD|M~#eddc>Ky#ftY!c0>uu_KVoiTa^AY8C zrLam|_Agm_qf{A@sw`VOS5Q;wn%a{&Os3>L83`_IIb0Nx8^Oy@-(sh4lhX@kT!6$R z4eO0_R0g)G`oh~(HIL6!$sP2~R5af>3(1nZU=sK$>SjQhl>$&W9L~u+4!G6%@){Lk z`_2Et{SyXw4sdwOXkrH44=0QC*B{X|c>0p*xU3t}&cRS#!R=Awl z2hx#{WSq~jh=MNn;o3j>iZ=)TT=|;v0MVX_TiFMlnMQ}$_9E$}RWr$CWwt9oR*bj@ z+vk6gi|lHxWy_Fr4=AryT;yyU_NyC>>*p^s*CRzL)Bn9?>CB%8NjAtb$PmXb+uKe6v6I>Y z9}qFw%PKj8#*rr@<6DyGlF5BhkP6MSszwOZ61_4vXIuIsL&ec^>e-OpWY5~0={Y)? zPB!O_+9_(Vb19P$rkC@{)|t6JEbLg3aGsyt8*DKk>LD9vWKk3R(KL?vmUWPd4{5tw zzKxc@5OTZLae=dT0UWnog7x1)&4}7q^ercP#87KMtyHES7uLSDaS`%CmG7IA7V7xT z3(0XZXX6cLEaJsOJ)jBj)=o~MvP1G809yA>0M0&M^7CPiycOA23gP@aRn|gZt;ztFP_D?DMjEVtDS;`Rzw}~ZY|=1neAy>^c)Q;# zifgiagah}Hai|&(;hA$Rlu6^YJ2WSwX3;80xo$C2f>g`TA(V^EsozzQDFqxGGX@;t zFiUj3iQQ=1t28xn87ssiLlP{~xV@U-!{R=!;w&Af6oY)lMK7DWV7y)Cm;u{;ucA&n1qNLqqmi&Z zaL!EFk{1K+l2u7jNx4WbiJN#0C-yggXYpZiJr!(Vjz5?v;+`8*^n_)OwiAazudVJC_!*+S@ z4)w}W7vIvk85;tfqGwx){R+4vmH7L&;lFTCpjG15I*_76CPChCubZyZL|5EsNzzr~ zH*i#x!v`2{dgSx*=kzJgzGF#BKXbItkmBR|`=})JFL%EDU-3FeYkBW(X#Qt2adER? z7A8UChAUKA()XEqd9?M|X)Me0-ZdHXwy3>sf2}H(^~o}({7phWztCnr@620@)9YuZ z>M4?FN8C>P`o%#bUwA1~y5K#PLzV)>WdRC%L4_o%MsVuUi^gnlw#W7HjXEVo3DDiw zqf~>YQi8;TjkIFN%j!D@-+eoXieYcCkm9W*_5x|!VACD00MRZt)2;we#(Rj;`_J50 zchLr>42#6mmlLium*K&y>W5|Z2X45x`vhLE+!y<~A6np>Xw%&D*!^OeQup@5fYp`m zDhC0UB-J74N$>Z&bV3t>pTrJMy0}VyYmnBMCMAJuzGFPuSyEYXPVj?CM(56q{!ei9 zTu+Y~n*)VUoS{F6IR5DX@)ff5>2A$JqfoozpL*_j`?*C9^^b*UTyKDa23EY)7I;TQ z5cOsCAdFT;S!GFE^1ZCv%wvg(_8|30Um?YBWlKZ7s1k=T!vuqNxpW8IB@O|+&&%#a zy-9e&dAkP1N#iALYK-D)CTa`ZrWv{AT5LVN3X1sZG84~v__s_=jf4z)cTMqJ-@n=i z4lg}h?)7D1D)9<-YaIo1Nt0|XrDkbPGNZ?eo91qqHk3c9as$_YG-sV9s!X7C-K)6* z&=Be`Za$}zoY`c?@FR6}HF$$7Lk4GFYAFUXKZs@NmPH!xB{-0t>zOIjMldXxHR;+U zADF21A>MjMQ}OjQDA~RYLO4^K-rkRkb1W(D8{COcNAu)?cBt%7iUbmaQZGw^`@sy0 zlH5(;{K~z(nnj_Dhc^wG%T4>gwHrB*gGCYUQKL0T+r9wnE(@j%N>C%oajmEM+o(Nu zW0mC!k#r;H_(nQk$!Gq7lCPsp_yrDo#$KR@G_fmP#!neR5U=KsSW5aki!XT0!B97a z9<*2ir~KX$r9>RgfeN_jJTs8lj>R(`E_}lw!=ykDJAXVHHPG)cBn;KoBwqyznVVaF zmu^Atk)lhPQYf>%CWLb_L&gK&jmg+}XsA1nQ79Hw2O6kny226-oH(7HH1&Zm4}z-$ zNCxKtr;a>cUVpVAs%P0JKm45jdOXo{s#{(K9ch|NM~*uzCO?a{wZ*%-WwK;CmJa#E zyPjnw^1u?Nr>#vSP^v1^S)4o=!EZBPn)r4F+wC|@*g{;!hZC!({R!=q(0rAX-^=5^ zDkz3X+(4wmkTPbKo`xoYec`)V#}k7?=XX-1-<{R$8aVTy9&5^m?{LzA0=>+jhk2K5 zJ3q4c$%!yrrE0fEI&AS&pClq2l!@5=Ds`)nTukCNBX4hW@{7b9Jb+b+c*#ajj_5Kg zb~pyDfR2rslI+V9bs5i>Gy6aL<(7Lfo$G+heIg?Rcq8-iRMpqa42?;Xb9iJ&grn)bS>o+KlSn?8|H z9_@r*0p?{yq;G#Vw@CGHu($%OvqgTNr1^FjPv#7gv$s+T1kEq{wT(76Yp}2uW=sMA zKt8axiE3!Rj}FybtJb?m;SyY!pRX)@$YB7S-;uW8H?w)~{<75LisnqvjC&_9o!K}r zx*+3iLru-9spDSTQOa*C?7yli(`P5iYcr1dnfVChJ|sSTu{tNR-``bUWetn$vf`zE zJ{uU)mTh1WS0#25P3A5bneJ_cedxuB`&XCw3Tfir0Z(Q zWxJG3tEQvs4mEszN4z(N$lTLcMvoHL6v@Ld=Q!Ojws*p70L=Y$SV9YBV5B;IkVCqZ zkYQA0P0?>Zcya5YnKLd)Eb5!TNQBY~81m`8FNf$TW8}P1s_b%TzCn)+3#Yb%s-|K57i-Q)}sYVu(6g zUC%%QOv2;{XJ$nKQNQ-ZBKh9Z-NEemJ_S8qf*}r85)G0|XjP~yNV9Lj1iVLzvvadC z{7$3jt=sI>tvLw76RW*(@m%tC2Mf*yO*^}bo!l|)nx6g!*zjBXV*6qeiWZU2lrF_M zd{tX-1~*4Y#us^o`Q=e0#}8|ho5>z}jXgqCa|-OM0mah$FgMpZ5}-YUO?>bn4tmap zL1@a|1f5E|UC<)GazqTWyLRsv{Mp#sL)E~HNXNOCxKsIRo2YFHIYBY35<8Sd3uc;A zZ|*EYXZN7SCZa9rc;MtVo3F#2Eeu$jIUJkLv#a>o9psdMH%&=p%zV~*AXTx@Tp6=< z0TRamE%kbH&s2pLI)*0&_*r|IkWBH4pRL~sfu{s^nmQ6DTtwmIHRHln)6MXZ@e%QY zk>QneacW^7d6rMoEmM8`^U{Stl_wqHY>W)tJKqL=@)UOJcN-5Vu-~SO=D^m1?c_i_ zuFDx{GZ7o$5fCEJp}<0bX9*-#^|SkG5s+(bAu(vGvh|kEDSlub^^^vwtkxW<-{NAs zQuuz|AS;~;x$zaxhfX)f?#eud5an`i{8C!@%gb4$_M z9;#^VLEIEsBT|$!Q#{8_K`u^^Q-^nPiw)B4Gn|0eaRtyxjljDfEZqq0%hIO!2@BW4&p&J1HAo{9sQgn~iG^ z!maAzr$JWHy)rxX^c4WtsqnwxgZ*Ch#&0OQZ%O;U&Zw&P+5MURfPd_!0sd`8_)8N6 z$I)%(lP;PmT~hjA%IZ_J0>diRUv4f{lT?s;%Q%G9?aa-(%ds-vPMaIQxL;naI#(J{ zcR2dtZNmPVQ9kFF-l5K_;C8)ep~h|Zed`JmZ)rCG?yKCtc8?iG>luJHaSC1Yq4SHU z0_~@s${`XNpR#y%rfl&%802s8f1OPQ46x9{li9M`hI{XDXrUKJ_Mso-?aHvOf;2Ev zq%#4d8Z|)+vht1N9P2a37HBxkYKL;mQW&+zV6;~3tNd^thIJxk)mS_yq_BNl z)g_N*I!Aw`!}lfXHO2{j@#Bl+OZ@tXb8RvPL&%8N`HVsQjwa4l-pFKWd?it{+h#1& z{GLN#7iG^@bQDL08c8%0j%H3d_&C`n>?S83wreYVEAO!=J=rXZ?KR0{kA}-*q(1}X zQ-oatheJj=b!Qn#l*gx2QitJ@H}`zHJ@i7w)$C@q=&IMpEk2O+oU?PAb*NRRAaiM)R)W4ajQ!j z|Mfk2)RbMHttZM9f`BF>Jnax1*h13XNf$}DZ22t}o*hX64mJ(3VNGoV6<>Pgy0;Be zSjM`*4Ehn*zSI#67i+L0kTs~47|*~1GbbF%$ctXDpo)9F_H`#uUzWz8&_=%K(@&4| zMCVMK1eG>DJ3dP&F`SRJVxGP$b5Mx_DcmAmt(+h)!1+PlHFj#s!GW>5i>HjXlPlpZ zYfulWnB91Rk-ipZStDLIxAqR>?YF5l7EwyF;r@IpnQ2Y3QH^*jPAs&}hpA6fTc7O{ zwdpe_0KZ@+wQ=lxABWV^mN_fFgSXPb$-gXUm30dY!OX@H;pQzClZq|DcQdBd_EnGr z7R7ONgf5wYE{qyG=z2MOT_R346qcH+P?DS6T*^||+v!}%Yn_=TH7U(S%_QeusRx;| zC4dr_NCg9Hl$^8jX|daqA8R^DHggdn<+(vU+5Q!AW~F?ozzb3tLv_hf(Ngo~!jP>^ z0-M&bCS|+213y0jHj-HKg3|d%Z|zua6(Wbn%!Pcxh7#CdTfQz$Y)-B& z(E3fce=`J{%!G*R4$Rb};+LZIZpG@ndKQ(>^|+?|A%Ei4H7$nSGc%99Yx}|EDBSjL zfwofdU1JAj9{8H|cQN^SVEH3_HJ=?6^*fxyoEPdLABM}wg$iW$oL7T#53{DcY-ip9 z9tRQpr=64AMac~1G+WV)KkUN4f7@IQ!pL0!?JsH4-JV2_b>~S;P?R@xrJqLoa1sM< zIOHrWotlH^p;PY)fVVb_Z-V-f$QOHyM%M>2$MvDFP_N6Hc`&D#pEn5- zTz6*J#aB?|1=*RgcYnVkPk25i{72yFeNP1WQK92?;As)>^yYMu?;iJoHbVDrUHkw2 z44)pGd;y-6Bz3I_E}Pq#Ab^?PnF3pxK-migYgX<$p9dIO30^Q>-W_u*B{v&j%xPp3 z1}P(Fu`Ee&Ca-XF_)8h9DE31nRB_yT!68eO>fU`am}5jOM7gl-D}bQ)nqv0fCDGO_ zVFm<8?|J9-zHb#@#_*#?eo3D=&j0Bh|Ne!1cMVHQW;`q%6 zBcsQ;Z;fGt7i^Ua(93e=?*M|Xf3MkY0H;VcoDg?rq!V(1ss^8psMBGP`;Cebt$NnF zzsjj172{~xH}zNNrsmp+eh}$?e^dV0XXQT3L{mIjxG3l@b5xtX`Z}#W0e2F>9OZKeoxz8h{JzCv=9W@NQ_ovYaex?2ETYmHZLP0+92SYm8 z_yn#1+2$?Q80@ai@)V8L(;KL%i0US@C7yNqY5>iH9O&m#xU8%b`&%M0Em86a_(C4U z)~e5TDsTH8fHeMkph*kcQYf{4ec^2k!2m?5Jq`5EzxMrND+A#ENoyg@`R(1$YyS1M z;@vkAleH3@VE6exL-Wmdte*rHehisA6_oq&g03i5!>feT+ACUqkL?%i3E<}POPu*w zE++gwr6ka&!AVuJh?){9Vxx>BETl zs9eLr_C)Vm7wvuwXNp?)hI+TyJ%4p}IZz}nL|6Cb3h;^cm!)=c;{916pPt7;BlkSE z<;LjEjA}IwfYbJXe^&AyzjSi#%O#Hd6RTv?+6aN_Wlb#KoW_q4qn zU?4+71T$LBQ~%D3OjA=i6jUq(oV?GhX&}j7++xfN?BrL|L2>Vc9f)Y!8kEzuE)oLJ z)V)jw1bo-d5Q|TWC@ViD#37ugvaIRI6%Q5lJhwQYn`nvTLG{Pwc6A<;D4==fA z7DsgvHDTwJaf#xEix_NIXV3vQfH~r-xuH08$G-Y*|!>dg9snH$cTxifc?{9 zqq(#S6n9BS{%ttIuR$`&c=FY3+>;2p1KgBe!h@mr7wz}Y-nZpAj#<(AM|*Fp_rxOV za682uNpacj6i+6Nf;>j`j>u8)4 zNu;ZjeQ5a}uM_X!e`LX2pYsy{IJSECSF8GOxZceF({g_&Wc|jTc@!gwY%B3-?C{?4 z#QBRon{qmbDy(I)5v}AdkYiuI1;x2W>B3ZxG8Gx=7o6#p4Q;tfO^AG3On`9#*`WGC zu21wb~9{?VS;^PFI?*4<&r~*!xv(@6t-H-2QD~!(Xlz4h!F5`#G5% z$F(T$6|HR&^Wck398#e!-gyfwr7!_MuvL`O7e7&@yMaWFcZ@Wl#)p%Bc$h?MtEshS zdd2ZD&#j!9T4LnEtXPHWFNk*S>exG$5D(3B4ZkR=oFH#rFX+JCDe^CErkfE&50@+C zT4MHD<*G`E)AXLEyGkV3W!_QU1Ydg>=9#ae;wpN|6*Zp`UX+$p2Hv1{5K6o&@7;R_ zeI!rXaqPZ|A9P7*CrZfWPefSNQJ`T$#m;v)V>v`KS1PZ#CNh1$vumhBGjAkSO@%jn zK7qY+W#lDdFjv?OZWZP{t8iY1cmFp_>R<79U;p}ZG4S$R<6o>wm`kdw(It09v1%6Z z?cglc(BqAy+x!*anegv({SQM;{cU7rHb(-f-hd_K-r1zr$KNXuhwXoS~_@e`z zLV@WvV(%N?P13y%DF;AeEu({X7 z$>UV)o@uu0O6zlcsA*;HQft4jtWbvT&Qd_Ifm3dbR4l!H+{RNqQ}N~(zpd|_g~JX| zb9$+q$fz?P!%h~V!PRMV(b3XGs|xCjpMujWaE4t&G{!>O?4p;jm1M-x7yO?I)iL7Z zXA#n^CBa38g}3yzR&t#&x{5$DPsGvT6UQVXw`s-FwsEHc5>R# z)f%@`h0V;^Ff*4&rGc4w9YodLHs7GSfmWuy{tmPX40G8nZ}wvctquJ9)1N~~;NgE)8TK-rD4;2ia3{9#+s0hhZvNbF*kl~fuj7{s@O2@y8Pf%OK$lWD?U z3&d$utT`PsE4kc#%-8)?D4Rk*I;23G3iQFR0-dYoX2@W;;mp!xg?uQiY>AxMq-vjj zE@4*EeH5|!B<1yO4W_{sd;WqpT}-&15xt*W93I<@ZdFB0dCgP=Mj6EQ#?I^9P^I%J z#QU?=NoUX<6`zk1VIBsXTE`C%tkLF+#MzuNS$(10oT&(cijgifQ|dAYRyoSP`1Nb1 z?fIuhhVzMDDmUaOh;!YUKeaclEl7Q-=vgYpD^GaLYz-7bCr0xN*26-0F<&Z1=Lpdy zMtC#KW*aUb(_xo*n>v*=jvVZp^}?aaHhuHOc3-hbw8sOjj|-=aU+l<~qo^`IqDeK< zI9ojLe6LbT33!^-`oRWYKy8Gyjg0h@u1!|5O^iR~CgU1+kk5@+UyN&woZmM+b328$ zGeeb!a}s}V0^Cf1Sad4lFo?0?c3~qeZx=P81I_V zvY}GRhgqtcaV9_ZVP+x-^UpoV4Ix@MTrIUNQFR4#2l6rF>;dZOlTCuz8wMT2p1YJ5 zY3!K>Q5BJl)}LZ0oI(#tV{a)+9tfrHhdenKz$I&cHc)U>?`180l&;P8I@PZglJqof z*t7@(Y6Y{@XJGBEwE+M@!XN)^?f4I-17Uxjg7`hq_m5rg?}Rx=Hd~+7wYsay(bGCF zbsUspr^P=GDg2dF7!=ljeBV;FJghdIjG}pZJrZRamD;5m)%MVAz5AMG)>RT<$+Mp+ zXQ);bTGW~YsaUdG+TuWb%27)wbMD*;(MB1lDJNDPx`>oa+8?CFkv&4n)NENMs)L<< z*A**nq8Od6IHNnL_ANPsWy+)CY^`!ZImTH;k7U@^IyjL%3TtKrPY1wY65^BRp0o8H zpWowhxCVNoWri5n zNgR5eVG@b8X0aQjB_F!VdUe@S$JMo6$_Rq=2zbo!Ba#J1;~wqPEx%nN$-v4tF=Yoh zlfpN5z1n5Vw$a!_=1{AHii_ZIUQTzW~vP z!;fBOwsUUpPq#BTn9+~S>6F^z#dY)z=Z-Mz{b17CiI!3~U6^F)$fRVDOXtyQrZuR* zTFcfOuVTMSSa+BHRF9QbjL}@Ke3O^OE%EbsZ~U-GIoP0^q{Tz&EfIR_!529@m*V5D zm=cKUw+feC=KdekfnumY!)1Zp<+CFLUFPbLfaMqPE*C?7X;6oiut?zp0VKLSiehGC z`rI(x58asSDGH}*AN?w!mN!g<=(5TOEv+8xRlix=cXwFkX{GJle^eOLjEHzqJoR$Q z37ZK#o*b_VH$|73Cg1mFMii{-n&~9Tc=z?K_|nz~cedpPa`BcXx%1GEx-^kJQsm=3 z0Da1Sdmtfrx9+wd@>k~OoNcqvx#!JpqJC|IbTUWUymtCBm-oS|#<>H=rIyihdVY&4 zX$-ZR_KfcatY39TQ@f#xA0m%ANu9=C79M7^_O9K6aGjw&WeJ?5_2027fAwCmv>#jfGMZj8=cGkV#ktK{8hpdaN0}j z+b-itUaj!>67uOq3#~SDnZ^0Qo9U@Thy0%mA0^&L?IGLd(W{53()ClNgJ?_jY!T zJI8`pesg(*&L$K#XQp-uX^aUX%kdU>=r7UP-HW{u!XntFvr{~(*SSl-jQ-iWteOhs zVT|Z_T`GyKn2RyHj$4{7lgD}A(_tQMt8IiTMa~z^lYClT{Z{jNXYiDGuwdnFJ}){ zK4!XJN)XkF68|(mB6YaS_3H!0OtG0Z8;xFyJWV)=VD6`qA4B|PJ8xuG)$rY?9EGU& zvhLHt-SGs@gA16N$}|UC1+TJFZisWAZ&>9^IJhX(4{Oni&B&&h?b|s3ms|m!Qnjsi zIXGQ_$V6$NA>Gdk?&0F za+37X3j$3)e46KryBRnILr&^LgoXx?`+6oi7v%0Y4tJ$kM!t{kE)GT$&Z%-PNx#0E zX2G$scPvamI>kbe0ZIq6gg1F&%c4MfVw%jOj;GeyE}3O*h$E#9PLNdtUT|Nl<-M$? z>c!yjyv%a#LRx15MR~?=9hn4zun9cb`8CGz*Ik!#UL{-};S}L;-v}W_LbvhskC-kR%lmX6N`hhhg6h8w5goZ+uza)2L&w| zl0O3n#b_lRjgFb&|J>hW z$zH25w=vi_f9H@+WflLc9YfQ%BfP?rNs5=}pG$Sk0GVx{7HHI0{8PbD0j9D{*9(gE zr(7+P3I$)w+8@W-;)P^C&dn)=7zz;+cTxFM5%LKrz(s!upo|DfVqCK%+K0I^^O?hQ<^2NbQ z$Mq;&)sAB&coZd4f67C^^7EL9{$7R8GK|zG$LV(G{q^}#D^hx`_3(TuU%^AWg|TAL zBN>r8=NQH;4bwgdQ4ofN!I+YG*k33cYC2g7q#Ru|EN2}m4Xy9VcBBhG{m~=QWs=gS zPxvrty*T>VDBgnOWFVs>T>2LFhs5wbZ8S`^OO{zF<_cgf$Ld?t@$t=9b=Az{ioxnw zClg-7azgMSzY0M%HXe=%2LLECh5q5n{~u2z#r%2R=Xb>7w_WGo(dln#sFq7!XlBk? zn|ifcu`>7+bm$YZg^jR62Lq>z5ll$Ec;h$1kJVGo89UvZe=2YrMZa48kdt0Jkx|*< zff&rLuzF+Q=$B5XCs$^kIPA%t$KeZfShbqgJ>#}b*>?3w7o`oFQN4ek^i-ic^JbbP z^P=2Tc+I2%91f$9$;f4?W{v!6>J6piHDj;NZFkm|SMy&+@zBmLG%3>*=a|*&(Z^vb z6cF8bQyMx;zAOZA_qI`e8l-A4t^O@)tNhZntx2o;+k^Z0Y@8#c`WxfO5puahZMxU& z>TJ*lzEC3B8l{19rk)CMwApuFswqpDiLO8-NkwXwbj4nBc3wbU3#Poyw#2!ka{|wg z4{Xc!T^#92Fdo(s*vDm3ek{@%ot2JP8k;27&t{O{L85aJwfS9;6sHfY!bGD6Rzd~q zvB5M>Nb!;Nq4vrT6Km?yYshQFk>eIeG45h@A4d2~=>=^9(-gOFX7w8@E@kxwObR6G zwlgsQg3E!mTHbW}Xmy_#HEMP5icOzK7(aU?Y}L%n5A>m;R0+nd!X6<1Y{vdYleSl0c3fMJKEx zqLdSvandzq{P3OyT?sg}R!D`{YF7R=w+naKz7>( zM!x4H&*`n3^PNeL8bPM9=HaIUuyW((=WEmL8|A!rLO*ups@khdncPD~K?Iw zEO%=k5%6U)?PUV1Nf7n}e7(l;$~jI4Pf?-9)kJpJ$XNo&d2gxQo(fpYv>(o_n#$z0 z&hGG(x#=yY*gC&dL0Bn}U+`h#jJ=g~=MPBsPLdaMd2R4_MT83C$IZ^u$717*^d zX_#1}SCYt~+&|(^#~YJt@wU7o4SeS{ex#0SygvN+dQ8f|RA?`M5?=LVthxPBStgSL zTpu)Zt3=hWlIz1`QE`c{g`1{B`tuLSHdmUhYLvj51vTA+)Vu@LjCf!RR6dCb7-Htrm zVIz+OdYK0nD1{$U1GT1Gt14=Wiodd$1wP)e#)#6nz04@tykFK&!`aCTg?;DY7i@t@ zKKq;r{FU8W)Hok{NT(y=W*9rqg&}_O()e@>$X-4##k|-OGU>{f8iN`@a$XE)9}^!H z+ddn*D_mAYI8e#fz?>; zQ%vT{%f7hb;W3@Qe4w&}s&%)LUwKn@g_m3gS+MQMZjHil+IWBJ>+~&fZy`U)7S74O z&SWHH**0%;G?zo0R!12uKs&#nvS>MwV!@t@T>kl9C)(%}iKs^&&$3EC?=(n=-pzI#>bn9|)aV@-s!nUA zePkXr*QF?2^2-g~CVqxRpi|cdf8Og2ISdP2c80$=?NwMeQt#5O#8-R{&X`c%zZc|p=)dS)~v}DjxBqY}qF!2blL&<(FqTL6QD}=A` z8*CKYeIhTz5IwOAY#utlI(b*;q%Zfs&+bY8dgZvA`pf-|y<6%voU9HoS!tSQ&vOdi$t546p-+OuAM*z6k*#1i{o3_)NAv-g23nlSq{%whKy46^`lMuRtThDO+ zK_|y#qi0)3Y@jBA-_6NONe#3&6m3BewO>t-`6rhr(em0M+OS3RQ`eFbf*v-GN}Bz& z2d?;u5VYa#83>r^Z6>?qt><`cbW1ZLj(r%h<(koL>=i(o9rS9=%?);6(j;*hyRP=~ zgRM`^-W-JoAG%y;Sw@6fh_m@U4!S*}*=)ALFQ&ynoaI6_#V7+JvM@{f-k%hBxT94*t$Utv$z4SAhColKb54JVrse>n0aW{V87e54wHdwqA$f z`WphzmcP|6TnA5-a3T{(_vRL_PgMTPq7TI>ezlK#VYd zZx49hCGEMyv*bF>{R+(7H|LJt(5P9{`l+*cCX(W>dY^?e?uaZhT8`Mh&p;4%cZV#X zIOzFDl|F~A$2JkvCIm5NVh7*RD1}SRoZO84+zA*jaz$nTTvyE^_%*K5?L)q z5_NLT(Slu;y;M#DPB15dB@6(#Z~EjPTI&A@m;=BO*7%!t;)qT?c3OFgo~*7EV2=++ zGbT@CC?Z$+MX4Rx=4%DUH7O%|w5^_vzAcXt*rMS;)uzDVqI+vwed&Z`wH77+AW4m< zf{_#KVs!i6@MhaQP>-&cZ!qIncQm*$mqJnslJfy%B3m1FqkiZn`f|l7( zY(jCJu7ehG#5{BJLMAyHXR>9FZ0jo|d#v&bYo#r5 zgyW!S%@e?#(hq-o? zu(kYF-dwQa{)pf^01Ml@f7R>%F*?^D9pR>u%V2(#w|AGTav2W-W<>Z2emL~|w%7nEdQ2|fksg~R^QhQ~%0BMnowlJEEm(4Z))9`zBrt=>q8 ze47d9S(n0kU4zxEVL=@oZ7z{Ihr5hDOy8p^?Q3lxsnUyO+GH7b>M_flGeQt0ksw>D ztp#0#xi8~2dp6RJf2VO?C?<9MJC$CMb{-jdB!dYe18iCAY)^mt$s}AMXpBaTX|o&h zAk(&*%Ek#2F1M9-5>L{i;ji+T$I7*SH|u=Y%XMAkF3ddMpj6wgzq^>v&cdX*YjTv) z`-3|H=W-eH3Q+gLp+$BM*cTmrFMcDNAwS$z+KjrX!NhdSoqL*v#`*U0^{M|h9O{Xz z?w)>J_G)DCBEBVFS}m6-GtocT(UBkxL z^@9FgDF#-~?wv5wUrP<4R{$r?atm35p4xYvug^nuQQaONnjVCRMKB004fTyD&Hr#H z$f=#UyZar1XSSpU)XOMOFHDCexv`;VhCq8duyK(@a<_>K_2Hr6q4AL+m^uK!#Q*hQ zO~3z0{(taD-i^H98h_@&`7`p%g&z9ng^)eoec8t1V>)Yxltv4D;L+YjYy}WQSCa1y zeA=xs3jiekUh}s`e!B%4{B|tGh3~Yc^5}iirKTkS?@vBDx!P}z)Ai}%zsTLk4Q?UB z_9a?ZfNwQ|zJJFF{UB+?m2+VV8@*tQT+qBMd;SLlPh2!KB+;W#d1f1Jb$+UxfCYk` zIm@tjnleEKH>Le^CVsjkEOs^&`!X9n1y-p|S(|>Ib99hr+wVzuUEiJAeix}1<&=X( z^^ML`xRd+o7iloJm8LwB*<$;Ym7Z6qy^@QsW_Qv0OVq#G+gNX%F}F(>7K3BX$vZQv zH_u}gO&-?TEr7CRhoj@mhqYx#mJXkuNZvY~t?6-=c0r7>EV$)`RhH{{CPgRs{F*6` z*@N+1J50I`0Yx_Mg^JKXMwR-R^p@~aVj5BtuCwif3JDC`HY-Ua`L;}Uj zJ&e<0TOC;9=T^3dKq%d$e#$ zmwWr%owiJ$gm^U+7I^tVoKEf<(&JcVSZ(q9@B!2N^{!llf}!lfwrR9j^E+#bKpqB~ z7ra2*8ec>MUU)f4RE00ElvzkYZX0}Uybg0@!+xm$eci_-`q!OY4!vGGrVt3cLVa_! zHqNleeOVFOgN%>Wia&+C5L?h#G+*Zkb&&o)?7ekZTU)y?N>^<`3lu37FYdIs!z!Kx zDP9OtoB)C1Uc()dKyVK(#R3Friw7rou;NZBMGA%XW_^2qcXgfnefRABJm=Ye9sYnB zW*E=Q%$)BS<9&akR<}I08KC+KJ~%<=eN@gMS6funPM>Xx)i5)*Fg-U<4CKJ#mgi!M zgZo;W0rCiGn@Pv_c{oQnKdVi$wCX^u2)mVgzNY&`B?V5`NCz`3f_hP^#c6krm5)3| z)9(he2ugW>yKCZC;4ctFVBNH=t>t^*l4YtU*6zk3+$p7+UBw@HeBwYp7))Uuklx(| z(+8gI?Fr{%vqN^;;wwed7Z;zTQMNop+R>}DRxN_{Smo)J1=SBkqVBPk!o2IhNI2=2 z0wG0U6RZ~sL-w9>;0U003C+Xx!9DVAz7yD zO0o~PPs+6R4II8m7LQRoWO>r|o3_73+foj_-~Jt104kN30ztKqxQSY(g0I%V$H z)jaU3G-2p*n7RIG$g0!HfEGQIWi@d&RBkhudnz&?8ynmA z?XCkIO~#9kN!pe?mAA944MkD)^%hFm{deqjeiAX=#Il5`Og~}Xdqoo}6(+F)0O->3 za)FbOTf)rb4B+c>7dn+L!LMiqN^D?7?`BF45senZvh$q9;-8J&-8A#}D#xr&ZENRK zM_8w_0D_J8^7V}1f_;4hxqSouiq`s)OpUl>V4v5Hriwm$w92JN2SD^Dk5FCDm3Bu@r$fySCu>Ib ztaFtewSjfkIS$k`=#z>bT|Nr3GtJuf>)up7Kp5_wiTkz1Z=*D>g=`j+Uu4Lg-8wt8 z8qsDsk?=nt{rsutj6QF~yd)&CwtAt=A9f)5`f<=P0XC-Zko{@#$6e{|&L2f1@*mqS zAGnt>p5P;Xg@*oh&T~BCN-H}sB=FngRRihW2C`qVXn&piC4&DI3Hh(1>-;;!k3drX zEAr0lOvN3Suk#E`A0z(pKX}j>es9nbG4DCNMgG^hgqJafFErndVR(>aUG;u(T7T4s zuwnEIEvS@5GN8_L10Cw``n$&9wdwon(P^~2dLgCyI6-&Ox?Z}~=hyS(0MS3|+6p<5T~+$rM&5moXpfBDxK zzaIUM?X>*X)UCl}s)$ZEkt6E4xF*=2cYhq0`lzklsI4`G{VukCG~Pb#UAdWmeR@_m zlNSsP>i7OEaO(DxXnkHmr!P$WlZ+p!raei#3|+FZJ{}WyN%OS)ZL1-QIGATZ(-N+% zV_ujJYpF99d4{%9PVMwD6lmb>tMZ^?lM8Xultja+e5a(zdB>F|1URzp_n!b)q{ATpG z??xX{rG_a00Nuer**0{Ta(>41y-+sQi~Oz#x_~y!`JM3m}lqQv=#W&v`gyLoXw&$rD0x%~@ArR$_%Fs-{rF7Q%M; zFgBrIO4~vK?=km2s5uKhXD6acSAVzRmfu@EK0qjX4}I#;&loX9+| z{{7P<)5~@Lh3w3A!>1>LQNz7CwpRi9CK`^JFDohL?Db&`qM=Ai+g&ZU4_T+iPc{=o zhs(GOoRl#s8FPCPI&fD|jTz#-lGN$Njb9hm zzmkz@*xlo+ikWn?>7g=?9_eB?S;*vPbiF0CGR=yTNllWr(1I9qH}VA4HX&?n18KU< zW!GKmb)G`KW2?Y$vg(_zM?y+#_DA>oq&-a>;r)zM)h@I8;VQ|mw7n}6L0tZ-?%bpa z+3s3pzNuO?H6w{vJ-MoH+`J+U`?JyDp3yUo75|%RpjIsjdx+J|4qG$MWkol#DRYPV z5weaU(cP_0Q``G;lCYXnUiN%)7b>BiwZi-PS?pGP!9sa}WpFfy1VH2D<7C`gVRp>+ zHdw}s^rn4v%}*khH}pO6J`PCJRgvAC(ujCq_MG=glDYguI3PU3yHhYSv6)N`-G_#1 zu*)Aeaov7&hqubaiOe_!m<~m{SYV%@(~PQVK#Ocd26%+v3${xcnQKH+xDfYFIsJe$`MQJfWT$)Ebi+;t5J-gE)D5==to-uGC}lio|Bg zAh9Mp@_XVM1#hmiRz{C~tTBMw=@l07(R7Nir%RcoF?dn1I@!j=My@1F?_?%t%pSJ5 z6`EZzI*82g6jMn&WT1o!6?3XvYF*=4!-iW>0X6$zZ?{(5?GfBx5z6ebOLo%;? zk;d#=AD3?05QL}oEa!P;AuRM8C5*vDk$tkK^(>#^?8J9xS8$O&Ufbkcd3&#@9`ut) z^6E~(c0(<1DINYw20efh4=mSKLxg974&9q}#6N`Qi-?u3)6qg()l`CjY*6lFie~pL z#v6g)5y6B+n|Hz)Ex-2-#(s&=rT4&_8S-{%NXJpI1k|fJS<#O#xfWdn+;N@06Iu`w zaa+|SV9CTVws)#myu&f}Wvo$Tw<`#Lj6TLT7QTCZPATr%DqntX0~fu!AsQ{40uH%O zSL?y&tc8?)GG&jg)dFU*OK5R2%h)l5b!;CV#gnL8JM^E{FqD{xcsQ)|)^beGED5cX z4Xbm+OH$Bmb1U%qH7*cDfZ~PNp~FXK1qOUxq#dQ2dAhiZfd5x(8ZaPB8Ag>5rz=<+Or`;m9 z6gpXJgHT|_Jr{s}fZ3;O()Twdj@+gClN;ggmA@7wCEv=4dKBC`dt}v;QreNC*QH-n zf!KhV!t?@&h=`*{{}$bU@x?E+mH#Qq(!Y!BH^Z6nm7S%jTfScmb8r8mG(hwhwsYC= z*Ovc32~>aM>^%pKl)LWar}r8l<_*+4WB0-=dQEfP0ozW${aHf~!I^yo@~Trc)4r zl(ugVgiY5~Ddlk*SGu54)%v%a>B4(qlT@%%=Xlc6Bo{y`7TOi)Mb#&U$&OFvXd+MR zrz5W4d4Bw=(E;9Ktm}W*o`u&>YCx%4UXb#~af9MnxA}V%%^d9O)9vBxm9gcnp2wO# zdC_OYGjV^ETg$LlWJqAOV3aB$YZHa8U>4#uKXR+@F~u{~jAi!TcYe=JfX&qEZkRQg z_HzRq(QMFOtX%&1VsY+--Kb@5fYf48%pH{#6LagDJ(OVSc%?tiof51QHd9SOX)Af* z!)E$Q{&(R|jU(L8@O@qN_~w{_rgE-g4ew6XVBPGcFJwrZr_Fq-n=g4m%p2|=X>Sr- z=|_&Q*)fnN6K>iLjJ8B=3$$W>!DM!NXef{)D`T_@FD;oW@p}6QgH7DvxTXRVnKFO8 z)?Lk)B1xVCr!y^D=u_C2!{V<7RmZUxcRUUax48$>)A1D}v{k*21M=+*ADD45xMXm> zFP8>7w?5%O<7H(ZwvyR|cTLxRd-)>JT!JDd&hA z1*WJ383#$QS76VnL?(sZq<7KX(`^@+t}n+PzHi`*UZ)dIQT&$VKXoU@(Bfni;8kTk&L`5m8^fX~3kTr8s!y^W;5SEob@U}saH{@mUr^YGTccuf91NpSJ^$M1E?P712hkt4UDciK>=^F$6mu3?+cq0ce%(@H#Ir8WNYYEw zM}9N-TG-%D;r5ZPgPmRXLB9R$0dL&lsHwz$Ll&H$izl~M&u-A=`()76cdB4n`gt+5 zh2cH;mZp>7wW8!``+9gy!~9%d`cTEToe)E*|0DwiQUF8m%_9Op4O5qPnkJ&$Q;WK+ zA)O2lWTMPvwzB=3qhVo z^y>G%zSsm0#cK&$%~Fs5cUSa(G_4VWxqiJ;x(e`iB~id#ZP(DoCfHCDUt!`tMX%Wm zeOF9MT1lc?m?=)-PO|}awV>d)XmX8N-`8ELfaw;*|%{rGP~e z`hcT@(5EvQ7dMG3VfQH7+}lYu!1^VswFC-|6{ z1v#1yhlh0wS{})}me;bon~^k& zYuKCbX`+?a>rbYKX>K3b4%a_8?+n@A`=QRM`+ZWO|9!o#8owcP3#uq4V@y#P*u9n< zx+NfJCi>|`x-A-tRGLbeC}7_O-2JZdfF30`d^U4B)ne{ppKsjk`I;ECP z4x-t}f_bMYRaAJzL9f+2_2;fBt`Aoed~aVIC$EY#<(1mFpZY0@75ENryP|U!*^D{* zhTf_ZIwAf9RnSwSRI?9E+m+QZ4_bcyazk_X$t`jrtCBI@(x83Xu>!;TAZI}ZJw5EX zI*&o=+pdp#EkmtNys}tqvuQSZZYM6KBlOFU05xA|X}-lqtI)ET%W4Sea=w;i=~6<8GbYR^Vd>P4`8PTyLY zVnFe%@o7H~aYw^-i7o|S-5L!XAN8j$fnhI?t|jt1+GNFgLb(-A1IU7lPYa;)Z`~;Qp6UAei)s&~R!@xhzkh;(Z_&?Wnlmzb?gAI5 zC*tOrb*kf`I17?#?tI~0H>EAp#lnnHsEAw!OPA9;23xr@)d5ur2~ZA&>5XjVaW3l( zUJ&yxs0H6pvmx2v$lGBd5#Bm_(ds{fvXPKxsz(pLKVYwj6Mm()$oYt%*UViT5&MNN zNP^=^W5{8+zp9M2FSUi(@kwcTVu)!*BQ_Wc|kK^pnesgOV0DYqh1TYcdY0 zR&i_Y@v4j&ot5qx>|D(@kOrkRcDN^u-Gp<+WkRKjX^2a;-$rDLojSdI!b9kFW`BEU zcgwFV>aWp4Z>Hh&VlxMwX-vg4{{}utM-NgUXSN)Sr-s+$i~Lh0 z!O7@`QT*JQxNe1(VCmuwgh_%7KCWKSRvW#z27g5U2X1NSM~=0>yH&F*;J0Y~q?Pwf z-=$+!t$}MYt6Gn7nI`m$;v!XtF`n##joWPb$#kXm4aN1i@~HC2l3l|Lk3jG^KA@zd z*6jCjcA!f--^PfqaEv7N3oY5;2k}Yt%h^AaI2+cu#*f1z?oaf~#eevM{j&aa4VpW( zE)D}UPQWg-Me;>e!UrzZ5QRu&=*8`7S-tv=I^l?7ACn)FRQ&H;vZGY4%1LK5T(Ih0 z^ESFt^?PC2YjB}2mbtwW=0%B472h@Q9tpUy)%VT=EBKdZ>(_RQeP{V~#oA3pGm`eI zPRwuD#K@5uc0boM8V=uV$=f?+!1avvZuRpv`}NH!{v_heGdODC9;vMXTobleD};=_ zNb4W|vc|GWPvuR)@FV-AITG+P`?k*!rhq}ySfr=U^lNPo)HHS6X>HNXPU6^CuCf)^ zmx3GU4=Y4i=6Zh?i^1cwyn?4}S6ue?DgeR3!M@1Y!APry`@SV-+L=2; z`b8N8U?6TTkW&7TDs&xFfVlj@8*RMW(Ep>%0@N?0kGeX*+2R~^5Y6ha_qfp1E1zu4 z`Nt0fKZ&*o>56y9ZjYKXJtJ5Hz2=~!#?~eU^7McoZKy#M!Vl2-|1Qh1|F1K`AKESd zZ!Z1gmq}!kjJ&w+oH1Gbv%z=1AOCiSAn!H$u$XU@bW~bwtAoXDOJ^9C;!UkfBb*L)7tl{I6ryze3qEIaFwmyT#4}6 zWJ#`5uGCp0x6^T6et?Q z`e)2+>v#t`=8q|ivEq<%?^2-n!-l3db0I-qPTZ<UP^>aAKj9zIM9NFuRPXspgl*GLo_4^b0Kc@;6!b0o; zHhm%g1b3gZ)A(JN?V2Br5mrDxLTNi~+shycG=JM({r3hpxuX=004W-^W-_wWZU%=T5KLNr_Z zSTZVTrRus8soF}+_sSB74JMzs?fEG2!>k4bw(y&o7o2Tz=!`P7wD)epCbK_;T{j8l zhq)8Rp?oi3zbO4Z0y1gAnb;H1BVn+!X;^wX^;IR>`M$d=K4q>1c&>1Ts=Q$jTbVzl z-!~dJ!4z;a6sAGgm_=^|R8+!$!x;u`&O>hFOCaBRA{f}bRaOwld#@y5+w8)9>#=6S z&q`4I9|g0j2j0#1Kf7z8(lP#F1%mO++T@tbz%4V^*V%EL$ekW~F_x%<`wyzv6w) z_F+XR<>Sd8wi5t-oI&cE`zqy#>#VW z_S)6V%mO~bQ3hj~4RYx9%o5-$Z;u+?~~>uEV>w#RR#a&Y-)9&^m2- zR4LDE*Gst)IbfT;{+^HAHa>1vJIj)a7vWTG{qfAwTx?@iAh%K@HN21)2HB+3qXt16 zcWyC<$`=&s@#AFwYAl}#@=lSC`PSqin~m6JJAIRAKi~Z+%MB=Sl9G8b=#b18fw5!NobsPj&>!@g0BJC!f$%E2`$o zE$cN*Hn!ChLh36%ZhjZX*_iK>m$wTkd8xDj3gYJ`5z$|S+u{Sv$jHei$9;FfEvNWC z^Ymv|u$ioE%SR82qQBOp#;J400E8VxX#mf#`Zq$GbPe9Ra{*?#stBGAC39=@dVzh@ zS6m*8D~Ywfuqy_=McC2K1{Xhyx)G6z)2dQ4o!#cX*DiFvqAU^M#ERzB+XZ4y-&TI1-m9lg)vri0L}{E^ z3N4<9LtDbMTI~F&RvdPI#=LW_mTf1kCy1ZMo zJqzBcJ+g7;#doW6&w7M^jEHOI6RTlGFIe#h$PDp`B+l|y!cgveYIbYg6i0WSns=~Y zE-EJV1We_<-BO{0^2#?d-CR=+-C+iTtU0N^d(lw@7^F&Q#oK#$L<$;U?e=`q<0z(i zd$jmszi(WeaUsA|ZWOuir2)$dzbUY8Oq9#ucAL31MM7rcfSp@u)o% zPhVu5qg&@X8|5cw0SS@JQh8ETwN33SrfxJ)uWD!6wAF#Q#jArd({x+Q^kNS`$z||| zee=+`o0QaaLjeH+CjHB?@1?kc$3CB5IDa>2D7Xi4%Q$>__Z(Jb+3A?MvG@D*S_gUuX^OM&_hN&NwN z3~~FT=|+wCXBY}sk#wW+in(y5enUuE{T85TKTqOwbER`_w}6dEuuci8)cS!6 zJI8qi;GA!f@_mpmgElN(&Qw})25ME|$))2^1hi)*!CR{Cu+m8Zt`|GufU~#B?hVS* zZG9Yl_2}6ADt0FR4)N>pm>`bxq?aT=wku!FktS?+m(zKEs1`M5$SU`V)v@B^X6SuL z4>uV55z#p7Nq`QCMYUZ3@)eSrAw{W>yN_`U(0bUtP>v{G08N*Q>L)gqcZ?0Db=8tG z@%x|Ix^0}Taj^>pOuE3a1U*xk#l}kXaVFCr2-nlVgOY&s0(b`YSi zZW7IgEjTUd_tQtlrOg#uGQCyDW#366-sYvHP*yn@w#|KRxYpNaEn)>q45VKWFLm_@ zUf z-XDxH-#+Hp=-li-d<#B3aXApnj^lFs^%nRwf3HAOWZD`{ zScCb!3Qk5l!EUj_3{5pQC<&k>@?2b3+!<6|`#tW-yO4NM*%leUikA(pQdo~##9ne~ zR!aUd`^xig$+baD^0(1xrjz>S0EktR&D5y<==c=aR2j%%nl7EGlJeBPc14dmjIxmf z83Mh$nHFfd*%)U}rc&(MK|pJHoCjs9HOAc%5N}WYtSOFxv$<=+06e0mBayhbK%+v< zO^d>BAjr4CK}TQ@|HJV(Nc{vFG0E8)@E}c`shREe3zL#Gy3k%we4k#TkE@mvtnK@; z7!>^$Q0}S~DF3iq6eIXYcGS0qNj34CQP6Iu<%_7K8TaiQo1~hNh5G(C_Zl$zk;(7b zG}xAn79jL1<6oR?^$fJr=bQVgq+L|(`sy}($`4v-WTrXmfQdy?20Kw&u!Im#T`8zz zy|EN#B8$Jrvm*LUzcWMnDN2#TEE}sAv&{|n#&Pg>z{JzhA}cdztQ#m`bWYfPs3nt( zcxV!u&Lu;K_wyb@UoJLTJ?U{ajjOYPR^Loa9$8XSzOvm9hEmg@LX}{4z3W<%v{|(F zaTOALXv!c?I+LAUu)b+}pgty0H_};GM2_*hvEeS*&_jj-K3Q83(P42trDw-XUy(0z zY8o+>kk6C2q4F+zVv8~jPIpWdC)ba4bmzta|1>-MNdzF*u*x1U^_xdRkMn0+eUz(s zx9@9D31w<37n=z(3u^Ay= zcGE6Sg^nWMr+ZG~j>L*jI2eHG^6A2 zu(M+bFIN_#q>i>@u7xtDO_#G{zR@M7Q`XSUx>;AHFlLq%aK9ffgONEOT=&kZp=us3 zovBS~rYAjas$ySNN;m3Kn@vh%(bZuJFTXEkV6-c~o+wgi5i7Tbmg??*gaS&&nDf?y z-wCYH1Z%8UIF-|<33JN+77UFB^FFnc2oyw0b2i~(8v$P=Rz_{}MRb#5>m1Ktm7G#- z2JJIbu|6(eEk`w0YSmY6t6Atn$XE;AjtvKLB0>kK5_XG1AS9_hhGmayADn(JbD2lB zyx>;k>RwM1SgW~*D;gxIp=&+XEW}8-z{hLG=nh>UW2e3A9;DIta`&x?@dJ*l68^lLm<_t%yozN z5<-H`K+^^Wg1t}DNGhrEgh0;kzO-eX?lLXAK}EBM?)bVU545P6aCR^VT-lRYosUhT zkO)je0?5pno7hNQRRT&uw9M!pm(&V4O}s(O#=6XR9{*6)wN**hGXvxupJ-`;*aT}m zAKmY!y@mHNZIX9ll5|JSpN?7Z_2bYRB7_1^)kJV%VY(@GSV^XLgG*&(ljhlcWW1Z( zOru2OgIB~Kmd87Kd5*l+AGF!>`y=isWkV*PQCdt#_?%u!F(aT51{0^)Z>Cw} zm~4wrLzvQ+A(*H|k-BhWGo-J;p5c9;Xeh+HnaW>%qm<7v%E?`m@>?7Ps94VI<7H{= zA$!x@eu;g#4ZHGXoDvh1rbWrO$C!9@uFj6OcV$(9=#U3g;+#Z;Lcu>mFtLrl-F`B(8yS)A-M=anQ6Angr90aZ;JQ5>rG0J4YUg?(x0hXAm-FKD)~zyUAkA z?1GW@Y(@+_PmL}GztZ=SUGj$M4pmHmJ|@Os<6~S;o_9kH&jAQXW5=mpnwFWnf0ogDW%EFK#g33HW}3}6TKoG zSGH=EsW z%@Eow(8w$;%Ib>VE(rZ@&LakkoIJiWuWnPNZc_1JF>k`@0Kit%-ap(QY_PGbC8uWs zBu1x1avY7->V>Q`i*wdLOw6AN9Lj?RGGF24edoophU}&ZT||=EuCc7at;e6_nW=p? zF}v{~M9KaUiiTlh&J3V%#j$es*_VJg04wPc&jXjq?_m!J#%l$J>j! z8^_N^eCTvX(qgguG7WdjMzI@ZYsizKa>Qnf*pWuSH8CbI)#LjYrY{uUwN%=Eb5Yggbeuv}`p9ormR6DyEDEwiK8D+V@zm5S<_qtbamBHFXoY3(+BpfG zqh6(vEO1}oZ0aA&ur7YWnLf%N)`Hc({jo#gEzbLB2Eg{{m|^*Np3~TpoTPS|Bgd(k z*{HLVIH5WMb!;WgIZ=rFcSYOl&#QlNY%)~&MUj-GOEC++WiS6`4f96-es7W}ZB0*A8iWfa zORr2uZHyLzOV~E4UJy4w;<>!;TX?u`s#-HK=eO(BDeO*}3YpkzYKTihaNSKPOn3wI z2PnWil*86oJKEB?&7XsMc~C8Pena3_X223)c`tk<4$Ve~3}hVeFoke$4Nx^yT8U8^Ty=5+UVmuqNb z?P}@mYLzH0b7AH;giSrK-c2et)cjZ}WB6Dd5j`$n*(R@r+7a^THt8`qB+yWcALu*D zJ|dWWWi>WS%uUznY22+cj9)+JjCt{C1C*D?1wsScrG3?uTh%do7iS>B!^4#ACr$Pa zwPQ7OJFh`fd@v@{ujF zpyI%U(jk*&kqFPn70q-iw9hiAcRxE*r%vCGk)MxXhh8YQ;@jb_v`Pf@@;ckf(U1FM zRb{HCf&o(ybq733F*k-6|AeI*%`+`|w(2=lLTB?;03b`3Xo?AD|yyb|&=x1*+)>gt&x8u(az40wFDZpDx5S>I7^#fU}Dg_Qeb! z`R)Nw7pE6X&v959lUa$4EKxRSce_xrhwOKI_hUQ%I}i44{lqWtO2ISwFi!5hum%aZ z5~50UeiU(F!D9}WHf%j_?%|GZ@D3G^7+)7jVjD^wctf`i+7EkNl?{Xyy za`gG&WS7R?L0~VY05u&QE7tJnLB!354;9D+Kn`6C-N*=VVm>_G7 zcXbqE^o~b4$zATsg*++2t56HYG5$Lg4wS_S3C1~X%a0UyNOZ=;u6WOs9WYi0fFgVyPwL}M z01C93K+3`bYe9JJ9c%fKPMoZ=5mefo`E|Gbd-?3`SfdLw=Z9(Hsu%RCa;J#u*`DtN zalVr99?jIz0$CB;@R|4y>fI_#Es#M8QvE_ zxTAH)M>ZO`rYV*K1WZccz)Lo3_?1KH8aLZkxta$}JbRG#!q1m9Y0@u*%VV-5)u z!`1B7YyG}a+ndXOh6neqaHV~^SJV52%bmX4pdY}c;_!@{_^S2Ra=E7oGI4NlpwCA0 zH%VY-;o20kpby%~5>>1%2AOc;UEtU+ei?@mlXtcf^Q0O+ye|0yQe`^<*_L4dSmIWT z`%>XF!Cz>Tns2=-ouK_=cO`8@7MbzIIVV6I!H$QTZD`BQM6@qS^?zRhgdf8_QC?drp@9#~+v$NqU?#@f@gTtSMNoEGKI3--c`M2r24jsJLq*`= z0{KjrGnbV3u589S@)`C=xuFS@}sc$AN-M z)Eq}5>@X&!A}5sNG9SFj>583>(go$d`AU_ahC5ohm86Wvjl=^)c}dtgSqVtliqH`D zNkPpdcG3yWw|HXpUIMmwYB;5E&#K1G4$Rtg8KgD9CSg>t0@A6!c&gU+Z33bvL37bo z`D|>YqhdO2xWC^*&RxKI3gGmc^=!X^H&v1$uXaXkhASOUHbBZuen&C>kn1@4|TXBesnzCOYHfkYJFR3W~Ff!I@pKiS+#= zJxiMc^YS2rb3OizwenWiVI}7#IG=b_r3SQ%Dy#=h<0vNOa17`=Op;#QEOyFnqX7t^ z@66D%stw>fpBC>FF(fqY-OAZNI5p}6x$<`G2P0fLU}kj=m-_6In>q3fDPjdyPi6clEGCsH0qwO_jhlW%SW}-}ZAB9bhicvqqkPW$9 z)Q_(@Mu1Ep^vjs~KR#1%-dl)0StFJgyc>2v7ZyBL8zDJTlT+^K3 zgn5PypD3~_*E-J*oPo+`9Y@cizj7V^Mb$l2I!5No&Yi@^Z0nWpx=Od)fwfGafYbxt9oZ!v>>I zI)O&v_EL?ph44ssE@$Xn4<|se9V|+9!^>IAzA@Nh;4G#vSnM};bE}f`r1guyQvYCc zus3uHEDMS0MLzrN$pVV;dBo#k=3cBZW2z0(emF$3zymes+;Kd}HP_5dQ-9srGywML z?#8u1t#`YPO$#654`R=>x-0FgbRlk0+Z=d;I3^$Gi;j0V_)vJ7E7%oEuo0_)Il%}* z19*VoktLaI+_bOoX(zkibb6!+{8#WHlAomAwtkux{E8g-3w9 z`Fxpoc0X2#ohPd6b4{j3^fLJUy7%y{%Udun%x$$|;J8d69SsUhqwCah{%mYwn$zUk zt8WyIB6^XRWEkfct>G~F@Jp`;Ebt+`U*k`r=qpQKNR5CtIrmn6vQy?p>&;182gz}c zf=VfXNt&6uw(z`~GJ5EA2(?y7$+=)6rK1%T^VRQ^4a$;-#)Z-*afnICkII~zW2M$* zlPsMwVY&_dhdH-d$aTnR=JvubmIbcPgFU`WcoVP?u&<^3H%#RYmhrZ7{= z(b&84+%XW|@?b4Ypzu40?XD)!F})(XcBXGORLyZdHWKTaQAP2M#^T!cHU*U!?Ne$q zq3!_>5qHIfbtp<9;cCwN_K$o7mn6TS*s%SYrw**!qr2AAHfOY|0jSq+=Ghl+0VRDn z{RtFT?0G&kkTWntz&6R00)h#~n2n8i^)!YyzKCFeLws3U4;VQ2z zM->hrF*HL&CROyCNg2K|by=D*$mY&?Y8prKs7{}y4|I82WSoN0j^7cH`k6k_Y| z6lNd7NdUm`*@yK7sA5(zo|yP#2o!X*X>Qpud zJV!_$*l697d6*n#?lnc1;MxSuLz}^B9gx5#1}HxllbsMHF+ULA%yO10=iPh21{x44 zeX#IRORol=IcGR1`*@<1EEf+Ip+@mK>vB$KDmxkNqizA_>;?!6{<$x&3=?DkC$#pQ zh8w)FIc1w0Syu5aMA=FDnGG^;!a38U$U$`~9#W+)qqV+KVK00$=&>p`HQuw_5Pg#{ ztbi{u_fe15MkX?=jv3>ARI2PUF|_Y3`TTofzI)Mx?zhCk^tfC0fa$KWU8#w>T-nNi zI4&G`P^NplE)Nk2aEwiy(_|B|O83!gYS!45lw>z4!G-9cBx`=O8!6J#+vtf(y)cL( zT|f`Ki=+F^R;Jk2XU;jcXimQzoC%6f-DNXD@c}4_1@^>G0u~Rx6t3DXz%*Csd(Bbf zxz@jHg?^i??DZ6lH~DSqt9^Z+Dv-e>(^?+ptlwv;l#ET+h_h_9tfkz5-h2s8f3C{| zsVdupI%g+%mAVR2JjG*+pO)-XGP-je!4Rb#%Z>@b6A&G%#oqZ~f6?h7dpZ?Ap@rT) zxW>Sk{>_$Ku+XEfpa`LSy{7=boGu zMTctaVgv`3S=M2L3C9-`g@uVuLigRqVwUj)t+q4aLezMFhD;Il?t`1R%p&(Om)5=r zE=E0#iFo;#n9#w2;F#dn8}c8n6$KDoXUVbk5zKp_#<*jgyii}*#U{k@;rU1ycI1^e zx^E=nRnaENox;I^306LsZgh+NFx4G7J3}D-qsle_6uJk1xLM0#n3g_i19eV3Mec?> zb6;&_H>K_pJnzB^e-cf&MMyH_R(1Qnk5Pzc|{Y%TRKbMG7=k{RbP@H_Ct!JPqI~Rh2lf=C@Q+F>s9m?V4-p!))6edoW z-K9K;dZ5~`jiuBr(5KK7D^=~+^8rAhZBfkY-Q7lt#(W1yJ#r-91bNRzY^4a?L>xFB zQLx3vDi$CZ-@y9Fq7!NIHVu|m9?Uh7(Qzcr%Uzoh`%;bEP5@&z)9!K=DMl+3AtR(; zGTBRZm*DzWKyMlaiO-iGW3%sp_^7|ey1(3xe(kh>0mX<9`w*KwjO} zVGjlkcX`4w5vTICKZ#zVu4sMI&i|tqh6n$n7e+y;2NR5pjQOBE)mT#gzC0P^Ysu_I zT*;e8Q78d|PECLbnqylc%rj&`6|w8Yyxp^vl5@dpCowIg50qHf;C3d@yKGYgb4*&; z5?gP~H!$yb2>Y|hPrTjo^txO&NcS$rEAPofFt~Hn3zDz{VRp@QbbcDW;yrWT4PrZ# z^#XBxz!(n^MPfRCm2=&FF+2W@xM^U0hp%{laeRo6mb9P29tSNb*58m3qmP5W3J(?n z4!FjZtXPKB9PDmw&rX*0du^|08O5{LiYsc2Oe#cO$-E;6rf(FpmBsk0T6bNXS5l3w zy(56a9}@g}loy!ZIsvyfH;MJ(p_A!^##SoPHFzHp(JgZAS7`d;Q?%l|p|aoOfM1I# zw^+6mnqS(RuIF5&{$OIcBJgwwf=GjQ82=|oK!Vf7hS7Y-lSazLh964c-$m!gx@%Bf zbjL@ooQ_My5igU9uQ8cEt)wN1-u}$px#Dca$5+p>%GnSw4GbV){712ySSIVJuZ9<; z30TM0I}Ke^UpIdei4+W4-Fj71OAZfM-ekXZCgfmB@_?i_@g2Fg!#Sw6W_{37A}0@Z zKsEB$8*XFUUVKdo2}Fuk-n@G~(c_iqC2CRHlXj?ht28k5>)K+If8WQpfwZYNM{Z_v zYtI+g2X~(+6Rk1k4E`kI^^G^{{tCI^vsjipm#kv;cD%0275mLsk-|avm(j>39R;o3h|E}q`Q|J~7Os=dVKveNv*CK`$7D~imm^0=zkfuT z|G!3A>823oqv+P_D9700PnA7137pf4*RL4!1Xy{i#p zipK?_%qx~oiqvstwF_+Wv5~Qn-9$vstPbm6)C?6cu!Cq5x@=6BQC@Z0tsie%MNR zoNBorwTyZCyQ(<5xktdl^vRH}weX={@(sjMUji(cv*xU_(ynQ870*;8HR=DMyf9^l zF^dwbGu)UV1I&)LEt%^}+*y#ATNb+2)GU^=24E9qNA<_hdpTGQ#ZN?j&YklvehN~; z+132Xq-1}@8a0l0PqezFSD%7S`SkG2^Ff`v`Zd6hJ!6fy7bCA&De*^CkPGFMUR#-C zcs7kT$ou#wk-}o_qUeWpCZhsG7M^LL-M z-kNg3PUpd1tQ=;F>I3L2_BYPCriLEwfxgTsh;D<$Bl)hGt;DDV2AoM^N;Uvs=gKqT z(h73(B>3g_NS1g@`l!dvb|otl)L_7fQvlbJ9%x&tKXQn`#{WXE2eY_7b8*{-70cr; z(>=eIGFG04&VPcrz;d8+2pRjZ)IRtIj8J|1J+@bBQ!k?qD!%rx^mP}m;@wfmh)*r> zti71QQd&OFTt3`hD0;h9Ix34fMb8Lf#F6MzM?HM9p-vH$gmGL|!?IhFQ(`$l;uI8j zp$8dTG*ng)i)R(zWi!j}Mndw!tVC=!Db~LzM7kr+xUVHwV6}Oxp491bOjY8*&Ka+C zy=g;BQ{iDYRl&SppRqTl%p$M4ypxI^U4EuS68bOMVWi=lAvRK)zWChgPcN;pvvthw zI>6Lrn)!my0z0Mj=2JVOTnOWAg@ zE_m`pCr0l{ukgib?$p$~$T6G7_jjO$XtwQb#VLDx0&gfSE&erG-JQ1uA#tUTgr?WO zsrrcWO!aVT;UAk8Fi}`&Roi=I!0|JG@@fc=)a__Z$8j53GFzXe_zUXsKRFtVN-=hv zf8KEHA|k@;L{oN>v|ifdD2de1L)&OyiEz4LlG3qpJB#TZ=p8)^sN$M(*V{u%jaM(V zoc~NYS1+1_9eJMf?bw=;0vu$5&xolS~G(q_#{(Z&mQ;sVm1J)CXHzgfydgAI*Ji!dX94kPTB$T;MR4we}#~Gq$ab z>zXfOtija+Lm-junZ{)RGnP&0&C<1oaO{j3`*6V>`3vyA@53%T7YnY80xpC_!-F2; z1I*jF{n|71hd+&{|6NPy|GY#Okvzy3N>`eG!ePYutdXf(*;=`1T)Q2ha6`}*D8?~a zLm!!7Eh?Yz;qgN9$kUiigweuE)>>o3p9Si5$aov z#fikZde&;jYeq@q{j3)y#bJ=0&I>^FfC`FA_a~7wi4sEliU4UTEWQ4=Kh3B}M*Ggk zx3di=XD%|DKobVpo65W5+JWP$JT-AdrW!+3f`G;^g?G1T5RGk?F9-o zxcjn|1G(ds{78Ybj(}rhkv(|LoN;ARp`>YE{7B!!87^h76S}01rZ^FWO$?ARd|jfR zmS#;2O!GZH$&m(`&F&B;ZwTcg9SpbAN#548FkBizz@atiheeE~ zkhM&GfJ5yN~gF(5`sgK06~i- zI4$lD#ogT<=4Q`1=bhQ-o_WvS@40t>?tT6sD`fGop0!qfzvo%&E85lqqZV+dIJ&0< zqlT)vU6Xso@q9aa%R)_G6g7Z%^D$lSJ-cG+Q6mtJoJ0+S5Qf1txC)`i=b8X(ce*@# zmAL3C`;$7ZpW+3Uj@;@yUVN5#bZu(eU#pxKCZ`Mydtj>;XOE<~R8)TRnWamF55>)y zGg}!iu@#!zsfhAwVbJad5bq`2+k-A`&`+Qbwl$n#Hs^cWw@Q<-Gq20(G`H{l(!(cU>_o^I6|0)1$Evq_lZZLHM2X+)F5j)| zI)eA|b3SFF&=^1|p@Yyt0*F4wA;j(hMf%;EFoObL?l@V(+urTP74is!i7|{Y&)Upn zq1lp4xLH34R<4iLV%NdbXGC-X2`!3Hn#$@CP3pH2f2w$)Rdo=Ty2JTwN;h7f&L z43Qt++tA2JFPXY`sqr!30}j3}u@V<62s|84exlC;R0F8=^K5`Q5i4PmN-^eyBJy2n z(ZKGpH|3g^UQ#>bKXg1Sm1kda)Y*v}l0t{XqW}fjGl+tW;Y!e9MNsUc=XE06YwP#V z$1SxUySx49>wmmo)L%f8@G^LPt*5$p#ZFZuBNw@!g7uZ$*)B~bICzp=3c|ok`T?dyR-RIRvPIZZlq9DvPbq!0xa&*%-D}$LEq@y&2YFtK4mKysm+xn( z@N7sPh2@6X@)sM5qHOhQwX0bAKx*k*YDpQu=)_Ywf)^mY(?$$3`BIVinKqLK(zg|E z=I2!g;%-ugHYwoTW6k=Ho5%mj>;FWf%IPRlnzD~Qyp%cL!Ub1XXsFP&x+iGCDUZk; zjWCk^(j~jXEin`+P+%^2%zmD0Z1lapz92+m>^OGi{Se1Wn>8old2u1kgjx|ugw6BW zk^plV#|Dke@7yV&9;9dXwPXFdR$X$|RcDjTjPS0nLzJC;bAm~nG3GZ*KKleyS}f}6 zY{YO4cW=lD(Qi0Uqgsc%NKwrYjth3fEx3&(pa#?<3@LBeiEw|fs63Z(7T?~xk+4eoLcst|e z@em;Vhk#XpRq(~I74OV)r-SoqqT0nf3px4upNC5>yx&J#+*an56{T0AoI~+p(89ic zfjI}ia3#xU5r_{1$7lfK^%zuZP%uC+^+T0zpO2E_N2RAv*af#Cukz#A?q5T?`LY?f zpd0EWazThqH40ZeF;v`Qlu9ut@u@^(I&>X3CQm!n(R2SxV`Qyk8Jt~Dv3H#5nygilu2i=V=q^&5=5?d9U+}JdUi>@d0vhbrj9nZSR05|RPUzm z<}GEp{OPS?U_wi4T8HG%{md<2Fb)q#LrVA#>lZ_zTn_wr?X~P$mZ0h4oYHCOBMK9B zvCtxm%`$F1?4NJ1YC{XGPt;$=lhIudNg)dVl28ZPaNyX zDZjDJpxRBlr5zekJakDCGMmmuJoJLJFo3<-(SJnr{^%|^paQYD7NEw zQH|#1xK=Y;xcKSF?`>`rkSTX)BSD>?Xr9JYb46h>P~oe66QaV68^g!5%_@@yUj*z0 zu(w>KMy5BBv_s+yW=r&XIYL+~SMiCAyc@Wc0hFRQDSgSQOxH`+j6+12x7v$O9luY_ z8?VEVrXmorEN+UH7$+!{XxR~N3=GZ5;%i_&N!pt>PHQbq;bT)JW*NzT{#2zjDlHkm zo(azrCCnMS$Wn@~EpdL@znq{XHAng4ArM0T!@A+U3_ zf(!lz26)|U5olkQ-R$T+!$!Pmp%n2{c$>Ls7o5bVv>u8EaCC--VeO>fD#U)?01`fT zAZgt=D6rTly9n-eWmOTXDw=VZF4)xXuPz>44ws1Ml(Vo9yuwd#s&Ej;*xU1^-6aE`?D93Q;JQEVrLZx3C3yPgOW2g!%ARazHFhPWE3>aR;!|%- zPVIxKWksV=L-|oqJGr$ksMd>+62?|FuBY4>9Q8RV(Z$40M%2P=mbS8KxnjD1XU+)8bA zW9P(X2yKOemUra_Y^1hvHh*M6@Y&N>ORiA7 zp#Oyr(tIXmYUu`l#6xZFQ|E`|&vTkJd>;G}*T^2yzi3}6J2gi6k`v&yC z;jo3VF#v5lq~xl^WJp2woA8MufE}rhTy14SJl`qbcyRJ?GK3!~igln*UiiKL|GX0Y z&ua7ByWjriDaWekDCX5zJd&8t)1Id(@c%(V(>kYho6iJq5=+W|^<+r~JH$0FIC7dF3d=4zR?e0@_u z#!yFZuahvLCv>El6=5*8vT{h)ZY;Fi19>uYHj$>?@y(oXOFPmDSKL}sKdMoLV%UTS z;yp=^RL~dDh-f(B=+t&rbpiEH&ACE~X)e4O42}IP!H*^S=*M)$xpd#jR>*jABfCLi zm-xlGBaEZjdgBWEJ=RZkC||@ADK+%54^t|$$*zRz2ncG|a2%Cks=mhHh7r>-65%S! zupCbE6RFGCGF^-A&l-0wTCefzyz|2IGWr7H9|1QNPo@76|R%r2?9CPNRA=GJ;C zP6Hyd221R$(te>P3tA24xVtPW&G%65E{^i&$?WQJP2 zw}Oe0AFb&wglO zWh&0yh{#z_6)gDjCX%*W*R`hnquoX4O0Q-awZ35UslMO2uPsLn8@GXlo8-;SN!4#S zRdVNxg5RqkkbFJ)Lv>F6B=(@FiSEK?4?a+JbcK!bcTbX0K!T#37wONnTEoizp_<7y zHmU9foHV2^FW49PlsY1taq-cg53q}C=^jOTw#etQ1w9=HmT5!-qzqEcHrSc8jiGhJtn*17QxCwEfDc#B@$^J}4OYwMGxObxfG0H2WtNh;;jsbc#Tz_L zPt|kfE@Pw|fpCM0`ZkZ)`l^vh#lYM~ZL9D=cYTXxM#GR>=ntHbgtGe8i4dyh+u;m| z@yuV=b3PMHt$VTTXn_Z#-2CR!nzevJ`;+-5br{!H3 z_k0`weUjeM8*fow;j$;uTE4jkQ33*Y_nk#^5?)}{a0=cvAZGrT63esyvgzZa-yI1&^{P zV*z~Atq{2!ZqDNB>StHVPl1`E6ekBlQCA)`mj_c=o%)7TR?cp)UD2R9h!MpkkG?aC zn;0&n9Mt-GFCCgq9D)igW+T-?l3U)0qqdc;Y(f7lWk=>)MX2s61EQ>;$i}=CzJq&; zX0<~~!6$dn1}lhV5YH@g>vV(^G_*@jj=NyTsRb__z^LCF%pPCq=IVBw6gyxiv*%La z&XHq3^kp7P%$ML}McT>0fr%m%^j&3MtP+3L^^ghjd^UM~s!|6995UytkAir-k*0o6jpN+bE9m5d}dy z=uu+;2Ri+-g9N)Tz=_pCi)?2~pzS;s6}pT@w#k^cc_id^5G@Mzc_j>ed>hf=tv#nc zi*IipHQ+(oA2&5YV|Qyc-UDxvXozRGQZt58CI#igI;FvttUt)I`H=Qd{Ep{e!dNFC z?rGV!C+m&R>Cr^BnQ~9CSC++iL{Dld+EXg@sS{G_3XFdcs^>(PSVk+AvLhvWb>#^Slzh_-x-RoM$Rei#)lq`rS)u+z-Qw z<&>JE+@f_gYIj`3YqaBpgEfzy^oEX3vV`_ATIeILKr`XVbN%D#jh5^@acj#14lq40 zax$!%xxKke@nB{8CNEc7y=W{F4j{K?C-o4gt|JJE=cPGO{8+wJ19C4P=W3&;3f8A1 zxW#)LkqIeu<*0pD|H!D3G+j^J;=Nqv+ZcUV=2HWYm-Cgolk!0qxg}6FvUaql1^WDE zWv614Kt(M=WAzl2Uu$Axhe$~B%EQMji>1TGdcyYqmNG#M^S94B?N@HHb(s4PN63pE z_P|lpT5OdF;+Lh*H=$SWw&rO{@F%xbIA=ybrJ4x`ONHyoH=jyqI20(>2T8~vy3lq? zcM(KHhTA;oBeG5pGd?>Xbh6OCV`A<5DVt*E?D1L(!>Dhg-}>YrLJi!|5em-DYYkvt z7Lacc=U%xrHkkkOH*WXZddm|%jkrx3KejqiQ{w{%zzj7c`4MSfy)y20; zXGhOEM9#`TI%mrr_dI&O(a@#Svh@0<#(C1QY3za7P;pT}@c6(Or%DFR^k}PQ3hS0s z^{lHi7efRoqg+mT%%d(YW=#XotelKt^FSFuwj(!dk%)S(-YR{0wkwaIIEzIe={C<9&MWA<9y&WmpAtM?PIJ z=o%?8)l_Z%U!SamdSa4>ul}<;C#@w7($0bjWCqi9wyV!08m^A4R&@dQf9B;`+@znu zaMVTnkNzpkm@W&~G@(*tohHsxLBE>Obe1O?)bc783&B9c{%0|tI(q}xrPwNzUm?*J z`#_iLX&-%7)f(|GxJ5;{Gp!q<_xg*WX#I8pCz_egF?3W$&ebkJpKtzU7kT*fjEYj{ z+NAPFak0rawo&GCpOd(A<0&bUC|JVI3FlDE3p~6tadC(hpSaL1u#y>ya%3DZ)7s%o$FCtN1vL0%3RJmWHYtI+WurxZ@z06!dVcrrj_ zq_JBdJ$;MUiiHCVhBV0+TogBC^O50x?bu_a?bVr;(UfPT+W_0l<_)wA4v&M&_C%L6 z{9=Z|qz>vU{E@1Gmma%fX+6#dtjvp`&?}&9SzH_i1%*8$@+gEH*T@~Zg{ipYZC<&$ z!?&S`@TD%P)l1Dmj;1>F%SAqVe6I$LYD~-Z;tUvBk%~+@IpZO%8`U34qm>TNf*fvzCt8s%%c?e!{^I_=|_& zzXB2A{J%wS!ufmfQL}9~*;?=x1LVsn($swuq^_To)Z$@EPZP@j1H++vlZm#hv=o7r z+9S^?HPo=SOa`@{+P22>l78EFgoa{l6I9FQk! z^1c9)Wv)7!CUv%qh+EEtv+@etlXUP{SEa}`C$!2R=fD=(*e~2<64gEk^Bg3HbabKW zCOe%BENc#{6M*)v7ec)kieIogd^9@%EoKDyQFxk<){Lk$goI^+N1@p5dSDbaqXEfia2VjGuRkM2&6}uS+*LloUjUkV3Bw0HzB)b;(>%|$y z|B)7uBle9COyq(pyLKk(o5m_E?gFas2j9`CF_F9{P^xFjJUp_oKXazmq1f}a2Mp_{ zNf7W#5N&WqeDRTF{^DUoExCBEqH60$@ciPVM%;lvtYzNQ`|Z)}_TBxcr&h4( zGB3$O``KA$rN{V@B3XQ_@2HYIAxaCYB&$2C)#>+Vs;M<{(O14=j|^l7eG-0=4ABGz zk==*A#?ANjO-^Y@4Iyp!$)E~zMXaj^L=FVjJ~iEVI^eu}_iSx({{(4!tX=5uUblhX z6`b(Eagk8{W$%Yao#_DDzhy5qef)}=?%*bmVc|C%=8(pNlNjB9qzS)|Xb>gY2y=z$ z(Qi1~eJNK23j|dEPt2C5JszbO1bm!Xs`hOwcg1xcu4!+m1>S6h4kCZC2QOCf2Ea8E zDiBMa&z%>XRFbDR4-P1t$ffoSasH7(c`e?9x!_F+X&R0%?b9p1o!ZZuuADcSxz~Fs ze!tFeZZ|?=@;994wOB#N4M+c$qtuvyn{?XimSJ&=f1nBXyzEbZ!+AtvrLUCU7twR8 zFW|5t`bo&)ADG3DD~`M$yVo^LllfKL(YdaiVFs~760#~x_xMsw{5&M*HRoK@g3us3 zOuUX9c7@)Z9d`ZZIMGtT@HYNlO+xT!KY^NxQNMoJf_TrbZ6dY~c`e_-t%i?lT<`w_ zqw=Z#oNIoe-yZ8U0Mc&ax51p-Hb&Tw_=Pw==3O}<*!A#1b6i{ANNjfPI%Iywc2Kvo z#PcIhpZ(_wr-}bS8y>FK{kVClmI>kU5qSOj)NZor%O1{R(?2kgX$QJCXr}hg?R3uu zF8oGdQ}faRcXaR-U%Hip^EuksdW`pPIG_I2vE{q)>&@hCrykdHW}>29|D&^+u9=c~ zOl8tJm*`+4++-m5+M8-G*hfJzh3ygdPnKe8{eM zYZ7xVe_3taE#Ii>vcW2rSw1?B=Z8>jNhvCy3shMvZ^&ZtH7|62eck2Ot;J>N6{cpj z<`U0NWg&XzQb3K8amQWjYmH+vSToXv5?PoBk6k@=*&w}lJnl5HZJSTgh+I*u>9R7P zmMOCTZ1_=4f?D{gg-BRyR~V6^l~;vPr>;me!&^8|%@gE}m*NmOc2fd3nK#juE85JI zYd2T!&)<$u;+wAI-eImHy{6?u0u}Lvvh>3zt@qXCz%|cxNXH?m) zTcTUEtkWuIjY^-%x&DV5a}?(1!_o%vX{`02&F-69rHag6Z4R$cXg>= z?eZHc@3BBOji{o*B}xYEJyv!GP?%^E1qGeLt?5)uUQ%z;;Mde+nodS-NB3XAOS{srX%OqWw|R&PwS`9azOVkEFPY24ZmJ#1bA)c`k< zO_NQtW5r#46!>bFAETQQYXWU{Ac#mr3=j)hgYl%eA)TpS$=T4;J9f#|`ij!2s)h|C zNp?9URA7P@>nvl>^oe?%>8sr-%*@jcqEKx;iEARhr9~o;2HhwIT)OxR+PR%-p$IGPS5b}1f|w%M3&+% zE-FekyT;WcfLrh$Yk>&n_iSDj^NcEWTI+Nwd1M&Znc3#dHoyMDAQKDyAt%z5tsz@B zqBo45GC_IU##$Czz_{~lIGBE<2|8IDltLgC_kxwpgZiL3KiBZc|Af{dwlOAzcETVp zv?CcrH9YjhLy*HbI5N+Scyhn^7 z+94XY&eypnCRGCDq@ty0hZHG6gSjqVAm37NG!SI~sAH_eZgQ0KOsr1cMVd|hD4TZlI0uGGvjw&xc|5pO?TSwwST(5d_T!fay#{S zetW+C>CD#6*t(?ast|Sja)CF?-Qk{v*A@zli7-9TukOypbj$zR?N~)oe72jUNG}0| zN{-s-Cg9=9H_jm_0({dxYTfQ;CnSj{5vo>sJqX|<+(W#S2l6y4U5{hcXL_@-(oJ5Y zrcge)<^g)7soyxK-606WoazoKdW`!ZePR`1ZR;%BZ`CMfT(-D(uC zl38PFMobx*N)r%GyWw$m0o7b7D7@s!5oIq6;;Tir`8gHMHXG+hw2wweG6S0PSI)h8 z(XPAJz->oFeH-~Lx!1Ucy&^Yi-8@GWcM1UG*3pq@2MSV*w*5*tsZPxZw6wN8KAjrnTH$f)*9>eJrfrrvy>V>4s@p&FiTA$Zas7DS5 z$gO<_P-5t>OwNVL417X9K1fE-x0KIJc4p&t5RXjWRih`DATD)&L(Pj-^%7~!>;1Z>VFOn0z zgQRqNDTu=ZDRpX?O>?-54Y1NpTY_E1bx9sf8I{*ASN(FWi&)4O^HAfAuNX6CXyz_< zbwzI#_SMn$>kM8=|6I?Tw6G3~{>x6nrfi<=f>=yS_!X>Hmxqzqau_`CB~zf~DbLbA z&0m~sv|=V3+AbQl;_SAm>!WA2%a_1W{>1&L@J-jDJxTL&qgvF=XUzbM?-(y8#IU{; zPj?LoWy-=^E#QtuN46QNi$Tl8Y3mEiQrv`K&_J7E@|AkIo_PzriUh^VMU1`IdbR8b zH6C-dF|(QTVG2hE;St;X*boj zE9d!OsmtLNWx2}Aa8{@-hY5xqt!rW6fsX;^U8wa4w!-*|1_Q8WmTyUGfqKRAk8&!l z^nU2wNxp-MCh(2vl4>R^cAr`Pk~mp;;{j_8%DD+PzKOd~=!~qD<0;=;2a<)S_7BVE z(jsAw4mpL+dWAZ|*%9)kOqGgT`GEHShWH zIkA2(3vR27*Apu~NffLWa66mBPo<%mhGGIq;we{meB`>^{j~_P92aaVorSwwqIB1) zGK~gAWemV>#BNTp>hE;e=C-CdSgh$Kbk~8b;x`ZES9y;JT{B`oa`y&f*pM;)?;O}j z8hOF?mARvpNQ-nXQr9>-g4L$L$Vdeqf;IzZ``5aP^3WM>rgTBu4rkXOpf$KADS^p{ zSjKWe(SQZ$N+dx4s=T>!=#7)!1O?SO$3&}nwpgMUf7l!I$z-A&LNO?il@(MCWCYGb zA|N3?c!^0WBcDOjXQ$IAuUZ$5WW@yhp2_5itu=l&B1jSY!CAYPvx_PQ;5@QT*`m9{ zs*0bd_gpUaoj(5!#~*q<0KPda^G-={IM7-%@j5!zX*4^9wQ~hteM>qhKKS!y>0#?w zB=*KyXpl_Mj%PR{wNR^*rjcOOFI)_?{G~mq40K6zqR%^|* zkw%x%vGIV>A1{UbmHGugFQ8&buk|f*`zkZEPc~j;xA4Tu979C9O5twLzQpzX+#4l7 z4CEo~I9Y3RPYk9i(DNZ?RiR1h+4WIK^yw}&pn5_?ZLL(94Yezu2_fpnxB;aqrx4Z* zD)YLZ7B`o`D#9rLbAOA^#f2H`w{!3nx>s+)6RQ=g;vEkk+1f19BHrtF7j?e7POUq9 z*BTn6%Q6aKSrM8?qfiI| zC!5iAPGo4WDH1diZEri`cfFr|ipyw{X=lWo$JM=Xc9NuUtTCfNx}QUu#6+( zR}?YP)Uxd2rU@7TiF;M9Mwrv%8w?Cl_0R!yii=>xc4xAZwT0v43cZ}z%g&~v)tBSL zex5YRVpMvYO&Ob~xule$L&$>CsQbCQv57c=fxrXNP#33R(+o~Zd;1bLRiePVa_7c) zHKEc9+&5gBH&5K``H`v}m69|mjuTpOoqpcT8S-&3~h9*ZK#;*irm1XQJjszEh@ zD;MybJsEBa&4}9QgptEKoejPh@+WFjN?>7pva|_7?9z2w2Rd=qCr?1}d1_S~c$LU= ze6nb2n=jCxLzv zwl-YuHJX8&93=y*1nnS3yl<*Bd3ThyjSGs=0S;JbKz4m=TRpsX6HBY62s~1lJ=a8> zyD?h8ra$iX7nG@?s=PnCmNXFADzIv!eAbpgo@tue_zz(7aF%_K_N+w-1+)(9+|}ZC zUaq)A-BnQBalc>)TdAszTA~S>yw=Xk6{Y=hN0~qE5t|7YMJCkZSNraSsi4>3Bal@j zBHINDB2uL7ofRvv6cbHVmABs_H=%lJAef_8Tf^BJWuNVb$;nAw;Nw#pg>cUCp#$xq zOuaA#%#SG95?Iol{D>HMM(}Z!b8WNFr0uS*Sn#y9J!c}=C>LIuMh_wdh{@?YF*_+W zSJ3yW+`tT+@Sv+#pJ(TIePGfys{)H$G?&WN-tN=Q#Kqd|;-$tK!-&~MM&E4F`xv+D zGpou0hN$#|Rm()fG>+gQw}%%;p!C;TK+8ovHA+bjP+YI@lepBiIypNct4GSUs|d*njlW5Y8RS;DyPeGc zhLaMxmRQtr#gt`T9AQY%S)Ha?amyjB!}S(+Ewotff2E-QU|wXiud)U(42E~9C2Z}{ zWMZvEYZC63Vns4w%Jm%BH`ny`s}A|iAF&>X)0#Lq8=w#W-9_P-3tsH2M0d*UtaQm z`Xz4r7xtB4h!3Hi)o8VMbGovier$h?`rq0yE2MnxFSj zU=5dMZC#UxA-|Y58m={(xMa**)wW9fQIu{iGh#EctBZ72{^%#EtT-?5h1;0x*!WG& zz<#BnDcv7MYDLl|Bo;pY|AmU#9ZX7AYH3M4(suGDcy2!obpiO9fLb_`4r?k$k(Ais zTQy*GSzSvWU%7ZeD$t#Vj<^H!^S2RxY<+oG@fqw@6r8gaS#V~fr)Ma~{~jqyGnR7> z?1`;Jsy~S_TY&}&)_BZhLeTAWfTcs?zIV3B+=S8-o^n^K3(wlGk>mo7saSd&Y^0_~ zKy*s%3e*~5KD#B>x%bA)yi)XD-aBi3w;~2uR4Z(g!DXFpx>@FuaL3%71?PT4^Wt() zHszbq@YIi-%T7eaw#?>;jU2ev*%T}LZq>KHZKU8LbE&NJU`VitgAq!rJWVsj4xG)1 z9Lqm9NYvj!%=6BIY%>Yc*XKC;KuD~S!NR7Q^?}>(PQf!|61jM)f=YlaHGet9yc3%~ zan@Y0Q!gSwAX~OyQk-W|VcDt|E59}l<15CzD27jmVGT&}=+%`XBSTvQ$cO#3f2ATA ziEuS_I;bc69yV0GIMLJ{>8SQg1cL|J5)=`SUIKjE?GMWm&<1T{&F30v&fRB&#d>8YopiqcfWD6v4o=GMXO1^_r#j z)95nq#gz60;@t<`>%rs5Y*v`zeYW0L82nH;q9oP3JqZjc4_>RIMj(@CoLYRUA_B){ zlnVpg-jz*>%vgluKa?ReY5CMlVI8ax_Jsa5Q>*^To`nx~5#yuU{{KR7D*tB$C-DZ< z?ld1hYX;pq;9^jO4cb^}9g<6B37@d$=dF68vGzK~c+aDZHinC%@=@wK4rO*DgN=MC z6H3G-NNop!)Q|9Vq#w`$Heyxm4w+)DTJxtzkD`Xlip9Pfh~!5X@S~N6h{CFJ&J3*d z_Y&wBX4yQD__V9@Mb#R$ZBC$PZ1Ji7lqE7kN|XuBayI(WEa&>socgE^l5Bof8(#Iu z-rnAhIvpK-pdn>e`u!JQTC6!bqFc;^ryzhb04vvL`qw|7g*d^=!5kU*loqE=L-sO4 zJ6{T=BTQgHB>RwZ-_3?nLqvY=u%7-095V2G9GnM#Qa5}Ij#N5Vs3;46? z*FCM5vpU(8m^M)JXYS7Gjx}yKqwlmGui8ml(N9mPim8eTFY%kX%kPnTbC;@U=AjCy zgv2xt-iMn0T(UG$F?vNOJ$m(QP0~*XuKu>u+8lO}SDuh;G)>#F2#RQqC)@)8Pq0pA zCvnlAx(yZtu>x4-hP;&_k7UjXWTV7RShm;eKaz(j>@SP?r!L_FwWm>4?2WXgJv1_5 z$J!#VVijEL*$dExUID-1#H%xYt#~~(N${8$>f~v?wkFIO#eU6C{`|fo(S;JJ!de3? z)r93lY@OscoLWI;Yj=ZKr#4W>9vQ%_|$DO9U*7Xl;cugiU4wpbOV24oAd-R$q0-eil}F-EhD< zo~Y}Xe?F-nM;F4Ld?vPvn7E@c)0rCK(IeZ5Zf4MpM~k#3?2skoaFUUB?xvH}r*+}k z4OeCWf9_&q%jl{9(aYs>y^Dps{ZWkJ&Wnyv)<{U<9G?-U$4LB*{{$s<7q>B#wcF95 z@FA3ykP6W@C3`L`;3RGo9If-3Uc^W#gwa)jUfKa`$2bdeL{Azjsh6*!jumiq2 zh{8n>WZKwhJB8iIQ*b3AJVgozqY1e>tb0si$EWzw}7H4C?py!{Yk> zC=ycVn=zlDdioL^SCV_Kejkyld*PREDRggLsRS7$?-jUFkYDY7_!|a2rn`{enC~u1 zENfwmeZzAZq|~DmxB6Ba$Yf@3oDOp{o?R4&gLFm7wROw#0OQGqCGB2Z?+yyJ@?P%x zG6L@2z;kXQN_rHEbb6F^b}t%kRi3pBMJ;VgkCzic_0&J!UwH`t7_Y%v7T<=Vq%)+Y zRU8R5dq%R4ig&CAPAk(7^(KG^v4i-)f0qpy6V?6cc`{*-t( z*%85PIa-WkLV%a^hA;?bgjJBKWY>pj_!pcM^usEBLb)xc%cUArbaz zm}$TIfcNyq`dr9ei&NDrO8&<^0hkxc-)#bf4&!IT{dDv(FD>kZ<9KLYfD$KPradLCiBGuy>sN%2UJK;Oa z%S`0p6~2_YDR?@CVL9?{X2{UQ;`$YMCtrVU{OlD(;ZZ{9A1@P6m{W%lklC50UdL=;qIO*_znM6DIM+ z6EZi>TDFgOl4gf$qUzc<>n0F)v&mOaPv!50BRM{LJbqG%eCU3hHucW_3SgP5asZqc zM`rAds~c=h4MCE|ItyEd%boF`!4DKFCe9U)VVA|8B#9l18-m^+A^eO;7T_yfMkJt& zkgQeq>hZ~AozLHfzl|(xmSC#j7dyU(#j+ezPFLJ|2|hmNCk<3Y3OM&2|Lu|F|4{ql zpBVCgEleNVFdoYP?kTNZ`aRjSH!wx$1fT>FT8%3ZQEPV~w-v6%l}xo)O@UYm#N4G#58ewyxM`rRcEvj%!3~GlWg$}MdEYC6w zPsbwmIL|p-ansv+16F5m1J7(YY?zg5%EGuh*cxNwxxQlsv$k>-`@VmGIjI;bqT=V{E(_WR#d+$&PWeqXBCU7`FQI#zRX%-8geZOnN@MYetY zY@gv3jVtbHG>FC@nV3oRhxg0p$2Q&`7BCiYMN(Vl<)^?pPW_{~ARX$wa!f!>r(|A*v<@O>j~}Xbh90& zymy6ryOwWu-23cH8G;WeMvqD!syW4DfITYpqkn~7y;t}&y@(>Y>id6BrFip$qOb2(X^K6%qkc*A>B~J?c=PH|vLV*^KpT7CTIu^p z&YW2US1Z{XpR+>HTQOs9dTJ8n*R`jV&7Z0fdt8LJoc(EYcHK}7QYLgAD3?Xg+w>`1 z*O*i!u4t-X2OU)THTx*w(|4_|lY^5nwrDQUscZGz{5hZP2*h1yG&1H7UIxJ*^a}oO zfYlubVR!nbf1Z31{LYYlF!B(vDlwHK-ZWUGG;sUG=ft}-e0qvk>O;!2k4sWJZGNM& zGR{(W!P>=BzBl6doEG}D%Zt1pP>oACm*ur=TFj zB5jxSj9Hu<91U+-UuAu{rck+N~;E?1k3emopKzYu)F&-^SdK6y2HckVeP2;F_`t~8?QDzI!7E<;6M$-Tc8Fn5i z<^M~*jm^>DXg-9|{~e+m=l41Es{NqJHE&wy{Mld4HR^__b*|Qb_M7vUFzWwILP~q~ zrB)}CVo9;vuS&tkKl6Q3#?_1SjZI!VWUHZu4L@_C^mGZ&=mnfLM=99tH*m&eqDtcT0=x{lkXZ zXZ{R9U8gscqr7An!iKI@!azlo(0ppt%Vz}lT_75MqDn{lkMlYMD0nw_%-KEiek50u zsAQ~*b@#F8H3@U^W$(i?8)<^ciJyT1dg*zGrWI6y2)xqA%x>l*ddc1z#s%YPBNfUx zI8=|m{Fm|f9^0Rk4etLbL*elMvEN$o=NV1<@5t%DOGJM!dGLVn>e5YqntmKJsp(Ht zx|)UaIMc^RBXXptsUdYn;f21Sv6oL00I)*O6_3?O#7d6w^3XHz(i010m7J1RZuS?A ziP&H@a5*_KD2DlaJks7V8NcDEWH`OX&Gu-FF~&vrkF5=Sb2ifDM1o4z;z}&B zTgrP;`Xgz*3DXooV0ma<$~)li;7>;PZxw}dl@3qEN&H=V+*QoZVmHj!g^p7*?7nN^ zUmM`+0e)Z~xrxJcq@dczVO#+`tG(x(!P(NRTrspR5G@>j3EQp0 z#5WnkI;iRCIir>tI6FO8H*(1(*uUoKt__BQJd4-z1e zhDTZ)xfG!#CL@9}uE!Pe>PN4i&UDkV&+7s(^+Tn2>g28d&CP^|RMi_clKMV|%%z&9 zXp*nQMt@ul^}te-k!AYb+#LtxW-TPbuj#vV8;@lSY9sp^$@1Vw(v8k`@A3Tfd|SvL zz41JC@X!HsL9M~$d6gb6S*!j@*(>{tZBqc;GS29A)_RYk<%Q~<{0iseI~4b_VZTdm zpo_DpAWyGWNfNILkD9GP%%OoItD>_m&^3QBPzXA!FFaCt;SYcBUD21H>g`s_8V}81 z@}(xV+q8?!PMnvqTP3@qhB>@dt_*j4PGZfS+iqhnjNe3a0vJ!THqQ|XBHL8gG<+n7 zJ*2xu@WJdVT)kLMlun9%eD~L)M8`iIT<9H(~3zD^O@cch@DLVPk-DkxLBUi(7 zn8DO9BW1-n1+@#y<@$+nb*MA~kY$FLOl;(hn3@9Z=0H9vKUG?tyty;UuL&v&a?Q`2 z7Jt{Qdh)88&8kcC7-e(I#(n$8#4`PC%xZ1?J$HA!3EC36a^cC_3T!$XsrQZ62-pp0 z{e`Lik8T&vX!}?{Ab#6$^S-0s$`dnvL%<3X^HY_joBhj*zQ2#ux1}WBj?ojf+hO=m zwtr0JmOqWz|Ibh8|6KJ5k7qZPT2Pb z?#2-*)j#FsJ;MJ6x4Da#M0w3+G_eXQ4-eN^tp*lE zTxt=$)F>McMtd{#Nth!E z2@Zu@sVimkR0?D>#-Sc|(@tedZT9~dIXukPUE8^m+ZSo(&INRL9#e|svJdt^XHrai zaHA8Hx{yM)YDBmeSgC=trA2Yfgf}6-C1~e$=F(UG*Ca4E(*S20TS4vwwzs$sDl{NO z7vlzaAPl|4N$1TY26aaWaA0rU+@luE6)x5zCVuus^=sfxAiptZhdHWW>YQr!k*^F; zuNu~Z@oR1;XuZW|F%^}v5Zoze28+oQ_CDlQ&r>LA zDeL3!b~qGO*r%1|rB2cAZTmTjF;QW6GwzbF7G}({B?MR4SNnz}4($O`LQ?v_*0dh( zJd)9)o^yMcl~-UcQ}K3&K00Bken`xAd1WalnPtPRLOmu-fqv##B~6fI-F_~uL1gzT zcv2y6yxw_PfJ3-eKfkv#feqcbCT$0QN-+eKXW|tVaUhyraB*?Ud1df_vG*QOO>J$v zC~g(EN|B;;5lHAodWS7Nq4y5bNg!b8NYSly0!RoYRDlEtReDFI_uhM#-n*hV`}@y1 z?)`t?ch33mf5&(KbH~jXFxH&R%r#kAneV&a_j#T-`GT?$p`~z#X2gFtb%3FRn?Es2 zdud9)Un6p?*Q%Y{G)bqHdRIh)Zgoq;>L_Hz@tIq|a^gqD3q^~kk;cCh5IjKh8^@fe zD~y;vs$+?>d|Nel>6 zzR55>`Pm&-LgOtL|1b-n$$TQA^1wK>iz(G)LvRm10CA+N=aGA;d5hr zF4?BoQ3!8)MQ`AuFC1DAn0-D;oJA^c2jQ07@^R)(oVL9 z9wN-eXcNe#h?mO)2#5on6a+?9bK|Q4Yh%5qp>Uor{c$W@KA4*AoDfk7RRI=NfIqVTdtg?IhVbf^p0g=Tx{TT!`+65wz(liB)`apX(LD>0 zRft00#^X*-BMyUy>Qe%^SQ-HqHU``H_GuA;eUySZfYnIH(@!IR1tKhxR4ZMhJEx{r zG&MM+rN0N#ZO|0bM71Cj5-`c+9lxY9%V;69h1Lox>a{h_2!-~3g|n>G5-PrXtl@4= zClaNpfP_k_$fwpyH~`DM6Cl6xPVgjrc_~f>PH93_Lrh-2icT{jaoNGHHpX7DL|fB5 zax_VaoR(`#hV`&+moQ1JsJdSz#J6r~1=rXsyfHz71$i^r&+|PCZpB7aC)u70*P!kI z_(>zS_9~D%k0I4`PVq6oadmqQGICIhFs#l83DLm_2#N9qzn1I3@e{H%GJ}xDU+4G)ds0gN7=`cy#wp*&KstnPkp9C2R z!K!KcndQ5+xvXJk_oo~N{W&MEh+eu^s;U(LW}3@J&8z_kJo>a6^3`Xzxbe-5w=G~? zX;^X<&seQf&BgfFM?uz$l!omcORqV+um&3~mrH_`+>qW`GGF5n{&}-C@yn5#7`_bhg%K>azqPHCJRyXzjno8oZ z*)7O2FAKAD14~UmZu1E?6BZ-U@UAx;NIw}o|dfkP3h&22S}vdi_kAtH;?%k*Y#2u zK!+Y$?k>}HNwI~`h!V{KcfcSvPg;XG0T$`dM24|l*)9Q4lC3lHmU9H47OtzwY4d9u z6My2T?cJxU!bM2gftjUOh$#&nf z6dAn))u8y2aL&sz0dS1GZmvWyDW_Lq#pp_DKP95~NG^p~vMzxeBOs^iu>W%^t8;;wljb+CuzBM!PW9ecl6n^KF;yi19#FS3}+MqWvG+1d|obhpRo*(^o%dhEJN#k*91HR+VeNz5z) z%S*Gi@HD_!FWjdox2LOQ*NuwT(8@EML!bTky9KuodR6(bK{88a@k|P;sEUGjyyS*H zic^D49WT{X>9eYOpR96qE`s8oE@^b{uo<=m=rHKeL&-746i`566zhyFL{J(Zkx0Dv zAQHAjzS*3^i?>Lh|$z4Hq%Ek#BO5#wh~1|IqG47EY=G);CbJRNk}*}peYl3zp! z)fk(c3C)zAY>+0?kIpH!=0FvL(tg9BMlKaSJ;@{y(^It!B;y^v3T^(Pse#r}Y;B#D zow5Gg`Nm|lsvWAubu+2DI&H1`VTRM41)VwS8SrSMs^Qtfq#5FaPj0F@EJv8~W!MB| zRZL4;DQ0asZah7PcRQ(HCgsM__pGgT+`eaJ#^Isy(?H>l|EUX4hK~>MF zlz~_dh_y0zkg|zZ_gJ@B=%r#I(l#neIlFi~K#x0zp|ZfJ>|nE2u}LV5`?q(I0F)A@ zZnk(z{GQ|aZs2X<&P2^XjYr>Z`G5+xE=G1}ItB@zn8(zera_BV*qhqzMYZ8-hT69N zk+r!lMfMoj-7ej@&H?SrW_*RLIM9*PWn&bpESk4qTTbAskI|47Vq{{SjQ^2o#xJ^M z4C30&x)W^oQ%FCUPw2QW@#xWXYn-C!}7KNrDefY2eMQ@LaT&09K|Gl zbKDCLsHnBL;#{Y+cx00UHt1@=Voi(A#hF<)yx%*x_d!M*6-Ihe5V!H=OsYPT6n#v0 zp$wj^*_j6-nY$qEgP(;G^cRvD)`)F0k|#%fjX>4*6D`$+4vadlFBcx|g!Gq5n>o>k zB6?$^c+b3~j(L{60eQjHshS>C?#-TiBDu6ebhkh{z6yIwIL_a$o+uiia6;IMZg2i+ zos76Dv`mWV5J`xxZhq|dhyJZNN5_xdp);tU#8|u*&L{RazEM60y)xZ4p+5-LX75q& zyYYbZK8?6-nnz)`l;+J3N{e01vNbewbaH7xr&Tin-0Q1}vHS?H31GSsJl{%Id>0Qo zoOT{B`A%*F%%K#>JN&i86wSM}*gwBE_pvbbl6>w5!Ek!Wu!Vxin}Y|}+e>Iii)@-# zSKx&UQ6)@RSQQiKC;^iO_Bb;x16yvaR;>IWaLd-rCyP|gKZc$1d?L6b;K=w`d;77w zO)NI7t}^fF2<=-j9WiUS0}Qf3E|*HT)(jb)^WXA+Fb!|faiHx|&yYjZ3TE<^eWlbW zDNviy5c#U;awer#j(X~Q$F*uW0V?tK8DAyJQ3yEfF$xvRUpaY0WNRB1T{9$=oR_?kj+|L@KqUj+C0RVFct>!x zym!=tswEyj0}*sTvJJm34i_|qZNwq9qF$^6IRRo_Rb|h_>=TJqCLz3%tmy3VU+avm zZj!J8yWQ@?P5O+yE_qowS1Ec52MH>Y$JQhq` zNf700Ro`0e0#i(fbdM_ErQ?w*P5i|SfadNUwMVjSLS^jo9#)IH+5HPd4U%8P9#bvHrN%?JN%G^e&`6{ zRETCp^qyN`;UcgMa(^jSh)mIX#*nReh-Auu9`ZxGpF`z?;8>w1<6FUQ;R1q&Br~}- zJcxm27Eca`Ii5$?E|r&5+9?7+rzsAb$PvL5TV1D>mg4tC;SzvN#BU|~-=>^wt`x>H z!H6C(VxPQ=RUr}oP?m-F$;u45M?pR*b>_O!=Dmp$Tlwvj^k|&WfJ#IQZ|10pD1(!T znAwI7H86P`q-$4-)&p)t^Drl$idJy`{WTNmP+^Tee_~9yLjCw31lU|LB+L|2``-?toyPh8AT{>k&2>GzL;NtRr zP=t?HQ*;LJ9$twwQcxlwjvP2+HCCBaL~qlTEwYW6Un3p|dmaZk*OOOP3RLYdLe#~a zG&#G-)w5Y-w5m?1cRshSZVgw=y=_Z{7{oc6z-Ua_UZRImOh$8|QDvrZJ(w7(K?A4c zPY5H|Z#5M?`Q>c|C;wG%4`)&Pc9t-S`F#PK#(QJLH7;bGYg6!1?s2Gau_OZLcfMW} zS6xr1^yG85W#iklwIQfw9INk&_PW5BrHcwUd}1IN`L2n@WTJ~_?Ww9EnP{tm-4{vX zT&0eWD<_+@Y5{Dv*x2Pkfx;OA``DC10}Wk+UQ@eX)4mG49-WeVgrveu_u5b?VBE5> zL*$j+cTxR(Zb)UeQK2!>)TgYnusxG*-sBIc5mit}v91D+U(2;BUb>qJzh0O^9RF{n zgQ>hD^q&vI%V7Fc1hM3bPT@$D*rl@aFQ)GxAd0BGaMp@g0Ae_Uuw{Tn#hOdlowvB( ztvj!5z0$!-(UL#mxn|Ndc~HYvEeq0o8-`4QtqL{$vLaV)NTy1hbGY!aYfBLGZ8JJ^ zHTmsZP~RS01;uZ%HfA*Ir?2X}Zn_Mr+2oXjK$I%Df&ngMxxq@d_7ILnD%%{3YdepP zs}}}(gHs*%mdDMn=#tDw<;}PtA{7d1(mcVpjI%luNYTw`v*658JEWDE8p zGN892k*UCqfcx+&xTsjy1;%%_`6oAt^V(Of4-1R+AAxkq$E%Y?@7D$m@t4Ngnx8+3 zmWfUqaCscn(5}bFy_R()ytO+kg!)84o1?~Bm|GM7LYS4$SC9mS?lBGwcsYtv#|y@Q z)!*uLery_nejBD-5}bHNb`^S6s%rCt;E;jx^SD16$C^JfS@_j;HfqN^H15T5LM3Oc z<#as0UO1LRrs@*`2?q0bt{{J1i891BB0l(*O)Na7*Lth*jdZj;f-BsaYD3gS)P&`T zF386A7tRwKi&UJZu7Su4AKYT;gVtx}ZMhD(6PZxl2~BU{RS7#L_}y?9+mfaopHO3! zbWC$RRWK*ZED8@~XJOf7VYq>+{p6Yt!`jw4KuCzf_vj;OeK)ix27JEpk;g8y`{0W; zw2~u>s&%1;{?e8S65$lcb3<@8I)C7?72{Wn~#X2^(PfV5G0t&6L*g z49feMFadaw#2MS?$0pXSz2V!>@q@s_C3$#f|KT6l#D9omEcic?yzmFXqTFUf|TNjoud0I_U~GSA-V z=zoVu$xyOKpu|svgf7~oOlYZzTYe{|Cn}5T4XegOEv5Uw_}|*-WW?XFmL7LJ<32du ze5TVlUp;a7zNA~M#yVe7M_u=gcGT&V$V`AhoEvm+q6`N3530DeA6n=uiRy3c@*L`X zc#m-7<-bIj8-7qO?Su!zdEQ(TZYymo1j@faIKNi3Ksb%Wb8JD|`$->4Jz}N~dEfw^fus z{~Yhu>4kH1_ncM9|K7TqYC-E;8?9;s{@$n9@@crWiQ=}7c!}*7YOpk^c$@5A)QE|B z+H%!Deyef)T|FMNDI_4`-F@h2aW z60tgo$zNmKJ13J}Mci`I;zkS-a*8uXMn}|LP1N&<41a>E|Aem&C2#Y=`IhZT{e>R% z|Ha#!fWYFUqRY8thiL9jl}V^v z1$XY^4C}`9iCg+Zr;+i4*UV zt5#cmIAZDD*FiDzPM^zx*y>cmJmJpYbD2?Vl;abcNCgo6G$;blh0hc;#IW=|?r7fj zd*9QoT>B{1{}Swh+4cBJ$adfGuI`%>I$7u>{uUcgu5$u=JrySjhU93nHpAlevjv>7 zN~zmp6XOr)p=w@H3G-Ik8P7W0kuvIF$3Z9Mm*v_Xq+V}TgtnnBs*R3UYxHoN z_C=2j&hRBe-9B@K=+o+jx?c~G4@63NF64S@{kopaB~?K$vr`)Xvi zN^FziUFzmk)nd0)Bt<)P&P=&9;#Z=BF&^hH)7;^sdmVi&9|B`9#p+x29;{3#*%g4I zo_;gh0zU1ndbcSmOq^Hq4$a|#w9n>=QgV3jr17*$pA0q}OHb!3TIk9&0?_bJV>6!| z8)?<7pHJW9<$c2w31cUcD1S+x;aJA+;}Q*7zX50dN`*zXc1(#CrACVD%!Ja9wZfN$ zzDDBf&?_i+Jxv&z&u!dSb$OfY8PdqA(7|#3Qoo04ub_%yKesGMWM&5LYzo9s-Sy6` z2GOARF*ibWU~|=Qn;Wm*UzsC6LF@Y8n8M0=oku0_%{#MQtQAgh5FV3cwm`<%`<#=b zDm}fEb$<<*7gr&h|j=nQog>oCzZ=7-;VmaKkKp@HU5 zfNn~ked51->>sjY7-~h#?;T$RP$c6LwEji&`*)l04M^F+!G1R%?46Py+R9-Z8BzZ- zVZ`Bn5WY;k-NWH|Ou_^k4p`avtCjK`gJJ*PM_x76R-zADt} zxOt~Fd&y{K{PGW|dBH|DM2j z{ z5HI{Wr$Alw&8&b1*Y&;-)mF%AFJiaK_5d&Rknoj;__z3mAgO%eU78_5bp60ZaMvQJc5SfEcf=EJByNnLaX%{iz|Ev%a<3Uhet%MndhW;#2^cSZ~b14`rfBs(K0D? z70!7JJw2&rKRN9ZhP-y4^t|i2*@JK&Px8-C)1l)vx)4K}-B z#s(2~!OB8zVF;Y?ZuivfZVVE_dq)ITF0gd4mK>T2ofi&i&iZ`BoqtsRSVNzwH=vU& zCCU+-%w=1LE=vMcl-tXv{whio)|2f*A)B4E`6zD6Cidwz!_!u*mf?rIQqBx4q6R*t zgUp6isnh@Z4EL)bi0siO%h7{DIc!c*95c*QjlB$r#dP|HJP2+`7-^p3Q83LzrU&gW z^1gYT&UtTGd$`hN{9C=Jb17nEbv8Pkuzp+6S5YH$Ga93un0rb==OmWk%vv)SFX-m* zeIUs`TR^C=%GE`!PJb2Wc*buN0=4bcnI0^(*MIK8Z-GQ=1EFf@wK9;BL$jr#Bsv|> zL5ye=VG3Uq6?4o0_qj!MLxKfxB9xUkmNoI120# z;EoU5+(^Y3_xJ3@7=@%AH#JndvzbI7laK;sk-Rbr`lugk!HD@7fDOU*#tCp$8 zK}Ce>;%y_XX)%Fm9oVqktV8oijB$n-G{iK~VN7?&Rgk6qxz3Cg$d%sAXcjfr6Hh3Y z3U^_v66RnMY<}@LGyAZs=-xEGXo~8=RJ;N)Xe=lMGyq6|E zh75W*Gl(3XikqNVJIMxMlvOWp0kzsS<6Zj%5L0BneqX}yy7kmK;YCDT#L8V<$CB&< zPge9Ibx&gLgmUITAThL(p5yVQc-?R;g^D&gV%&v2uG|_WX&HARzO)H0Qgq%n#aYg{ zyK)MLW~%-&_l1f>HM2+9{uFy_etp&==>x&dOpbr(N&TbF{~S%`<{kBw3BIqu=vOpu zqHq7)cta#R7~uA;x3Wj}l>eKA?A3b$0uB9tw1S^~{}NB{5AFfn&0mnRkGYzZv*Z1= zNOR4kI5#q(8}Cj{H^o6Wu0R6(DeLltn)15tBD$;c;*B#Znp=PzV=}58rluPuhId1Y zkMlo+PB1-0G6o$>OrNc``^jdpfO?9jQk_edCSPRmc*LjTvCU1D{Q-Dj-17y3$hZ%I ztTNC&*0pa%=lSXW^}VD5Vus_j19)^Mg2eVkNs)U79-T=o`iVa6?IHiM;fwzg1NkS( zzfNhaxzin$i}KeXhd=71cUr4+gRBf1%v=52<-)8|BIG^(%1Z`ac!cax zM$orx%r8(Q6H127XUaI>j_{$lE(0R;PI!?xz8XF2gw1n;TkB!?g4MM45s*T(Mqju* zbK3c+lc$G)+m?D8V=#DE)O1PncyT9PEHUC)hPD13C0M80>E-ggm-b6&;zozPCRzROyYzNDm~@z~EMN>h#k)oJ&Y4W&Fz zlc=2Y60X@gq;Ye4G91J&xKy5Ve4OjGt9dQ`N>RzM-cm!L912R6`FV@d|GdRrU%R?_ zk+yd9nRjsXT$=9dOI>;=J^m*{#U<}7+pHHa{ig;>Pn$E3baSz~WUqV?=;lA z(=j&OgiWc!9c9Pkm`ZQ#QPcB?rrp!l%;Ks!ma0Z=wKe-BM@bWlcMpsc5WpTj|GDG* zFOUAiB>KP1NJx^>QEYjpO8;G8)%7opTh#bRfVE4sQ^Kn)n+uOur@s*pq~`zS&41VU zmn5YLesRnDyEFfN$6w{ZKW~2tD^mIjbp1w`?eipNq9QQA=clJg6E1n1c8&lpS zi`()r`Krt>C0Ep&!V2~_WAA^V9D4OoK&d@!Z4H3tXrmgEt5Xm@r2H_r#M#|B-Tb^@ zCHM1S)O>X*u(8@U;cQxEY}RaaWz5ZGzi@fNu*G>UmQxo8$$4k-kOM5h%s0(8V0&4d zjZA7ziAC7-?Cbl9h>T$0{~(Z{^uBLD9H^Y3xvdIj0h00rW`HWoW8$Ft`2uuCJ!@8N zs!DS(=*I(UK^fu1i~d9L>-k?~$SUchW%))+Ui!EaN}e_CyK2MmxaYw9G3asf0n2r% zQ*(fzaoxDh5VL<2t1F%HETr+&1Ea*b2m^04lE_FQ4R8P z6qat<>S#UQYHlyPdwDo~>&Q>2fsOz!w$9$K~vXm51d%-i+s`rdq7;aK9Kj^cc|T=I`(kR~O&QIPK{E zjx?Kc9-<<)54!a^?{Ynv+%E!$juu#WHlgAZ?{uT=2f>ZgjFXDQ3m3Hb6}_b#;Rr=< zX~TSZUCkWQwj$omRS3h8yCP=sC>>&}3TZydgs|`pN~)3QX2w|Dtf-cL)s-39760^L zg)%*W*KH~QtZHT{Ke%&jmJnBkuR&D!r`zezM8ZF_jhxsJ=66qj7hE!3+$sH*ARIUL zUH;sC5l=z-^XsX{ytEr0>tXceFpue-P+0wq*Yxz<<4Nt^GGz z$e(BV^YOo&zW(Qv|NG;=(p3m8^)~F*Ol%UD56Gc$aCxg6sKodVe0r4cdQ=`8zN%HW zV_m>jY|JT*QNpsE z-MFbnq%9`?Nny?tWKySLa7|&NFT-PvbI-h{3VQCky5$&!mqGhf{5U1%swnzvEtwQ+{Klu~_TEDn#PC7T))P1liTmzW2Qm z4TTxMjoD1jk#HEyiHPezZlbe?vZ9q{RR!l%wJ-E489_KDdxv3rd;Yp>oxbl$1MmHK zVxk#RlU_`tc?Dxy;bWc7v9w@16Uv;&2E8?Ajx4GnN?EhNrPehKUiH>Rl8taW^8wvg zx1F*+^Du*RA?R{_>Mu%ATOYNK)RI&dwz$rMxM--(nT|4_xIs5*P=RF6Xr;fSxjnzQ zoTt?%-H2ddu82fQ<8It$oY!b!1>^JAmkhX<=v3q92W~s{Y}hpUl&J}!m7b3Da^Lh7 znJquxrx9uf3!3CZ%~PUvl<~B`_9AL76!*Nt7pdcA1d}-GX~e1+7#Cyd5@PftHB`3 z1K00dLb3k^R~Kj1!pmgy+NV!)x5w<}ifvAH=n>TGrB`NDmPy?ek=-c(mpUK8rA36%*d z8J(fG*VRj|{Y6+cnuA#BW8_CS`?|xIb-L|KRYyk{3nrR1<>5%LDgFi}ccW+-sLx>nV=CD_D^Fu6)h~8>jPV80D8- zE2yargr%xGL_%il#zXTypVOK9Cr7>U zOB5`UubJNdLU;3=)4?Qak(AzoZXu2L*eL-nH60j|So8dARB;phgREPQXP!6yO)Jj> z*VMMP8wi#U=D%%vM;o^uL#}8omfr4()LpiJy6#4gXU@VrkE4G78ZTI+bZ|4W#qSt9 zFYZ9mm%9P+3nBe^worKGM8C+LJ-z-)x=$p0#QXh;K5MC(A{m+3J!+X1r;=1>(pg*@ zl%ajXQf!j3R##%wl|ZaP^rM9N%KzcZqX9`^f0ql;{$k71Zo=AA;+|kP-c_9~;QFy0 z3L<|H5*dTiMiNCyvR_1cQ-z#=QEhPRXG_r>96l%U{(04C)VAry@7_hM8#^&_w$m-t z>5F05AZrb#3GG>Ks@=#bDk=(g&us0-GvX(tH36|N^^(1d^<|$hTbpXt|8}TqUFO+A zjumnKwCghMTM4YD)DRhd2Z2F>&ha!Z8+`c!$tvOuM58^$Wme?YO(+~-1j%MQGhY#yACWa)F`_Qb>UXcE zWedPYtscKsoz%~j*Gw3VD8ILcQu zRsveq$ZZ3p=^n59TsadSdBs~%Gpq~`?(Y10I%T`5AL-I>%bG1#JmIOLhbqH9?!#$x zYGb)xy!*nANvf(CaTW?O0Rf3INL1qMu)1GEFl(OynQRp&6&dg8XF~y*ZJe{Uox3&@ zEzVu6+dVVk_I|*-eD@NvHvkw!@71q}c6}l!Ar>!;;C|q5XOFJ}5BS3u#^4J-|KSU3 z;(cL6hDtl#eN!r_ZvOf+&+=EKuhSe~oYDphXLg&E)bh9mkf|5B^nm(CyQtev3&gI0 zdfSNQd!SAy>^p7j7}oMUMs;$8A^RYietGTJD%R8kqUcPk02Fd%l(R!Pr#{M=OK?jlwkFIGvD zoN5w-8P67`xlrpc@}ias%hP#*6ZJ0c!%kKAl)Nu*@yFq1(4z09I#65m7wTbion1XO zUut>l46ku;k32Eo23p}f;ww<&1AUHXbzi;uy$fJAo`FTG2F)IhB;Qmvs$7>H}@=M`7g(J1( zeU(VH&OXi=o5}5e_>8^u?^aU&)9U}lqqy@|`$fd~(|(cswDF>^|IP6@>=8?c$;zwF zJ`MP3^(BA0AoB!pAJ;&S`i}qTg}U=|dCF@(=|v{lm9Cy9RRFsaF`w^ZFIG8Zbl3o0 zNYHEp1}SiauYj{a0C)W3Oua|_KxmY#qUx-;SQ8&8WLUYQbR(eXo+ue63JP~JK|xI; zO%S7%I3?^K0-Y#({7d4~FOF@`*xQVmtBOqGx4=cl;$V&4MxN>-e9>=$n}Fy4z~B7Y z^)C{!_+O@3ey-@B9VxDF{!*T%G_Y=~S0yZVUCEiZg43}nsLnuk(R54?%3f|n#jPOl-jhx}iqBb6=pzIym(W0t3 zuypU&MFLWb0RQ_&ng-Ky*0vyak$G!*2)z11ASI3y52Cy#lzvTEl8Hv7(xS|hSyh|M zb|o*bMSZ>XAhQ#QN$_R6%D@kTEYwoQ4XW5gwV4BQgP{kz%jibJ=d(fjP1}N2>?vvH zJlWQ^!aoS`>9+;8SIl)fS(~7|I;Bp#V+P5NV>Y9**qMhDT3VQAbtT4vB24V(LRdc< z4nkYgsxn>Z5vD^trjv4OK8NbFUzN?5FsgT*v*Cf7E0$DFN{ED7-@>RwH9L_BpZXbWVX_BrCi zD2+&!8-JQmzLLBXjX$aj>@ibRWcXcjRk8N6N0CfoQ)xm8MSg$5r@wd^zdTQoIJ z@t(%tqNyUzAp`hms)3Q=mTo?aPz15Gu!giDEi$Bx$J1Y=EAP;{A|V-adl9UIWM;m8 zo7r_qi1pKJz2Kj#JokGUwFy^CIjt%%OwRb7aSs_tu@TufdOV+mR(qL~wjtz<|-Ym`x#fF650gEVV@X=W^$dES_pYnwB zba4Ty0Z7x=1b3tUM+7kb9|swi3e)*L*v4-S1iQX1>o_tR*EGB&of~+~`Tn1MUH)1B zzh3zLpRMG7zn^p&8IKvPKq9jyJA2#&u77bCR4*!}O0OCghc9M2=??SPMra#=wJ&@r zn1$txPfn_orZT`Of-=n6ugBZ0*jJd)CZcD>IWCKbrw2UwE{BQ3ks~yoB{t)gZMhhH zDTl`nc{}1aZ?#~D8)@|-zN(szM^-*pu^KBoq6R;_76-vAV`(W9>Lk}qNKWOu+Vy|1B6%tGqK8=9DQuQ=@4*f%}I{~57v$^|IEk0aF_NpyQ znY1_yb&GwwbAPj{9;11l@RHY`+jMiV?DZB$<==7AJdRhg%5q+A2T26CyZZlndH#cl z+fV;pYUr=C{Lfnd6)b_nk+l4$r{{N5tHnDu>9t)zrRCQA=)ew2`Oty&VBgJ8*DIml zJ`$CKO;Hmhx!4hdP#)cO^ z2$JZbq0(NNoyLZHV^Uq-bf2hY{&X_g5L%zLF!`0VvQ~4UJmlb6@Ku;6pOsT$;8^Q-zz+gJ8Rd_IbQhF|?D1J@ zYeu{N4bj5HM7~;d*1?+sm*8#Ilz>s89+;3SSg$K(CoV-~YA=fqSDI(wnY5-48{M1x z5PmxZ*tIO|wht@=*4Cb6kcSPpZ*DR?p@{$OFaHpEk?mn*rpyOce=h$&i-iA4ZR^j~ zjSg=A4>`xbO!Gf${6Cdx`F|@baznVHqIR?ZeQ_r3%9}xx`>w{o>qV*vb|B&HROiqv zZ$gUm*9ivAKqnSCV%A`GXeB9&JLx9@=SmbZ6_cA{jl|pXDJvJM9|T9zM0E77WG$PA zIipaC3s}W=g!Jfky~|33EGMd52k|W@o4?=xeTQC4yAX$@xKjXQmv`I>Ju9uzdR$6^ zGar^UevJ!Sr@>*F762h~Cu})<)YsrdSAti%!*!V0)*9*sJ``Iz-`2j=%NCR!mVBdM zh*4j^Qsfx}5>+ShRPsOpu^in~Vb4790|2qUYMnvH+}*C3TM3|>B)ubY-o}lOq$S#F zb~;7E^;LDIpGgJ3PhUVT%_73V%48gPhMNwx|Eb5B<%Eqv6LT@M3l<^{+I88l%upk^ z{Jr6e))A)t6A+4unEXH%hblx1AAq(o<1#ZUuwi)dv%5ldOAXEJHy|bAvIIxW3HiynjZ($q=&_hp&&D#2| z!@aVr#mH3ei%U|2OwKdCv!5UrxK?k7UX94fqp%~+F*Thd_h^l-c zR0(W*w7mo*^;d7?1TWA%Y=@r_{2{e*93|bdyU^iw+EZhnEtT<0`*897;IE>b>%otMg)iVzaMHD?PR;dm3_4X@wzzG{e_gTNHLj2i!rTUGPSXL>qJ=KJ-&QH6EUBs5d+2vI5EFc+t z83*>04cAS#h#Xh=jM&-3VRiqYyzLdpFu0GiL zfjF1WmW}E&nU-A_-SeHL25NH(`G}F41SbfLb+38&6ve|DPa#+cP<3*XLCV}28MN_u z(tNETk@%sa=Ofhm75OXlYl8oiti_Ete(Kzt&i2NeRnOPO3D!*% z$?vLA*|TF^bwM~Ks8BLuRP;Sd8vAIK*8t0|(mWNNCE>!Y6KM#Ry>S8&r!m7@A^o>d z&+4c%#cb`r%V7BYTjnIi?7zow{uG+{FCIDhFSxvB#-d7z-g(5AViSi+voKIQk3KNz z0#RiS&kFlOtF>I1prW0y3Kn7yI}-#q+%bPlKfvJ1*Rl^6O$CU0nsU}cWq$#!qo(kR zoU39Ip0Ty4rTB!hL71khd4X+n6Uw)U1|LWctf&i4ymDQm&*(R$ z&CJyTRo@~b7Pr8crHH^(o0Josk7J#it77ZYiMrqpfjZjle01mP+HW5s!uc08z8(}+ z|2mvC8+IljOVDk);gVo#qc@4?4f+_h0ov5;BN&|Rx6_s(VLNt|f`s!Cac6@ zWyS}7VP=68!j*ik~`C}&m`6Ef8Oq5x4X-FYsJ=DSDL&7S|6XCnm3ZftWadNRe2WO`zL(XWOUU3OV<>@$ovBm4=vv;V}AV-Me z#lFMZwL<9}vymuRZCzA_Yx^txFwXhNNJQ}|+5~j1@n%zj$R&oZx_L`L>2OoS=vkbv zIj!lgI=ltm#V#xYg0zX*mn4J9)8BxA00ooTIO_IeT4S+!%NPR-y*?1D+I{w@F2o^T z)tcvz?*t384DukBBP;C48NtI z@{B_PbwSbUN9H1!yuU1~^}XBl2La*6EP}U;#@PDKTjl-rbvH7(9>pb*^dAJ_77Lj* ztzSd0Vz1f-?ey1+cs6+49wTx?6WYY82jkSM2a&MGaPq=>it!D!e@dEhW7fy^cZZT@ zNBqWK`X7F+63{)MNgWPXu!XWc3YWS)?D9U?8d2%;J%^`VvVayYQ>AK~H*9Tnlxo-N zBRPggF7v+SjT!oYC8Z!P+a`qI#nK`u>PH^`3o-stAK$ux}W4n!1Nv2%&r^a=bKG5~*(^ z2p`j?4DL;+!o19S-R5~oCDLt8MpraaZR_+<6q@ep!XLh6-h}~z07z6qtAZ&R)du7H z8z24-boZYF()@G3@aJFtZ}TjEPVx6gH)K2E{*g2diRjG})-Ul9;od^`eYtaNf{-9k z^m2Xs>I*D~HkYj!D%V{uuGNEpcCrD;4U@T-KeTPmKJ$46`aEZiG8sA?IR>nq9xzcC z8c}CWh6vc2Oy!cvII%ZraBxW9kBY6zANvFU!?8!n{joQggKbriaX#Qgc7T_7pHg=H z-g6Q!OID!^VUJg?-(syg1Z;*kG`kE$PKRB`uevg1t{A^05}rrkgFqPpq{lsP{n|(` z-z41}=nMDR$3M-zTS4=+>YbEcBOL~sLNC`oH!g>M`}Ac&{@c;w{Gt5!=Q#xalZkjC zF2+j|apX5e&HroO^1$^`zhBhPi;=#k0UX^zb_qLu3{9yz*%2w8{ovHpnP=mjeJ*Uh zttj2HjQvq}JnJrAKVrz;dPm#(+;!RV)v19Go%%KxnYyG(O3li3bIG&X?B#ph zr@OmV(^FOR{k8)-8zlLr@zvIi?jtYrIVq?y%e>kr{1k*n4`4YQfBzf^TF#W$7;}TlL#p^!3D0;70s;zOG;V zuEu93?JXLW8V!xnv@x0;;Dv+Mt=mDR+Ce27pKswdJ(^t@vnclN)Twt{g=XZo21Yr1 z1<(fyw?Av+D#=33SH;IewJy*gV^kGdDf8N~`iQ2QVC3&H|pMd)ZU+0=1 z+w3KLWb2acfs?#z&z#uh%D^DBuF_QeqIGEP(yp&3ichZC*LiF8Tb=NAt|6mR!zVO^ z{f>9p%xdEmx. - */ -package com.djrapitops.plan.capability; - -import java.util.Optional; - -/** - * List of different capabilities current version provides. - *

- * The enum is package private to restrict direct access. This is to avoid NoClassDefFoundError in case - * a wanted Capability is not provided in an earlier version. - *

- * Use {@link CapabilityService#hasCapability(String)} with name of a Capability to figure out if an API is available. - * Example usage: {@code CapabilityService.getInstance().hasCapability("DATA_EXTENSION_VALUES")}. - *

- * If a capability is not available, attempting to use the capability might lead to exceptions. - * - * @author Rsl1122 - */ -enum Capability { - - /** - * ExtensionService, DataExtension API base package, PluginInfo, Conditional, Tab, TabInfo, TabOrder and BooleanProvider, DoubleProvider, PercentageProvider, NumberProvider, StringProvider annotations. - */ - DATA_EXTENSION_VALUES, - /** - * DataExtension API table package, TableProvider, Table and Table.Factory - */ - DATA_EXTENSION_TABLES, - /** - * DataExtension API addition, allows throwing {@link com.djrapitops.plan.extension.NotReadyException} inside a Provider method when your API is not ready for a method call. - */ - DATA_EXTENSION_NOT_READY_EXCEPTION, - /** - * DataExtension API addition, parameter {@code showInPlayerTable} for BooleanProvider, DoubleProvider, PercentageProvider, NumberProvider, StringProvider annotations. - *

- * When the parameter is set to {@code true} the value from this Provider is shown on a table alongside players. - */ - DATA_EXTENSION_SHOW_IN_PLAYER_TABLE, - /** - * - */ - QUERY_API; - - static Optional getByName(String name) { - if (name == null) { - return Optional.empty(); - } - try { - return Optional.of(valueOf(name)); - } catch (IllegalArgumentException e) { - return Optional.empty(); - } - } - -} \ No newline at end of file diff --git a/Plan/api/src/main/java/com/djrapitops/plan/capability/CapabilityService.java b/Plan/api/src/main/java/com/djrapitops/plan/capability/CapabilityService.java deleted file mode 100644 index cd5ed969f..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/capability/CapabilityService.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.capability; - -import java.util.Optional; -import java.util.function.Consumer; - -/** - * Service for figuring out provided API capabilities. - *

- * {@link CapabilityService#registerEnableListener(Consumer)} to be notified of Plan reloads - * {@link CapabilityService#hasCapability(String)} to check if a capability is available. - *

- * See {@link Capability} for list of capabilities provided by the current version. - * - * @author Rsl1122 - */ -public interface CapabilityService { - - /** - * Obtain instance of CapabilityService. - * - * @return CapabilityService implementation. - * @throws NoClassDefFoundError If Plan is not installed and this class can not be found or if older Plan version is installed. - * @throws IllegalStateException If Plan is installed, but not enabled. - */ - static CapabilityService getInstance() { - return Optional.ofNullable(CapabilityServiceHolder.service) - .orElseThrow(() -> new IllegalStateException("CapabilityService has not been initialised yet.")); - } - - /** - * Register a method to be called when Plan reloads. - * - * @param isEnabledListener The boolean given to the method tells if Plan has enabled successfully. - */ - void registerEnableListener(Consumer isEnabledListener); - - /** - * Check if the API on the current version provides a capability. - * - * @param capabilityName Name of a capability - * @return true if the capability is available. - * @see Capability for different capabilityNames. - */ - default boolean hasCapability(String capabilityName) { - return Capability.getByName(capabilityName).isPresent(); - } - - class CapabilityServiceHolder { - static CapabilityService service; - - private CapabilityServiceHolder() { - /* Static variable holder */ - } - - static void set(CapabilityService service) { - CapabilityServiceHolder.service = service; - } - } - -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/CallEvents.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/CallEvents.java deleted file mode 100644 index 88bffd7cf..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/CallEvents.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -/** - * Enum representing different events when Plan calls methods of {@link DataExtension} automatically. - *

- * You can also call the update methods via {@link Caller} manually. - * - * @author Rsl1122 - */ -public enum CallEvents { - - /** - * This event represents a manual call via {@link Caller}. - * Definition inside {@link DataExtension#callExtensionMethodsOn()} is NOT REQUIRED for using Caller methods. - */ - MANUAL, - /** - * This event represents call to player methods on a Player Join event. - *

- * The call is made from a listener at the last event priority (Bukkit/Bungee: MONITOR, Sponge: POST). - * Method calls are asynchronous. - */ - PLAYER_JOIN, - /** - * This event represents a call to player methods on a Player Leave event. - *

- * The call is made from a listener at the first event priority (Bukkit/Bungee: LOWEST, Sponge: PRE). - * Method calls are asynchronous. - */ - PLAYER_LEAVE, - /** - * This event represents a call to server methods when the {@link DataExtension} is registered. - *

- * Server methods include any {@link Group} parameter methods. - *

- * Method calls are asynchronous. - */ - SERVER_EXTENSION_REGISTER, - /** - * This event represents a call to server methods via a periodical task. - *

- * Server methods include any {@link Group} parameter methods. - *

- * Periodic task with a runs user configured period (Plan config). - * Method calls are asynchronous. - */ - SERVER_PERIODICAL - -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/Caller.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/Caller.java deleted file mode 100644 index f56475ac3..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/Caller.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -import java.util.UUID; - -/** - * Interface for manually calling update methods on a registered {@link DataExtension}. - *

- * You can obtain an instance by registering an extension via {@link ExtensionService#register(DataExtension)}. - *

- * Plan calls the methods in DataExtension based on {@link CallEvents} defined by {@link } - * - * @author Rsl1122 - */ -public interface Caller { - - /** - * Calls all player methods of the associated {@link DataExtension}. - *

- * Player methods have {@code UUID} or {@code String} as a method parameter and a Provider annotation. - * - * @param playerUUID UUID of the player. - * @param playerName Name of the player. - * @throws IllegalArgumentException If playerUUID or playerName is null. - */ - void updatePlayerData(UUID playerUUID, String playerName) throws IllegalArgumentException; - - /** - * Calls all server methods of the associated {@link DataExtension}. - *

- * Server methods have no parameters or {@link Group} method parameter and a Provider annotation. - */ - void updateServerData(); - -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/DataExtension.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/DataExtension.java deleted file mode 100644 index 5636ab5d8..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/DataExtension.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -/** - * Interface to implement data extensions with. - *

- * The class implementing this interface should be annotated with {@link com.djrapitops.plan.extension.annotation.PluginInfo}. - * If the extension is given to Plan API without the annotation it will be rejected. - *


- *

- * Public methods in the class should be annotated with appropriate Provider annotations. - * Provider annotations: - * {@link com.djrapitops.plan.extension.annotation.BooleanProvider} for {@code boolean} values and conditions for {@link com.djrapitops.plan.extension.annotation.Conditional}. - * {@link com.djrapitops.plan.extension.annotation.NumberProvider} for {@code long} values. (Use this for integers by casting to long) Has option for formatting. - * {@link com.djrapitops.plan.extension.annotation.DoubleProvider} for {@code double} values. - * {@link com.djrapitops.plan.extension.annotation.PercentageProvider} for {@code double} values that represent a percentage. - * {@link com.djrapitops.plan.extension.annotation.StringProvider} for {@link String} values. - *


- *

- * Methods can have one of the following as method parameters: - * {@code UUID playerUUID} - UUID of the player the data is about - * {@code String playerName} - Name of the player the data is about - * {@link Group group} - Provided group the data is about (In case a group needs additional information) - * nothing - The data is interpreted to be about the server. - *


- *

- * The name of the method will be used as an identifier in the database, so that a single provider does not duplicate entries. - * Only first 50 characters of the method name are stored. - * If you need to change a method name add a class annotation with the old method name: {@link com.djrapitops.plan.extension.annotation.InvalidateMethod} - *

- * Some additional annotations are available for controlling appearance of the results: - * {@link com.djrapitops.plan.extension.annotation.Conditional} A {@code boolean} returned by {@link com.djrapitops.plan.extension.annotation.BooleanProvider} has to be {@code true} for this method to be called. - * {@link com.djrapitops.plan.extension.annotation.Tab} The value of this provider should be placed on a tab with a specific name - * {@link com.djrapitops.plan.extension.annotation.TabInfo} Optional Structure information about a tab - * {@link com.djrapitops.plan.extension.annotation.TabOrder} Optional information about preferred tab - *


- *

- * Method calls are asynchronous. You can control when the calls are made via {@link DataExtension#callExtensionMethodsOn()} and {@link Caller}. - *

- * You can check against implementation violations by using {@link com.djrapitops.plan.extension.extractor.ExtensionExtractor#validateAnnotations()} in your Unit Tests. - *

- * Implementation violations: - * - No {@link com.djrapitops.plan.extension.annotation.PluginInfo} class annotation - * - Class contains no public methods with Provider annotations - * - Class contains private method with Provider annotation - * - Non-primitive return type when primitive is required (eg. Boolean instead of boolean) - * - Method doesn't have correct parameters (see above) - * - {@link com.djrapitops.plan.extension.annotation.BooleanProvider} is annotated with a {@link com.djrapitops.plan.extension.annotation.Conditional} that requires same condition the provider provides. - * - {@link com.djrapitops.plan.extension.annotation.Conditional} without a {@link com.djrapitops.plan.extension.annotation.BooleanProvider} that provides value for the condition - * - Annotation variable is over 50 characters (Or 150 if description) - * - Method name is over 50 characters (Used as an identifier for storage) - * - * @author Rsl1122 - * @see com.djrapitops.plan.extension.annotation.PluginInfo Required Annotation - * @see CallEvents for method call event types. - */ -public interface DataExtension { - - /** - * Determines when DataExtension methods are called automatically by Plan. - *

- * Override this method to determine more suitable call times for your plugin. - * You can also use {@link Caller} to update manually. - *

- * If an empty array is supplied the DataExtension methods are not called by Plan automatically. - * - * @return Event types that will trigger method calls to the DataExtension. - * @see CallEvents for details when the methods are called. - */ - default CallEvents[] callExtensionMethodsOn() { - return new CallEvents[]{ - CallEvents.PLAYER_JOIN, - CallEvents.PLAYER_LEAVE, - CallEvents.SERVER_EXTENSION_REGISTER - }; - } - -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/ElementOrder.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/ElementOrder.java deleted file mode 100644 index f4d3fd634..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/ElementOrder.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -import java.util.ArrayList; -import java.util.List; - -/** - * Enum representing big elements of a plugin. - *

- * Used for determining in which order elements are placed on a {@link com.djrapitops.plan.extension.annotation.Tab} by - * using {@link com.djrapitops.plan.extension.annotation.TabInfo}. - * - * @author Rsl1122 - */ -public enum ElementOrder { - /** - * Represents text - value pair box. - */ - VALUES, - /** - * Represents graphs. - */ - GRAPH, - /** - * Represents tables. - */ - TABLE; - - public static String serialize(ElementOrder[] order) { - StringBuilder builder = new StringBuilder(); - - int length = order.length; - for (int i = 0; i < length; i++) { - builder.append(order[i].name()); - if (i < length - 1) { - builder.append(','); - } - } - - return builder.toString(); - } - - public static ElementOrder[] deserialize(String serializedOrder) { - if (serializedOrder == null || serializedOrder.isEmpty()) { - return null; - } - - String[] split = serializedOrder.split(","); - - List order = new ArrayList<>(); - for (String elementName : split) { - try { - ElementOrder element = valueOf(elementName); - order.add(element); - } catch (IllegalArgumentException ignore) { - /* Has been deleted */ - } - } - - return order.toArray(new ElementOrder[0]); - } -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/ExtensionService.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/ExtensionService.java deleted file mode 100644 index c40b27442..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/ExtensionService.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -import com.djrapitops.plan.extension.extractor.ExtensionExtractor; - -import java.util.Optional; - -/** - * Interface for registering {@link DataExtension}s. - *

- * Obtaining instance: - * - Obtain instance with {@link ExtensionService#getInstance()}. - * - Make sure to catch a possible NoClassDefFoundError in case Plan is not installed - * - Catch IllegalStateException in case ExtensionService is not enabled - *

- * Registering {@link DataExtension}: - * - Register your {@link DataExtension} with {@link ExtensionService#register(DataExtension)} - * - Catch a possible IllegalArgumentException in case the DataExtension implementation is invalid. - * - * @author Rsl1122 - */ -public interface ExtensionService { - - /** - * Obtain instance of ExtensionService. - * - * @return ExtensionService implementation. - * @throws NoClassDefFoundError If Plan is not installed and this class can not be found or if older Plan version is installed. - * @throws IllegalStateException If Plan is installed, but not enabled. - */ - static ExtensionService getInstance() { - return Optional.ofNullable(ExtensionServiceHolder.service) - .orElseThrow(() -> new IllegalStateException("ExtensionService has not been initialised yet.")); - } - - /** - * Register your {@link DataExtension} implementation. - *

- * You can use {@link ExtensionExtractor#validateAnnotations()} in your Unit Tests to prevent IllegalArgumentExceptions here at runtime. - * - * @param extension Your DataExtension implementation, see {@link DataExtension} for requirements. - * @return Optional {@link Caller} that can be used to call for data update in Plan database manually - If the Optional is not present the user has disabled the extension in Plan config. - * @throws IllegalArgumentException If an implementation violation is found. - */ - Optional register(DataExtension extension); - - /** - * Unregister your {@link DataExtension} implementation. - *

- * This method should be used if calling methods on the DataExtension suddenly becomes unavailable, due to - * plugin disable for example. - * - * @param extension Your DataExtension implementation that was registered before. - */ - void unregister(DataExtension extension); - - class ExtensionServiceHolder { - static ExtensionService service; - - private ExtensionServiceHolder() { - /* Static variable holder */ - } - - static void set(ExtensionService service) { - ExtensionServiceHolder.service = service; - } - } - -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/FormatType.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/FormatType.java deleted file mode 100644 index ca59cfda9..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/FormatType.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -import java.util.Optional; - -/** - * Enum for determining additional formatter for a value given by a {@link com.djrapitops.plan.extension.annotation.NumberProvider}. - * - * @author Rsl1122 - */ -public enum FormatType { - - /** - * Formats a long value (Epoch ms) to a readable timestamp, year is important. - */ - DATE_YEAR, - /** - * Formats a long value (Epoch ms) to a readable timestamp, second is important. - */ - DATE_SECOND, - /** - * Formats a long value (ms) to a readable format. - */ - TIME_MILLISECONDS, - /** - * Applies no formatting to the value. - */ - NONE; - - public static Optional getByName(String name) { - if (name == null) { - return Optional.empty(); - } - try { - return Optional.of(valueOf(name)); - } catch (IllegalArgumentException e) { - return Optional.empty(); - } - }} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/Group.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/Group.java deleted file mode 100644 index 2d9c35fb7..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/Group.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -/** - * Method parameter for providing values about a group with provider annotations. - *

- * Usage Example: {@code @StringProvider String provideStringAboutGroup(Group group)} - *

- * Group names of users are provided with {@code @GroupProvider String[] provideGroups(UUID playerUUID)} - * {@code Group} parameter methods are not called without knowledge of a group name. - *

- * This method parameter is used since it is not possible to differentiate String playerName and String groupName. - * - * @author Rsl1122 - */ -public interface Group { - - String getGroupName(); - -} \ No newline at end of file diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/NotReadyException.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/NotReadyException.java deleted file mode 100644 index 22f3b34ea..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/NotReadyException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -/** - * Exception to throw inside DataExtension if a method is not ready to be called (Data is not available etc). - *

- * This Exception will not cause Plan to "yell" about the exception. - *

- * Requires Capability#DATA_EXTENSION_NOT_READY_EXCEPTION. - * - * @author Rsl1122 - */ -public class NotReadyException extends IllegalStateException { - - /** - * Construct the exception. - *

- * The Exception is not logged (Fails silently) so no message is available. - */ - public NotReadyException() { - } -} \ No newline at end of file diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/BooleanProvider.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/BooleanProvider.java deleted file mode 100644 index 8eb5d2da5..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/BooleanProvider.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Method annotation to provide a boolean value about a Player. - *

- * Usage: {@code @BooleanProvider boolean method(UUID playerUUID)} - *

- * The provided boolean can be used as a condition for calls to other Provider - * methods by defining the name of the condition and using {@link Conditional} - * on the other method with a Provider annotation. - *

- * For example: - * {@code @BooleanProvider(condition="example") boolean condition(UUID playerUUID);} - * {@code @Conditional("example") @NumberProvider long someValue(UUID playerUUID);} - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface BooleanProvider { - - /** - * Text displayed before the value, limited to 50 characters. - *

- * Should inform the user what the value represents, for example - * "Banned", "Has Island" - * - * @return String of max 50 characters, remainder will be clipped. - */ - String text(); - - /** - * Display-priority of the value, highest value is placed top most. - *

- * Two values with same priority may appear in a random order. - * - * @return Priority between 0 and {@code Integer.MAX_VALUE}. - */ - int priority() default 0; - - /** - * Text displayed when hovering over the value, limited to 150 characters. - *

- * Should be used to clarify what the value is if not self evident, for example - * text: "Boat", description: "Whether or not the player is on a boat." - * - * @return String of max 150 characters, remainder will be clipped. - */ - String description() default ""; - - /** - * Name of the {@link Conditional} condition limited to 50 characters. - * - * @return Case sensitive string of max 50 characters. - */ - String conditionName() default ""; - - /** - * Should the result of this method be hidden from the user. - * - * @return true if the value should not be displayed on the page. - */ - boolean hidden() default false; - - /** - * Name of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Name of the icon, if name is not valid no icon is shown. - */ - String iconName() default "question"; - - /** - * Family of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Family that matches an icon, if there is no icon for this family no icon is shown. - */ - Family iconFamily() default Family.SOLID; - - /** - * Color preference of the plugin. - *

- * This color will be set as the default color to use for plugin's elements. - * - * @return Preferred color. If none are specified defaults are used. - */ - Color iconColor() default Color.NONE; - - /** - * When the parameter is set to {@code true} the value from this Provider is shown on a table alongside players. - *

- * If {@link BooleanProvider#hidden()} is {@code true} then this value will not be shown in the table regardless of the value of this parameter. - * - * @return false by default. - */ - boolean showInPlayerTable() default false; -} \ No newline at end of file diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/Conditional.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/Conditional.java deleted file mode 100644 index ecc87b070..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/Conditional.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Method Annotation to determine that a method can not be called unless a condition is fulfilled. - *

- * Condition information is provided with {@link com.djrapitops.plan.extension.annotation.BooleanProvider}. - * If {@link com.djrapitops.plan.extension.annotation.BooleanProvider} for the condition is not specified the - * method tagged with this annotation will not be called, (Condition is assumed false). - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface Conditional { - - /** - * Name of the condition limited to 50 characters. - * - * @return Case sensitive string of max 50 characters. - */ - String value(); - - /** - * Reverse the condition. - *

- * Example: - * - Method with {@code Conditional("expires", negated = true)} will only be called when the condition "expires" is false. - * - * @return {@code false} by default. - */ - boolean negated() default false; - -} \ No newline at end of file diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/DoubleProvider.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/DoubleProvider.java deleted file mode 100644 index df004701e..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/DoubleProvider.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Method annotation to provide a double value about a Player. - *

- * Usage: {@code @DoubleProvider double method(UUID playerUUID)} - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface DoubleProvider { - - /** - * Text displayed before the value, limited to 50 characters. - *

- * Should inform the user what the value represents, for example - * "Distance from spawn", "Balance" - * - * @return String of max 50 characters, remainder will be clipped. - */ - String text(); - - /** - * Display-priority of the value, highest value is placed top most. - *

- * Two values with same priority may appear in a random order. - * - * @return Priority between 0 and {@code Integer.MAX_VALUE}. - */ - int priority() default 0; - - /** - * Text displayed when hovering over the value, limited to 150 characters. - *

- * Should be used to clarify what the value is if not self evident, for example - * text: "Balance", description: "Economy balance of the player" - * - * @return String of max 150 characters, remainder will be clipped. - */ - String description() default ""; - - /** - * Name of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Name of the icon, if name is not valid no icon is shown. - */ - String iconName() default "question"; - - /** - * Family of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Family that matches an icon, if there is no icon for this family no icon is shown. - */ - Family iconFamily() default Family.SOLID; - - /** - * Color preference of the plugin. - *

- * This color will be set as the default color to use for plugin's elements. - * - * @return Preferred color. If none are specified defaults are used. - */ - Color iconColor() default Color.NONE; - - /** - * When the parameter is set to {@code true} the value from this Provider is shown on a table alongside players. - * - * @return false by default. - */ - boolean showInPlayerTable() default false; -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/InvalidateMethod.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/InvalidateMethod.java deleted file mode 100644 index ca10a9f42..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/InvalidateMethod.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import java.lang.annotation.*; - -/** - * Annotation used to invalidate old method values. - *

- * The name of the methods are used as an identifier in the database, so that a single provider does not duplicate entries. - * Only first 50 characters of the method name are stored. - * If you need to change a method name add this class annotation with the old method name. - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Repeatable(InvalidateMethod.Multiple.class) -public @interface InvalidateMethod { - - /** - * Name of the old method, values of which should be removed from the database. - * - * @return Name of the old method, case sensitive. Only first 50 characters are used. - */ - String value(); - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - @interface Multiple { - - InvalidateMethod[] value(); - - } - -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/NumberProvider.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/NumberProvider.java deleted file mode 100644 index 6f1a57e1d..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/NumberProvider.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Method annotation to provide a long (64bit number) value about a Player. - *

- * If you want to return int values, use this provider with a long as - * return type of the method. - *

- * Usage: {@code @NumberProvider long method(UUID playerUUID)} - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface NumberProvider { - - /** - * Text displayed before the value, limited to 50 characters. - *

- * Should inform the user what the value represents, for example - * "Owned Chickens", "Claimed Blocks" - * - * @return String of max 50 characters, remainder will be clipped. - */ - String text(); - - /** - * Display-priority of the value, highest value is placed top most. - *

- * Two values with same priority may appear in a random order. - * - * @return Priority between 0 and {@code Integer.MAX_VALUE}. - */ - int priority() default 0; - - /** - * Text displayed when hovering over the value, limited to 150 characters. - *

- * Should be used to clarify what the value is if not self evident, for example - * text: "Fished", description: "How long the player has fished for" - * - * @return String of max 150 characters, remainder will be clipped. - */ - String description() default ""; - - /** - * Apply special formatting to the value before presentation. - * - * @return {@link FormatType} that best represents the long value. - * @see FormatType for available formatters. - */ - FormatType format() default FormatType.NONE; - - /** - * Name of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Name of the icon, if name is not valid no icon is shown. - */ - String iconName() default "question"; - - /** - * Family of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Family that matches an icon, if there is no icon for this family no icon is shown. - */ - Family iconFamily() default Family.SOLID; - - /** - * Color preference of the plugin. - *

- * This color will be set as the default color to use for plugin's elements. - * - * @return Preferred color. If none are specified defaults are used. - */ - Color iconColor() default Color.NONE; - - /** - * When the parameter is set to {@code true} the value from this Provider is shown on a table alongside players. - * - * @return false by default. - */ - boolean showInPlayerTable() default false; -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/PercentageProvider.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/PercentageProvider.java deleted file mode 100644 index 68da86301..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/PercentageProvider.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Method annotation to provide a double (Percentage) about a Player. - *

- * Usage: {@code @PercentageProvider double method(UUID playerUUID)} - *

- * The returned value should be between (or one of) 0.0 (0%) and 1.0 (100%). - * Other values will be ignored. - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface PercentageProvider { - - /** - * Text displayed before the value, limited to 50 characters. - *

- * Should inform the user what the value represents, for example - * "Health", "Power" - * - * @return String of max 50 characters, remainder will be clipped. - */ - String text(); - - /** - * Display-priority of the value, highest value is placed top most. - *

- * Two values with same priority may appear in a random order. - * - * @return Priority between 0 and {@code Integer.MAX_VALUE}. - */ - int priority() default 0; - - /** - * Text displayed when hovering over the value, limited to 150 characters. - *

- * Should be used to clarify what the value is if not self evident, for example - * text: "Power", description: "Faction power, affects ability of faction to perform actions. Regenerates" - * - * @return String of max 150 characters, remainder will be clipped. - */ - String description() default ""; - - /** - * Name of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Name of the icon, if name is not valid no icon is shown. - */ - String iconName() default "question"; - - /** - * Family of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Family that matches an icon, if there is no icon for this family no icon is shown. - */ - Family iconFamily() default Family.SOLID; - - /** - * Color preference of the plugin. - *

- * This color will be set as the default color to use for plugin's elements. - * - * @return Preferred color. If none are specified defaults are used. - */ - Color iconColor() default Color.NONE; - - /** - * When the parameter is set to {@code true} the value from this Provider is shown on a table alongside players. - * - * @return false by default. - */ - boolean showInPlayerTable() default false; -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/PluginInfo.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/PluginInfo.java deleted file mode 100644 index 908380921..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/PluginInfo.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Class Annotation for informing Plan about a plugin. - * - * @author Rsl1122 - * @see TabOrder to determine preferred tab ordering if you use {@link Tab}s. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface PluginInfo { - - /** - * Name of the plugin, limited to 50 characters. - * - * @return String of max 50 characters, remainder will be clipped. - */ - String name(); - - /** - * Name of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Name of the icon, if name is not valid no icon is shown. - */ - String iconName() default "cube"; - - /** - * Family of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Family that matches an icon, if there is no icon for this family no icon is shown. - */ - Family iconFamily() default Family.SOLID; - - /** - * Color preference of the plugin. - *

- * This color will be set as the default color to use for plugin's elements. - * - * @return Preferred color. If none are specified defaults are used. - */ - Color color() default Color.NONE; -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/StringProvider.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/StringProvider.java deleted file mode 100644 index 6b0cfd7d7..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/StringProvider.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Method annotation to provide a String value about a Player. - *

- * Usage: {@code @StringProvider String method(UUID playerUUID)} - *

- * The returned value is limited to 100 characters, remainder will be clipped. - *

- * If the value is a player name, provide value for playerName=true. - * This will allow linking between pages. - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface StringProvider { - - /** - * Text displayed before the value, limited to 50 characters. - *

- * Should inform the user what the value represents, for example - * "Town Name", "Pet Name" - * - * @return String of max 50 characters, remainder will be clipped. - */ - String text(); - - /** - * Display-priority of the value, highest value is placed top most. - *

- * Two values with same priority may appear in a random order. - * - * @return Priority between 0 and {@code Integer.MAX_VALUE}. - */ - int priority() default 0; - - /** - * Text displayed when hovering over the value, limited to 150 characters. - *

- * Should be used to clarify what the value is if not self evident, for example - * text: "Power", description: "Faction power, affects ability of faction to perform actions. Regenerates" - * - * @return String of max 150 characters, remainder will be clipped. - */ - String description() default ""; - - /** - * Determine if this value represents a Player name, for example a mayor of a town. - * - * @return {@code true} if the name can be used as a link to another player's page. - */ - boolean playerName() default false; - - /** - * Name of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Name of the icon, if name is not valid no icon is shown. - */ - String iconName() default "question"; - - /** - * Family of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Family that matches an icon, if there is no icon for this family no icon is shown. - */ - Family iconFamily() default Family.SOLID; - - /** - * Color preference of the plugin. - *

- * This color will be set as the default color to use for plugin's elements. - * - * @return Preferred color. If none are specified defaults are used. - */ - Color iconColor() default Color.NONE; - - /** - * When the parameter is set to {@code true} the value from this Provider is shown on a table alongside players. - * - * @return false by default. - */ - boolean showInPlayerTable() default false; -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/Tab.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/Tab.java deleted file mode 100644 index 5b61c9d6e..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/Tab.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Method Annotation for determining Tab the given element should appear on. - *

- * If not specified Plan places the item on the default tab. - * - * @author Rsl1122 - * @see TabInfo if you want to determine an icon or element order for a Tab. - * @see TabOrder to determine preferred tab ordering if you use Tabs. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface Tab { - - /** - * Name of the tab to place this item on. - * - * @return Tab name, limited to 50 characters. - */ - String value(); - -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TabInfo.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TabInfo.java deleted file mode 100644 index d0b555f6f..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TabInfo.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.icon.Family; - -import java.lang.annotation.*; - -/** - * Class Annotation that allows determining an Icon and {@link ElementOrder} of a tab. - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Repeatable(TabInfo.Multiple.class) -public @interface TabInfo { - - /** - * Name of the tab this information is about. - * - * @return Tab name, limited to 50 characters. - */ - String tab(); - - /** - * Name of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Name of the icon, if name is not valid no icon is shown. - */ - String iconName() default "circle"; - - /** - * Family of Font Awesome icon. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @return Family that matches an icon, if there is no icon for this family no icon is shown. - */ - Family iconFamily() default Family.SOLID; - - /** - * Order preference for the large elements of a tab. - *

- * If an ordering is not present they will be added to the end in the default order. - * If a duplicate ordering exists only the first will be used for determining the order. - * - * @return ElementOrders in the order that they want to be displayed in. - */ - ElementOrder[] elementOrder(); - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - @interface Multiple { - TabInfo[] value(); - } -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TabOrder.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TabOrder.java deleted file mode 100644 index b934a7a41..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TabOrder.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Class Annotation for informing Plan about plugin's tab order preference. - *

- * If tab order is not defined alphabetical order is used. - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface TabOrder { - - /** - * Order preference of different {@link Tab}s. - *

- * If a tab is defined that is not present it is ignored. - * If a tab is not defined but is present alphabetical order is used. - * - * @return Names of the defined tabs (case sensitive). - */ - String[] value(); - -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TableProvider.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TableProvider.java deleted file mode 100644 index 1a8f69936..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/annotation/TableProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.annotation; - -import com.djrapitops.plan.extension.icon.Color; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Method annotation to provide a Table. - *

- * Usage: {@code @TableProvider Table method(UUID playerUUID)} - *

- * Tables about players can have up to 4 columns. - * Tables about server can have up to 5 columns. - *

- * It is recommended to place each table on their own tab with a {@link Tab} annotation on the same method. - * - * @author Rsl1122 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface TableProvider { - - /** - * Determine the color of the table header. - * - * @return Preferred color. If none are specified defaults are used. - */ - Color tableColor() default Color.NONE; - -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/extractor/ExtensionExtractor.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/extractor/ExtensionExtractor.java deleted file mode 100644 index 90c9a924d..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/extractor/ExtensionExtractor.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.extractor; - -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.Group; -import com.djrapitops.plan.extension.annotation.*; -import com.djrapitops.plan.extension.table.Table; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.*; -import java.util.stream.Collectors; - -/** - * Implementation detail, for extracting methods from {@link com.djrapitops.plan.extension.DataExtension}. - *

- * This class can be used for testing validity of annotation implementations - * in your unit tests to avoid runtime errors. {@link ExtensionExtractor#validateAnnotations()} - * - * @author Rsl1122 - */ -public final class ExtensionExtractor { - - private final DataExtension extension; - private final String extensionName; - - private final List warnings = new ArrayList<>(); - - private PluginInfo pluginInfo; - private TabOrder tabOrder; - private List tabInformation; - private List invalidMethods; - private MethodAnnotations methodAnnotations; - - private static final String WAS_OVER_50_CHARACTERS = "' was over 50 characters."; - - public ExtensionExtractor(DataExtension extension) { - this.extension = extension; - extensionName = extension.getClass().getSimpleName(); - } - - /** - * Use this method in an unit test to validate your DataExtension. - * - * @throws IllegalArgumentException If an implementation error is found. - */ - public void validateAnnotations() { - extractAnnotationInformation(); - - if (!warnings.isEmpty()) { - throw new IllegalArgumentException("Warnings: " + warnings.toString()); - } - } - - private Optional getClassAnnotation(Class ofClass) { - return Optional.ofNullable(extension.getClass().getAnnotation(ofClass)); - } - - private Method[] getMethods() { - return extension.getClass().getMethods(); - } - - public void extractAnnotationInformation() { - extractPluginInfo(); - extractInvalidMethods(); - - extractMethodAnnotations(); - validateMethodAnnotations(); - - validateConditionals(); - - extractTabInfo(); - } - - private void extractMethodAnnotations() { - methodAnnotations = new MethodAnnotations(); - - for (Method method : getMethods()) { - int modifiers = method.getModifiers(); - if (!Modifier.isPublic(modifiers) - || Modifier.isStatic(modifiers)) { - continue; - } - - MethodAnnotations.get(method, BooleanProvider.class).ifPresent(annotation -> methodAnnotations.put(method, BooleanProvider.class, annotation)); - MethodAnnotations.get(method, NumberProvider.class).ifPresent(annotation -> methodAnnotations.put(method, NumberProvider.class, annotation)); - MethodAnnotations.get(method, DoubleProvider.class).ifPresent(annotation -> methodAnnotations.put(method, DoubleProvider.class, annotation)); - MethodAnnotations.get(method, PercentageProvider.class).ifPresent(annotation -> methodAnnotations.put(method, PercentageProvider.class, annotation)); - MethodAnnotations.get(method, StringProvider.class).ifPresent(annotation -> methodAnnotations.put(method, StringProvider.class, annotation)); - - MethodAnnotations.get(method, Conditional.class).ifPresent(annotation -> methodAnnotations.put(method, Conditional.class, annotation)); - MethodAnnotations.get(method, Tab.class).ifPresent(annotation -> methodAnnotations.put(method, Tab.class, annotation)); - - MethodAnnotations.get(method, TableProvider.class).ifPresent(annotation -> methodAnnotations.put(method, TableProvider.class, annotation)); - } - - if (methodAnnotations.isEmpty()) { - throw new IllegalArgumentException(extensionName + " class had no methods annotated with a Provider annotation"); - } - } - - private void validateReturnType(Method method, Class expectedType) { - Class returnType = method.getReturnType(); - if (!expectedType.isAssignableFrom(returnType)) { - throw new IllegalArgumentException(extensionName + "." + method.getName() + " has invalid return type. was: " + returnType.getName() + ", expected: " + expectedType.getName()); - } - } - - private void validateMethodAnnotationPropertyLength(String property, String name, int maxLength, Method method) { - if (property.length() > maxLength) { - warnings.add(extensionName + "." + method.getName() + " '" + name + WAS_OVER_50_CHARACTERS); - } - } - - private void validateMethodArguments(Method method, boolean parameterIsRequired, Class... parameterOptions) { - Class[] parameterTypes = method.getParameterTypes(); - - // Possible parameters for the methods: - // UUID playerUUID, String playerName, Group group, none - - int parameters = parameterTypes.length; - - if (parameterIsRequired && parameters == 0) { - // Does not have parameters, but one is required - throw new IllegalArgumentException(extensionName + "." + method.getName() + " requires one of " + Arrays.toString(parameterOptions) + " as a parameter."); - } else if (parameters == 0) { - // Has no parameters & it is acceptable. - return; - } - - if (parameters > 1) { - // Has too many parameters - throw new IllegalArgumentException(extensionName + "." + method.getName() + " has too many parameters, only one of " + Arrays.toString(parameterOptions) + " is required as a parameter."); - } - - Class methodParameter = parameterTypes[0]; - - boolean validParameter = false; - for (Class option : parameterOptions) { - if (option.equals(methodParameter)) { - validParameter = true; - } - } - - if (!validParameter) { - // Has invalid parameter - throw new IllegalArgumentException(extensionName + "." + method.getName() + " has invalid parameter: '" + methodParameter.getName() + "' one of " + Arrays.toString(parameterOptions) + " is required as a parameter."); - } - // Has valid parameter & it is acceptable. - } - - private void validateMethodAnnotations() { - validateBooleanProviderAnnotations(); - validateNumberProviderAnnotations(); - validateDoubleProviderAnnotations(); - validatePercentageProviderAnnotations(); - validateStringProviderAnnotations(); - validateTableProviderAnnotations(); - } - - private void validateBooleanProviderAnnotations() { - for (Map.Entry booleanProvider : methodAnnotations.getMethodAnnotations(BooleanProvider.class).entrySet()) { - Method method = booleanProvider.getKey(); - BooleanProvider annotation = booleanProvider.getValue(); - - validateReturnType(method, boolean.class); - validateMethodAnnotationPropertyLength(annotation.text(), "text", 50, method); - validateMethodAnnotationPropertyLength(annotation.description(), "description", 150, method); - validateMethodAnnotationPropertyLength(annotation.conditionName(), "conditionName", 50, method); - validateMethodArguments(method, false, UUID.class, String.class, Group.class); - - String condition = MethodAnnotations.get(method, Conditional.class).map(Conditional::value).orElse(null); - if (annotation.conditionName().equals(condition)) { - warnings.add(extensionName + "." + method.getName() + " can not be conditional of itself. required condition: " + condition + ", provided condition: " + annotation.conditionName()); - } - - if (annotation.conditionName().isEmpty() && annotation.hidden()) { - throw new IllegalArgumentException(extensionName + "." + method.getName() + " can not be 'hidden' without a 'conditionName'"); - } - } - } - - private void validateNumberProviderAnnotations() { - for (Map.Entry numberProvider : methodAnnotations.getMethodAnnotations(NumberProvider.class).entrySet()) { - Method method = numberProvider.getKey(); - NumberProvider annotation = numberProvider.getValue(); - - validateReturnType(method, long.class); - validateMethodAnnotationPropertyLength(annotation.text(), "text", 50, method); - validateMethodAnnotationPropertyLength(annotation.description(), "description", 150, method); - validateMethodArguments(method, false, UUID.class, String.class, Group.class); - } - } - - private void validateDoubleProviderAnnotations() { - for (Map.Entry numberProvider : methodAnnotations.getMethodAnnotations(DoubleProvider.class).entrySet()) { - Method method = numberProvider.getKey(); - DoubleProvider annotation = numberProvider.getValue(); - - validateReturnType(method, double.class); - validateMethodAnnotationPropertyLength(annotation.text(), "text", 50, method); - validateMethodAnnotationPropertyLength(annotation.description(), "description", 150, method); - validateMethodArguments(method, false, UUID.class, String.class, Group.class); - } - } - - private void validatePercentageProviderAnnotations() { - for (Map.Entry numberProvider : methodAnnotations.getMethodAnnotations(PercentageProvider.class).entrySet()) { - Method method = numberProvider.getKey(); - PercentageProvider annotation = numberProvider.getValue(); - - validateReturnType(method, double.class); - validateMethodAnnotationPropertyLength(annotation.text(), "text", 50, method); - validateMethodAnnotationPropertyLength(annotation.description(), "description", 150, method); - validateMethodArguments(method, false, UUID.class, String.class, Group.class); - } - } - - private void validateStringProviderAnnotations() { - for (Map.Entry numberProvider : methodAnnotations.getMethodAnnotations(StringProvider.class).entrySet()) { - Method method = numberProvider.getKey(); - StringProvider annotation = numberProvider.getValue(); - - validateReturnType(method, String.class); - validateMethodAnnotationPropertyLength(annotation.text(), "text", 50, method); - validateMethodAnnotationPropertyLength(annotation.description(), "description", 150, method); - validateMethodArguments(method, false, UUID.class, String.class, Group.class); - } - } - - private void validateTableProviderAnnotations() { - for (Method method : methodAnnotations.getMethodAnnotations(TableProvider.class).keySet()) { - validateReturnType(method, Table.class); - validateMethodArguments(method, false, UUID.class, String.class, Group.class); - } - } - - private void validateConditionals() { - Collection conditionals = methodAnnotations.getAnnotations(Conditional.class); - Collection conditionProviders = methodAnnotations.getAnnotations(BooleanProvider.class); - - Set providedConditions = conditionProviders.stream().map(BooleanProvider::conditionName).collect(Collectors.toSet()); - - for (Conditional condition : conditionals) { - String conditionName = condition.value(); - - if (conditionName.length() > 50) { - warnings.add(extensionName + ": '" + conditionName + "' conditionName was over 50 characters."); - } - - if (!providedConditions.contains(conditionName)) { - warnings.add(extensionName + ": '" + conditionName + "' Condition was not provided by any BooleanProvider."); - } - } - - // Make sure that all methods annotated with Conditional have a Provider annotation - Collection conditionalMethods = methodAnnotations.getMethodAnnotations(Conditional.class).keySet(); - for (Method conditionalMethod : conditionalMethods) { - if (!MethodAnnotations.hasAnyOf(conditionalMethod, - BooleanProvider.class, DoubleProvider.class, NumberProvider.class, - PercentageProvider.class, StringProvider.class - )) { - throw new IllegalArgumentException(extensionName + "." + conditionalMethod.getName() + " did not have any associated Provider for Conditional."); - } - } - } - - private void extractPluginInfo() { - pluginInfo = getClassAnnotation(PluginInfo.class).orElseThrow(() -> new IllegalArgumentException("Given class had no PluginInfo annotation")); - - if (pluginInfo.name().length() > 50) { - warnings.add(extensionName + " PluginInfo 'name' was over 50 characters."); - } - } - - private void extractTabInfo() { - tabInformation = new ArrayList<>(); - getClassAnnotation(TabInfo.Multiple.class).ifPresent(tabs -> { - for (TabInfo tabInfo : tabs.value()) { - String tabName = tabInfo.tab(); - - // Length restriction check - if (tabName.length() > 50) { - warnings.add(extensionName + " tabName '" + tabName + WAS_OVER_50_CHARACTERS); - } - - tabInformation.add(tabInfo); - } - }); - - tabOrder = getClassAnnotation(TabOrder.class).orElse(null); - - Map tabs = this.methodAnnotations.getMethodAnnotations(Tab.class); - Set tabNames = tabs.values().stream().map(Tab::value).collect(Collectors.toSet()); - - // Check for unused TabInfo annotations - for (TabInfo tabInfo : tabInformation) { - String tabName = tabInfo.tab(); - - if (tabName.length() > 50) { - warnings.add(extensionName + " TabInfo " + tabName + " name was over 50 characters."); - } - - if (!tabNames.contains(tabName)) { - warnings.add(extensionName + " has TabInfo for " + tabName + ", but it is not used."); - } - } - - // Check Tab name lengths - for (Map.Entry tab : tabs.entrySet()) { - String tabName = tab.getValue().value(); - if (tabName.length() > 50) { - warnings.add(extensionName + "." + tab.getKey().getName() + " Tab '" + tabName + "' name was over 50 characters."); - } - } - } - - private void extractInvalidMethods() { - invalidMethods = new ArrayList<>(); - getClassAnnotation(InvalidateMethod.Multiple.class).ifPresent(tabs -> { - for (InvalidateMethod tabInfo : tabs.value()) { - String methodName = tabInfo.value(); - - // Length restriction check - if (methodName.length() > 50) { - warnings.add(extensionName + " invalidated method '" + methodName + WAS_OVER_50_CHARACTERS); - } - - invalidMethods.add(tabInfo); - } - }); - } - - public List getWarnings() { - return warnings; - } - - public PluginInfo getPluginInfo() { - return pluginInfo; - } - - public Optional getTabOrder() { - return Optional.ofNullable(tabOrder); - } - - public List getTabInformation() { - return tabInformation != null ? tabInformation : Collections.emptyList(); - } - - public MethodAnnotations getMethodAnnotations() { - return methodAnnotations; - } - - public List getInvalidateMethodAnnotations() { - return invalidMethods != null ? invalidMethods : Collections.emptyList(); - } -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/extractor/MethodAnnotations.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/extractor/MethodAnnotations.java deleted file mode 100644 index 4b854ab15..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/extractor/MethodAnnotations.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.extractor; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -/** - * Implementation detail, utility class for handling method annotations. - * - * @author Rsl1122 - */ -public class MethodAnnotations { - - private final Map> byAnnotationType; - - public MethodAnnotations() { - byAnnotationType = new HashMap<>(); - } - - public static boolean hasAnyOf(Method method, Class... annotationClasses) { - for (Annotation annotation : method.getAnnotations()) { - for (Class annotationClass : annotationClasses) { - if (annotationClass.isAssignableFrom(annotation.getClass())) { - return true; - } - } - } - return false; - } - - public static Optional get(Method from, Class ofClass) { - return Optional.ofNullable(from.getAnnotation(ofClass)); - } - - public void put(Method method, Class annotationClass, T annotation) { - Map methods = byAnnotationType.getOrDefault(annotationClass, new HashMap<>()); - methods.put(method, annotation); - byAnnotationType.put(annotationClass, methods); - } - - public Map getMethodAnnotations(Class ofType) { - return (Map) byAnnotationType.getOrDefault(ofType, new HashMap<>()); - } - - public Collection getAnnotations(Class ofType) { - return getMethodAnnotations(ofType).values(); - } - - public boolean isEmpty() { - return byAnnotationType.isEmpty(); - } - - @Override - public String toString() { - return "MethodAnnotations{" + byAnnotationType + '}'; - } -} \ No newline at end of file diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Color.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Color.java deleted file mode 100644 index 58f9296fb..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Color.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.icon; - -import java.util.Optional; - -/** - * Enum to determine what color to use for some element. - * - * @author Rsl1122 - */ -public enum Color { - - RED, - PINK, - PURPLE, - DEEP_PURPLE, - INDIGO, - BLUE, - LIGHT_BLUE, - CYAN, - TEAL, - GREEN, - LIGHT_GREEN, - LIME, - YELLOW, - AMBER, - ORANGE, - DEEP_ORANGE, - BROWN, - GREY, - BLUE_GREY, - BLACK, - NONE; - - public static Optional getByName(String name) { - if (name == null) { - return Optional.empty(); - } - try { - return Optional.of(valueOf(name)); - } catch (IllegalArgumentException e) { - return Optional.empty(); - } - }} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Family.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Family.java deleted file mode 100644 index 0125d6ee9..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Family.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.icon; - -import java.util.Optional; - -/** - * Enum to determine font-awesome icon family. - * - * @author Rsl1122 - */ -public enum Family { - SOLID, - REGULAR, - BRAND; - - public static Optional getByName(String name) { - if (name == null) { - return Optional.empty(); - } - try { - return Optional.of(valueOf(name)); - } catch (IllegalArgumentException e) { - return Optional.empty(); - } - } -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Icon.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Icon.java deleted file mode 100644 index 5fb858292..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/icon/Icon.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.icon; - -/** - * Object that represents an icon on the website. - *

- * See https://fontawesome.com/icons (select 'free')) for icons and their {@link Family}. - * - * @author Rsl1122 - */ -public class Icon { - - private Family type; - private String name; - private Color color; - - private Icon() { - type = Family.SOLID; - color = Color.NONE; - } - - public Icon(Family type, String name, Color color) { - this.type = type; - this.name = name; - this.color = color; - } - - public static Builder called(String name) { - return new Builder().called(name); - } - - public static Builder of(Family type) { - return new Builder().of(type); - } - - public static Builder of(Color color) { - return new Builder().of(color); - } - - public Family getFamily() { - return type; - } - - public String getName() { - return name; - } - - public Color getColor() { - return color; - } - - public Icon setColor(Color color) { - this.color = color; - return this; - } - - @Override - public String toString() { - return "Icon{" + type.name() + ", '" + name + '\'' + ", " + color.name() + '}'; - } - - public static class Builder { - - private final Icon icon; - - Builder() { - this.icon = new Icon(); - } - - public Builder called(String name) { - icon.name = name; - return this; - } - - public Builder of(Color color) { - icon.color = color; - return this; - } - - public Builder of(Family type) { - icon.type = type; - return this; - } - - public Icon build() { - if (icon.name == null) { - throw new IllegalStateException("'name' was not defined yet!"); - } - return icon; - } - } -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/extension/table/Table.java b/Plan/api/src/main/java/com/djrapitops/plan/extension/table/Table.java deleted file mode 100644 index b082fcf1c..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/extension/table/Table.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.table; - -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Icon; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Object for giving Plan table data. - *

- * Usage: {@code Table.builder().columnOne("columnName", new Icon(...)).addRow("Your", "Row", "Data").build()} - *

- * Tables about players can have up to 4 columns. - * Tables about server can have up to 5 columns. - *

- * Icon colors are ignored. - *

- * If a row has more values than the column limit, they are ignored. - * If a row has less values than table columns, a '-' is displayed to distinguish a missing value. - *

- * If a table has no columns or rows, it is ignored. - * - * @author Rsl1122 - * @see com.djrapitops.plan.extension.annotation.TableProvider for associated annotation. - */ -public final class Table { - - private final String[] columns; - private final Icon[] icons; - - private final List rows; - - private Table() { - /* Tables are constructed with the factory. */ - - columns = new String[5]; - icons = new Icon[5]; - rows = new ArrayList<>(); - } - - /** - * Create a new Table Factory. - * - * @return a new Table Factory. - */ - public static Table.Factory builder() { - return new Table.Factory(); - } - - public String[] getColumns() { - return columns; - } - - public int getMaxColumnSize() { - int columnCount = 0; - for (String column : columns) { - if (column == null) { - break; // Prevent having one null column between two columns - } - columnCount++; - } - return columnCount; - } - - public Icon[] getIcons() { - return icons; - } - - public List getRows() { - return rows; - } - - /** - * Factory for creating new {@link Table} objects. - */ - public static final class Factory { - - private final Table building; - - // These variable are related to implementation, and is used when the table is being fetched from the database. - Color color; // Table color is defined with TableProvider annotation. - String tableName; // tableName is defined by method name annotated by TableProvider. - String tabName; // Tab name is defined with Tab annotation - int tabPriority; // Tab priority is defined with TabOrder annotation - ElementOrder[] tabOrder; // Tab element order is defined with TabInfo annotation - Icon tabIcon; // Tab icon is defined with TabInfo annotation - - private Factory() { - building = new Table(); - } - - private Factory column(int indx, String columnName, Icon icon) { - building.columns[indx] = columnName; - building.icons[indx] = icon != null ? Icon.called(icon.getName()).of(icon.getFamily()).build() : Icon.called("question").build(); - return this; - } - - /** - * Set first column name and icon. - * - * @param columnName Name of the column. - * @param icon Icon of the column, color is ignored. - * @return Factory. - */ - public Factory columnOne(String columnName, Icon icon) { - return column(0, columnName, icon); - } - - /** - * Set second column name and icon. - * - * @param columnName Name of the column. - * @param icon Icon of the column, color is ignored. - * @return Factory. - */ - public Factory columnTwo(String columnName, Icon icon) { - return column(1, columnName, icon); - } - - /** - * Set third column name and icon. - * - * @param columnName Name of the column. - * @param icon Icon of the column, color is ignored. - * @return Factory. - */ - public Factory columnThree(String columnName, Icon icon) { - return column(2, columnName, icon); - } - - /** - * Set fourth column name and icon. - * - * @param columnName Name of the column. - * @param icon Icon of the column, color is ignored. - * @return Factory. - */ - public Factory columnFour(String columnName, Icon icon) { - return column(3, columnName, icon); - } - - /** - * Set fifth column name and icon. - * - * @param columnName Name of the column. - * @param icon Icon of the column, color is ignored. - * @return Factory. - */ - public Factory columnFive(String columnName, Icon icon) { - return column(4, columnName, icon); - } - - /** - * Add a row of values to the table. - * - * @param values One value per column you have defined, {@code Object#toString()} will be called on the objects. - * @return Factory. - * @throws IllegalArgumentException If given varargs for 'values' is null. - */ - public Factory addRow(Object... values) { - if (values == null) { - throw new IllegalArgumentException("'values' for Table#addRow can not be null!"); - } - - if (values.length == 0 || areAllValuesNull(values)) { - return this; // Ignore row when all values are null or no values are present. - } - - building.rows.add(Arrays.copyOf(values, 5)); - return this; - } - - private boolean areAllValuesNull(Object[] values) { - boolean allNull = true; - for (Object value : values) { - if (value != null) { - allNull = false; - break; - } - } - return allNull; - } - - /** - * Finish building the table. - * - * @return Finished Table object. - */ - public Table build() { - return building; - } - } - -} \ No newline at end of file diff --git a/Plan/api/src/main/java/com/djrapitops/plan/query/CommonQueries.java b/Plan/api/src/main/java/com/djrapitops/plan/query/CommonQueries.java deleted file mode 100644 index ceb2740b4..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/query/CommonQueries.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.query; - -import java.util.Optional; -import java.util.Set; -import java.util.UUID; - -/** - * Class that allows performing most commonly wanted queries. - *

- * This exists so that SQL does not necessarily need to be written. - * Obtain an instance from {@link QueryService}. - * - * @author Rsl1122 - */ -public interface CommonQueries { - - /** - * Fetch playtime of a player on a server. - *

- * Returns 0 for any non existing players or servers. - * - * @param playerUUID UUID of the player. - * @param serverUUID UUID of the Plan server. - * @param after Data after this Epoch ms should be fetched - * @param before Data before this Epoch ms should be fetched - * @return Milliseconds the player has played with the defined parameters. - */ - long fetchPlaytime(UUID playerUUID, UUID serverUUID, long after, long before); - - /** - * Fetch last seen Epoch ms for a player on a server. - * - * @param playerUUID UUID of the player. - * @param serverUUID UUID of the Plan server. - * @return Epoch ms the player was last seen, 0 if player has not played on server. - */ - long fetchLastSeen(UUID playerUUID, UUID serverUUID); - - Set fetchServerUUIDs(); - - Optional fetchUUIDOf(String playerName); - - Optional fetchNameOf(UUID playerUUID); - - boolean doesDBHaveTable(String table); - - boolean doesDBHaveTableColumn(String table, String column); -} diff --git a/Plan/api/src/main/java/com/djrapitops/plan/query/QueryService.java b/Plan/api/src/main/java/com/djrapitops/plan/query/QueryService.java deleted file mode 100644 index 76eee4f98..000000000 --- a/Plan/api/src/main/java/com/djrapitops/plan/query/QueryService.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.query; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.Future; -import java.util.function.Consumer; - -/** - * Service for Query API. - *

- * Requires Capability QUERY_API - * - * @author Rsl1122 - */ -public interface QueryService { - - /** - * Obtain instance of QueryService. - * - * @return QueryService implementation. - * @throws NoClassDefFoundError If Plan is not installed and this class can not be found or if older Plan version is installed. - * @throws IllegalStateException If Plan is installed, but not enabled. - */ - static QueryService getInstance() { - return Optional.ofNullable(QueryService.QueryServiceHolder.service) - .orElseThrow(() -> new IllegalStateException("QueryService has not been initialised yet.")); - } - - /** - * Get what kind of database is in use. - * - * @return H2, SQLITE or MYSQL - * @throws IllegalStateException If database has not been initialized (Plugin failed to enable) - */ - String getDBType(); - - /** - * Perform a query against Plan database. - *

- * Blocks thread until query is complete. - * - * @param sql SQL String to execute, can contain parameterized queries ({@code ?}). - * @param performQuery set your parameters to the PreparedStatement and execute the query, return results. - * @param Type of results. - * @return The object returned by {@code results}. - * @throws IllegalStateException If something goes wrong with the query. SQLException might be as cause. - */ - T query( - String sql, - ThrowingFunction performQuery - ) throws IllegalStateException; - - /** - * Execute SQL against Plan database. - *

- * Does not block thread, SQL is executed in a single transaction to the database. - *

- * Differs from {@link QueryService#query(String, ThrowingFunction)} in that no results are returned. - * - * @param sql SQL String to execute, can contain parameterized queries ({@code ?}). - * @param performStatement set your parameters to the PreparedStatement and execute the statement. - * @return A Future that tells when the transaction has completed. Blocks thread if Future#get is called. - * @throws IllegalStateException If something goes wrong with the query. SQLException might be as cause. - */ - Future execute( - String sql, - ThrowingConsumer performStatement - ) throws IllegalStateException; - - /** - * Used for getting notified about removal of player data. - *

- * SQL for removing this player's data should be executed when this occurs. - *

- * Example usage: - * {@code subscribeToPlayerRemoveEvent(playerUUID -> { do stuff })} - * - * @param eventListener Functional interface that is called on the event. - */ - void subscribeToPlayerRemoveEvent(Consumer eventListener); - - /** - * Used for getting notified about removal of ALL data. - *

- * SQL for removing all extra tables (and data) should be performed - *

- * Example usage: - * {@code subscribeDataClearEvent(() -> { do stuff })} - * - * @param eventListener Functional interface that is called on the event. - */ - void subscribeDataClearEvent(VoidFunction eventListener); - - /** - * Get the UUID of this server. - * - * @return Optinal of the server UUID, empty if server did not start properly. - */ - Optional getServerUUID(); - - /** - * Perform some commonly wanted queries. - * - * @return {@link CommonQueries} implementation. - * @throws IllegalStateException If database has not been initialized (Plugin failed to enable) - */ - CommonQueries getCommonQueries(); - - /** - * See https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html - */ - @FunctionalInterface - interface ThrowingConsumer { - void accept(T t) throws SQLException; - } - - /** - * See https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html - */ - @FunctionalInterface - interface ThrowingFunction { - R apply(T t) throws SQLException; - } - - /** - * See https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html - */ - @FunctionalInterface - interface VoidFunction { - void apply(); - } - - class QueryServiceHolder { - static QueryService service; - - private QueryServiceHolder() { - /* Static variable holder */ - } - - static void set(QueryService service) { - QueryService.QueryServiceHolder.service = service; - } - } - -} diff --git a/Plan/api/src/test/java/com/djrapitops/plan/extension/extractor/ExtensionExtractorTest.java b/Plan/api/src/test/java/com/djrapitops/plan/extension/extractor/ExtensionExtractorTest.java deleted file mode 100644 index c91bb62f8..000000000 --- a/Plan/api/src/test/java/com/djrapitops/plan/extension/extractor/ExtensionExtractorTest.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.extractor; - -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.annotation.*; -import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; - -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -/** - * Tests for different validations of ExtensionExtractor. - *

- * This Test class contains only INVALID implementations of the DataExtension API. - * - * @author Rsl1122 - */ -@RunWith(JUnitPlatform.class) -class ExtensionExtractorTest { - - @Test - void pluginInfoIsRequired() { - class Extension implements DataExtension {} - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Given class had no PluginInfo annotation", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void providerMethodsAreRequired() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension {} - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension class had no methods annotated with a Provider annotation", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void publicProviderMethodsAreRequired() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @BooleanProvider(text = "Banned") - private boolean method(UUID playerUUID) { - return false; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension class had no methods annotated with a Provider annotation", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void pluginInfoNameOver50Chars() { - @PluginInfo(name = "five five five five five five five five five five -") - class Extension implements DataExtension { - @BooleanProvider(text = "Required Provider") - public boolean method() { - return false; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Warnings: [Extension PluginInfo 'name' was over 50 characters.]", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void booleanProviderMustReturnBoolean() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @BooleanProvider(text = "Banned") - public String method(UUID playerUUID) { - return "false"; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method has invalid return type. was: java.lang.String, expected: boolean", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void booleanProviderMustReturnPrimitiveBoolean() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @BooleanProvider(text = "Banned") - public Boolean method(UUID playerUUID) { - return null; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method has invalid return type. was: java.lang.Boolean, expected: boolean", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void numberProviderMustReturnPrimitiveLong() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @NumberProvider(text = "Achievements") - public Long method(UUID playerUUID) { - return null; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method has invalid return type. was: java.lang.Long, expected: long", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void doubleProviderMustReturnPrimitiveDouble() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @DoubleProvider(text = "Money") - public Double method(UUID playerUUID) { - return null; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method has invalid return type. was: java.lang.Double, expected: double", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void percentageProviderMustReturnPrimitiveDouble() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @PercentageProvider(text = "Achievements awarded") - public Double method(UUID playerUUID) { - return null; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method has invalid return type. was: java.lang.Double, expected: double", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void stringProviderMustReturnString() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @StringProvider(text = "Town") - public Double method(UUID playerUUID) { - return null; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method has invalid return type. was: java.lang.Double, expected: java.lang.String", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void tableProviderMustReturnTable() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @TableProvider - public Double method(UUID playerUUID) { - return null; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method has invalid return type. was: java.lang.Double, expected: com.djrapitops.plan.extension.table.Table", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void booleanProviderCanNotSupplyItsOwnConditional() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @Conditional("hasJoined") - @BooleanProvider(text = "Banned", conditionName = "hasJoined") - public boolean method(UUID playerUUID) { - return false; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Warnings: [Extension.method can not be conditional of itself. required condition: hasJoined, provided condition: hasJoined]", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void conditionalMethodRequiresProvider() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @Conditional("hasJoined") - public boolean method(UUID playerUUID) { - return false; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method did not have any associated Provider for Conditional.", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void conditionalNeedsToBeProvided() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @Conditional("hasJoined") - @BooleanProvider(text = "Banned", conditionName = "isBanned") - public boolean method(UUID playerUUID) { - return false; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Warnings: [Extension: 'hasJoined' Condition was not provided by any BooleanProvider.]", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void methodNeedsValidParameters() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @Conditional("hasJoined") - @BooleanProvider(text = "Banned", conditionName = "isBanned") - public boolean method(Integer invalid) { - return false; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method has invalid parameter: 'java.lang.Integer' one of [class java.util.UUID, class java.lang.String, interface com.djrapitops.plan.extension.Group] is required as a parameter.", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - - @Test - void methodHasTooManyParameters() { - @PluginInfo(name = "Extension") - class Extension implements DataExtension { - @Conditional("hasJoined") - @BooleanProvider(text = "Banned", conditionName = "isBanned") - public boolean method(String playerName, UUID playerUUID) { - return false; - } - } - - ExtensionExtractor underTest = new ExtensionExtractor(new Extension()); - assertEquals("Extension.method has too many parameters, only one of [class java.util.UUID, class java.lang.String, interface com.djrapitops.plan.extension.Group] is required as a parameter.", assertThrows(IllegalArgumentException.class, underTest::validateAnnotations).getMessage()); - } - -} \ No newline at end of file diff --git a/Plan/build.gradle b/Plan/build.gradle deleted file mode 100644 index e62e6921f..000000000 --- a/Plan/build.gradle +++ /dev/null @@ -1,153 +0,0 @@ -// Aggregate Javadocs -buildscript { - repositories { jcenter() } - dependencies { - classpath 'com.netflix.nebula:gradle-aggregate-javadocs-plugin:2.2.+' - } -} - -plugins { - id "java" - id "jacoco" - id "checkstyle" - id "org.sonarqube" version "2.7" - id "net.ltgt.apt" version "0.21" - id "net.ltgt.apt-idea" version "0.21" - id "com.github.johnrengelman.shadow" version "5.1.0" -} - -apply plugin: 'nebula-aggregate-javadocs' - -allprojects { - wrapper.gradleVersion = "5.0" - - group "com.djrapitops" - version "4.9.1" - - test { - useJUnitPlatform() - testLogging { - events "passed", "failed" - exceptionFormat "full" - } - } - - // Fix for UTF-8 files showing with wrong encoding when compiled on Windows machines. - tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' - } -} - -subprojects { - // Build plugins - apply plugin: "java" - apply plugin: "maven-publish" - apply plugin: "net.ltgt.apt" // Annotation processing plugin - apply plugin: "net.ltgt.apt-idea" // Annotation processing IntelliJ IDEA configuration plugin - apply plugin: "com.github.johnrengelman.shadow" - - // Report plugins - apply plugin: "checkstyle" - apply plugin: "jacoco" - - sourceCompatibility = 1.8 - targetCompatibility = 1.8 - - ext.daggerVersion = "2.24" - ext.daggerCompilerVersion = "2.24" - - ext.abstractPluginFrameworkVersion = "3.4.1" - ext.planPluginBridgeVersion = "4.9.0-R0.3" - - ext.bukkitVersion = "1.12.2-R0.1-SNAPSHOT" - ext.spigotVersion = "1.12.2-R0.1-SNAPSHOT" - ext.paperVersion = "1.12.2-R0.1-SNAPSHOT" - ext.spongeVersion = "7.1.0" - ext.bungeeVersion = "1.12-SNAPSHOT" - ext.velocityVersion = "1.0-SNAPSHOT" - ext.redisBungeeVersion = "0.3.8-SNAPSHOT" - - ext.httpClientVersion = "4.5.9" - ext.commonsTextVersion = "1.7" - ext.htmlCompressorVersion = "1.5.2" - ext.caffeineVersion = "2.7.0" - ext.h2Version = "1.4.199" - ext.mysqlVersion = "8.0.17" - ext.hikariVersion = "3.3.1" - ext.slf4jVersion = "1.7.26" - ext.geoIpVersion = "2.12.0" - ext.guavaVersion = "28.0-jre" - ext.bstatsVersion = "1.4" - - repositories { - mavenCentral() - maven { // Spigot Repository - url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" - } - maven { // Paper Repository - url = "https://papermc.io/repo/repository/maven-public/" - } - maven { // Sponge Repository - url = "https://repo.spongepowered.org/maven" - } - maven { // BungeeCord Repository - url = "https://oss.sonatype.org/content/repositories/snapshots" - } - maven { // RedisBungee Repository - url = "http://repo.md-5.net/content/repositories/snapshots/" - } - maven { // Velocity Repository - url = "https://repo.velocitypowered.com/snapshots/" - } - maven { // bStats Repository - url = "https://repo.codemc.org/repository/maven-public" - } - maven { // PlanPluginBridge Repository - url = "https://dl.bintray.com/rsl1122/Plan-repository" - } - } - - dependencies { - // Dependency Injection used across the project - compile "com.google.dagger:dagger:$daggerVersion" - annotationProcessor "com.google.dagger:dagger-compiler:$daggerCompilerVersion" - testAnnotationProcessor "com.google.dagger:dagger-compiler:$daggerCompilerVersion" - - // Test Tooling Dependencies - testCompile "org.junit.jupiter:junit-jupiter-engine:5.5.1" // JUnit 5 - testCompile "org.junit.platform:junit-platform-runner:1.5.1" // JUnit 4 runner for JUnit 5 tests - testCompile "org.junit.vintage:junit-vintage-engine:5.5.1" // JUnit 4 compatibility for JUnit 5 - testCompile "org.junit.jupiter:junit-jupiter-params:5.5.1" // JUnit 5, parameterized tests - testCompile "org.mockito:mockito-core:3.0.0" // Mockito Core - testCompile "org.mockito:mockito-junit-jupiter:3.0.0" // Mockito JUnit 5 Extension - testCompile "org.seleniumhq.selenium:selenium-java:3.141.59" // Selenium (Browser tests) - testCompile "com.jayway.awaitility:awaitility:1.7.0" // Awaitility (Concurrent wait conditions) - - // Testing dependencies required by Plan - testCompile "org.xerial:sqlite-jdbc:3.28.0" // SQLite - testCompile "mysql:mysql-connector-java:$mysqlVersion" // MySQL - } - - configurations { - testArtifacts.extendsFrom testRuntime - } - // Test classes available to other modules - task testJar(type: Jar) { - classifier "test" - from sourceSets.test.output - } - artifacts { - testArtifacts testJar - } - - checkstyle { - configFile rootProject.file('config/checkstyle/checkstyle.xml') - } -} - -sonarqube { - properties { - property "sonar.projectName", "Player Analytics" - property "sonar.projectKey", "com.djrapitops:Plan" - } -} \ No newline at end of file diff --git a/Plan/bukkit/build.gradle b/Plan/bukkit/build.gradle deleted file mode 100644 index fe6752325..000000000 --- a/Plan/bukkit/build.gradle +++ /dev/null @@ -1,23 +0,0 @@ -dependencies { - compile project(path: ":common", configuration: 'shadow') - - compile "com.djrapitops:AbstractPluginFramework-bukkit:$abstractPluginFrameworkVersion" - compile "org.bstats:bstats-bukkit:$bstatsVersion" - -// compileOnly "org.spigotmc:spigot-api:$spigotVersion" -// compileOnly "org.bukkit:bukkit:$bukkitVersion" - compileOnly "com.destroystokyo.paper:paper-api:$paperVersion" - -// testCompile "org.spigotmc:spigot-api:$spigotVersion" -// testCompile "org.bukkit:bukkit:$bukkitVersion" - testCompile "com.destroystokyo.paper:paper-api:$paperVersion" - - testCompile project(path: ":common", configuration: 'testArtifacts') -} - -shadowJar { - configurations = [project.configurations.compile] - - relocate 'org.bstats', 'com.djrapitops.plan.utilities.metrics' - relocate 'org.slf4j', 'plan.org.slf4j' -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/BStatsBukkit.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/BStatsBukkit.java deleted file mode 100644 index 3f3288990..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/BStatsBukkit.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plugin.api.Check; -import org.bstats.bukkit.Metrics; - -public class BStatsBukkit { - - private final Plan plugin; - private Metrics metrics; - - public BStatsBukkit(Plan plugin) { - this.plugin = plugin; - } - - public void registerMetrics() { - if (metrics == null) { - metrics = new Metrics(plugin); - } - registerConfigSettingGraphs(); - } - - private void registerConfigSettingGraphs() { - String serverType = plugin.getServer().getName(); - if ("CraftBukkit".equals(serverType) && Check.isSpigotAvailable()) { - serverType = "Spigot"; - } - String databaseType = plugin.getSystem().getDatabaseSystem().getDatabase().getType().getName(); - - addStringSettingPie("server_type", serverType); - addStringSettingPie("database_type", databaseType); - } - - protected void addStringSettingPie(String id, String setting) { - metrics.addCustomChart(new Metrics.SimplePie(id, () -> setting)); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitServerShutdownSave.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitServerShutdownSave.java deleted file mode 100644 index c710c349d..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitServerShutdownSave.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.utilities.java.Reflection; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * ServerShutdownSave implementation for Bukkit based servers. - * - * @author Rsl1122 - */ -@Singleton -public class BukkitServerShutdownSave extends ServerShutdownSave { - - @Inject - public BukkitServerShutdownSave( - Locale locale, - DBSystem dbSystem, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(locale, dbSystem, logger, errorHandler); - } - - @Override - protected boolean checkServerShuttingDownStatus() { - try { - return performCheck(); - } catch (Exception | NoClassDefFoundError | NoSuchFieldError e) { - logger.debug("Server shutdown check failed, using JVM ShutdownHook instead. Error: " + e.toString()); - return false; // ShutdownHook handles save in case this fails upon plugin disable. - } - } - - private boolean performCheck() { - // Special thanks to Fuzzlemann for figuring out the methods required for this check. - // https://github.com/Rsl1122/Plan-PlayerAnalytics/issues/769#issuecomment-433898242 - Class minecraftServerClass = Reflection.getMinecraftClass("MinecraftServer"); - Object minecraftServer = Reflection.getField(minecraftServerClass, "SERVER", minecraftServerClass).get(null); - - return Reflection.getField(minecraftServerClass, "isStopped", boolean.class).get(minecraftServer); - } -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/Plan.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/Plan.java deleted file mode 100644 index e09fa21da..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/Plan.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.command.PlanCommand; -import com.djrapitops.plan.command.commands.RegisterCommandFilter; -import com.djrapitops.plan.system.PlanSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.settings.theme.PlanColorScheme; -import com.djrapitops.plugin.BukkitPlugin; -import com.djrapitops.plugin.benchmarking.Benchmark; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.task.AbsRunnable; -import org.bukkit.configuration.file.FileConfiguration; - -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Main class for Bukkit that manages the plugin. - * - * @author Rsl1122 - */ -public class Plan extends BukkitPlugin implements PlanPlugin { - - private PlanSystem system; - private Locale locale; - private ServerShutdownSave serverShutdownSave; - - @Override - public void onEnable() { - PlanBukkitComponent component = DaggerPlanBukkitComponent.builder().plan(this).build(); - try { - timings.start("Enable"); - system = component.system(); - serverShutdownSave = component.serverShutdownSave(); - locale = system.getLocaleSystem().getLocale(); - system.enable(); - - registerMetrics(); - - logger.debug("Verbose debug messages are enabled."); - String benchTime = " (" + timings.end("Enable").map(Benchmark::toDurationString).orElse("-") + ")"; - logger.info(locale.getString(PluginLang.ENABLED) + benchTime); - } catch (AbstractMethodError e) { - logger.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); - } catch (EnableException e) { - logger.error("----------------------------------------"); - logger.error("Error: " + e.getMessage()); - logger.error("----------------------------------------"); - logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); - onDisable(); - } catch (Exception e) { - Logger.getGlobal().log(Level.SEVERE, this.getClass().getSimpleName() + "-v" + getVersion(), e); - logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); - logger.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); - onDisable(); - } - PlanCommand command = component.planCommand(); - command.registerCommands(); - registerCommand("plan", command); - new RegisterCommandFilter().registerFilter(); - if (system != null) { - system.getProcessing().submitNonCritical(() -> system.getListenerSystem().callEnableEvent(this)); - } - } - - private void registerMetrics() { - Plan plugin = this; - // Spigot 1.14 requires Sync events to be fired from a server thread. - // Registering a service fires a sync event, and bStats registers a service, - // so this has to be run on the server thread. - runnableFactory.create("Register Metrics task", new AbsRunnable() { - @Override - public void run() { - new BStatsBukkit(plugin).registerMetrics(); - } - }).runTask(); - } - - @Override - public ColorScheme getColorScheme() { - return PlanColorScheme.create(system.getConfigSystem().getConfig(), logger); - } - - /** - * Disables the plugin. - */ - @Override - public void onDisable() { - if (serverShutdownSave != null) { - serverShutdownSave.performSave(); - } - if (system != null) { - system.disable(); - } - - logger.info(locale != null ? locale.getString(PluginLang.DISABLED) : PluginLang.DISABLED.getDefault()); - } - - @Override - public String getVersion() { - return getDescription().getVersion(); - } - - @Override - public void onReload() { - // Nothing to be done, systems are disabled - } - - @Override - public boolean isReloading() { - return reloading; - } - - /** - * @deprecated Deprecated due to use of APF Config - */ - @Override - @Deprecated - public void reloadConfig() { - throw new IllegalStateException("This method should be used on this plugin. Use onReload() instead"); - } - - /** - * @deprecated Deprecated due to use of APF Config - */ - @Override - @Deprecated - public FileConfiguration getConfig() { - throw new IllegalStateException("This method should be used on this plugin. Use getMainConfig() instead"); - } - - /** - * @deprecated Deprecated due to use of APF Config - */ - @Override - @Deprecated - public void saveConfig() { - throw new IllegalStateException("This method should be used on this plugin. Use getMainConfig().save() instead"); - } - - /** - * @deprecated Deprecated due to use of APF Config - */ - @Override - @Deprecated - public void saveDefaultConfig() { - throw new IllegalStateException("This method should be used on this plugin."); - } - - @Override - public PlanSystem getSystem() { - return system; - } -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/PlanBukkitComponent.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/PlanBukkitComponent.java deleted file mode 100644 index 60d1223aa..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/PlanBukkitComponent.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.command.PlanCommand; -import com.djrapitops.plan.modules.APFModule; -import com.djrapitops.plan.modules.FilesModule; -import com.djrapitops.plan.modules.ServerSuperClassBindingModule; -import com.djrapitops.plan.modules.SystemObjectProvidingModule; -import com.djrapitops.plan.modules.bukkit.BukkitPlanModule; -import com.djrapitops.plan.modules.bukkit.BukkitServerPropertiesModule; -import com.djrapitops.plan.modules.bukkit.BukkitSuperClassBindingModule; -import com.djrapitops.plan.system.PlanSystem; -import com.djrapitops.pluginbridge.plan.PluginBridgeModule; -import dagger.BindsInstance; -import dagger.Component; - -import javax.inject.Singleton; - -/** - * Dagger Component that constructs the plugin systems running on Bukkit. - * - * @author Rsl1122 - */ -@Singleton -@Component(modules = { - BukkitPlanModule.class, - SystemObjectProvidingModule.class, - APFModule.class, - FilesModule.class, - BukkitServerPropertiesModule.class, - ServerSuperClassBindingModule.class, - BukkitSuperClassBindingModule.class, - PluginBridgeModule.Bukkit.class -}) -public interface PlanBukkitComponent { - - PlanCommand planCommand(); - - PlanSystem system(); - - ServerShutdownSave serverShutdownSave(); - - @Component.Builder - interface Builder { - - @BindsInstance - Builder plan(Plan plan); - - PlanBukkitComponent build(); - } -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/api/events/PlanBukkitEnableEvent.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/api/events/PlanBukkitEnableEvent.java deleted file mode 100644 index db2c68be0..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/api/events/PlanBukkitEnableEvent.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.events; - -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -/** - * Event that is called when Plan is enabled. - *

- * This includes, but might not be limited to: - * - First time the plugin enables successfully - * - Plan is reloaded - * - Bukkit-BungeeCord setup updates settings - * - Plan is enabled after it was disabled - *

- * {@code event.isPlanSystemEnabled()} can be called to determine if the enable was successful. - * It is not guaranteed that this event is called when the plugin fails to enable properly. - * - * @author Rsl1122 - */ -public class PlanBukkitEnableEvent extends Event { - private static final HandlerList handlers = new HandlerList(); - - private final boolean enabled; - - public PlanBukkitEnableEvent(boolean enabled) { - super(true); - this.enabled = enabled; - } - - public static HandlerList getHandlerList() { - return handlers; - } - - public boolean isPlanSystemEnabled() { - return enabled; - } - - @Override - public HandlerList getHandlers() { - return PlanBukkitEnableEvent.getHandlerList(); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/command/commands/RegisterCommandFilter.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/command/commands/RegisterCommandFilter.java deleted file mode 100644 index 72c7a7b5a..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/command/commands/RegisterCommandFilter.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.google.common.collect.ImmutableSet; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.Logger; -import org.apache.logging.log4j.core.filter.AbstractFilter; -import org.apache.logging.log4j.message.Message; - -import java.util.Set; - -/** - * Filters out WebUser registration command logs. - * - * @author Rsl1122 - */ -public class RegisterCommandFilter extends AbstractFilter { - - private final Set censoredCommands = ImmutableSet.of("/plan web register", "/plan webuser register", "/plan register"); - - public void registerFilter() { - Logger logger = (Logger) LogManager.getRootLogger(); - logger.addFilter(this); - } - - @Override - public Result filter(LogEvent event) { - if (event == null) { - return Result.NEUTRAL; - } - - return validateMessage(event.getMessage()); - } - - @Override - public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) { - return validateMessage(msg); - } - - @Override - public Result filter(Logger logger, Level level, Marker marker, String msg, Object... params) { - return validateMessage(msg); - } - - @Override - public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) { - if (msg == null) { - return Result.NEUTRAL; - } - - return validateMessage(msg.toString()); - } - - private Result validateMessage(Message message) { - if (message == null) { - return Result.NEUTRAL; - } - - return validateMessage(message.getFormattedMessage()); - } - - private Result validateMessage(String message) { - if (message == null) { - return Result.NEUTRAL; - } - - return commandShouldBeCensored(message) - ? Result.DENY - : Result.NEUTRAL; - } - - private boolean commandShouldBeCensored(String message) { - return message != null - && (message.toLowerCase().contains("issued server command:") - && shouldBeCensored(message)); - } - - private boolean shouldBeCensored(String message) { - return message != null && censoredCommands.stream().anyMatch(message::contains); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitPlanModule.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitPlanModule.java deleted file mode 100644 index 0aa85c20c..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitPlanModule.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules.bukkit; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.command.PlanCommand; -import com.djrapitops.plugin.command.CommandNode; -import dagger.Binds; -import dagger.Module; - -import javax.inject.Named; - -/** - * Dagger module for binding Plan instance. - * - * @author Rsl1122 - */ -@Module -public interface BukkitPlanModule { - - @Binds - PlanPlugin bindPlanPlugin(Plan plugin); - - @Binds - @Named("mainCommand") - CommandNode bindMainCommand(PlanCommand command); -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitServerPropertiesModule.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitServerPropertiesModule.java deleted file mode 100644 index 60b5fa43a..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitServerPropertiesModule.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules.bukkit; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.system.info.server.properties.BukkitServerProperties; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import dagger.Module; -import dagger.Provides; - -import javax.inject.Singleton; - -/** - * Dagger module for Bukkit ServerProperties. - * - * @author Rsl1122 - */ -@Module -public class BukkitServerPropertiesModule { - - @Provides - @Singleton - ServerProperties provideServerProperties(Plan plugin) { - return new BukkitServerProperties(plugin.getServer()); - } -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitSuperClassBindingModule.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitSuperClassBindingModule.java deleted file mode 100644 index cab6c3125..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitSuperClassBindingModule.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules.bukkit; - -import com.djrapitops.plan.BukkitServerShutdownSave; -import com.djrapitops.plan.ServerShutdownSave; -import com.djrapitops.plan.system.database.BukkitDBSystem; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.importing.BukkitImportSystem; -import com.djrapitops.plan.system.importing.ImportSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.info.server.ServerServerInfo; -import com.djrapitops.plan.system.listeners.BukkitListenerSystem; -import com.djrapitops.plan.system.listeners.ListenerSystem; -import com.djrapitops.plan.system.settings.BukkitConfigSystem; -import com.djrapitops.plan.system.settings.ConfigSystem; -import com.djrapitops.plan.system.tasks.BukkitTaskSystem; -import com.djrapitops.plan.system.tasks.TaskSystem; -import dagger.Binds; -import dagger.Module; - -/** - * Module for binding Bukkit specific classes to the interface implementations. - * - * @author Rsl1122 - */ -@Module -public interface BukkitSuperClassBindingModule { - - @Binds - ServerInfo bindBukkitServerInfo(ServerServerInfo serverServerInfo); - - @Binds - DBSystem bindBukkitDatabaseSystem(BukkitDBSystem dbSystem); - - @Binds - ConfigSystem bindBukkitConfigSystem(BukkitConfigSystem bukkitConfigSystem); - - @Binds - TaskSystem bindBukkitTaskSystem(BukkitTaskSystem bukkitTaskSystem); - - @Binds - ListenerSystem bindBukkitListenerSystem(BukkitListenerSystem bukkitListenerSystem); - - @Binds - ImportSystem bindImportSystem(BukkitImportSystem bukkitImportSystem); - - @Binds - ServerShutdownSave bindBukkitServerShutdownSave(BukkitServerShutdownSave bukkitServerShutdownSave); - -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java deleted file mode 100644 index 428a5916f..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.database; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.db.H2DB; -import com.djrapitops.plan.db.MySQLDB; -import com.djrapitops.plan.db.SQLiteDB; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DatabaseSettings; -import com.djrapitops.plugin.benchmarking.Timings; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Bukkit Database system that initializes SQLite and MySQL database objects. - * - * @author Rsl1122 - */ -@Singleton -public class BukkitDBSystem extends DBSystem { - - private final PlanConfig config; - - @Inject - public BukkitDBSystem( - Locale locale, - MySQLDB mySQLDB, - SQLiteDB.Factory sqLiteDB, - H2DB.Factory h2DB, - PlanConfig config, - PluginLogger logger, - Timings timings, - ErrorHandler errorHandler - ) { - super(locale, sqLiteDB, h2DB, logger, timings, errorHandler); - this.config = config; - - databases.add(mySQLDB); - databases.add(h2DB.usingDefaultFile()); - databases.add(sqLiteDB.usingDefaultFile()); - } - - @Override - public void enable() throws EnableException { - String dbType = config.get(DatabaseSettings.TYPE).toLowerCase().trim(); - db = getActiveDatabaseByName(dbType); - super.enable(); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/BukkitImportSystem.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/BukkitImportSystem.java deleted file mode 100644 index 554c6f10c..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/BukkitImportSystem.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.importing; - -import com.djrapitops.plan.system.importing.importers.OfflinePlayerImporter; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * ImportSystem implementation for Bukkit. - * - * @author Rsl1122 - */ -@Singleton -public class BukkitImportSystem extends ImportSystem { - - private final OfflinePlayerImporter offlinePlayerImporter; - - @Inject - public BukkitImportSystem( - OfflinePlayerImporter offlinePlayerImporter - ) { - this.offlinePlayerImporter = offlinePlayerImporter; - } - - @Override - void registerImporters() { - registerImporter(offlinePlayerImporter); - } -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/data/BukkitUserImportRefiner.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/data/BukkitUserImportRefiner.java deleted file mode 100644 index 7afd4683e..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/data/BukkitUserImportRefiner.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.importing.data; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.system.DebugChannels; -import com.djrapitops.plugin.api.utility.UUIDFetcher; -import com.djrapitops.plugin.benchmarking.Timings; -import org.bukkit.OfflinePlayer; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * UserImportRefiner attempts to find any crucial information that is missing. - * - * - Finds UUIDs if only name is present. - * - Finds Names if only UUID is present. - * - Removes any importers that do not have any identifiers. - * - * @author Fuzzlemann - */ -public class BukkitUserImportRefiner { - - private final Plan plugin; - private final Timings timings; - private final boolean onlineMode; - - private final List importers = new ArrayList<>(); - - private final Map missingUUIDs = new HashMap<>(); - private final Map missingNames = new HashMap<>(); - - private final Map foundUUIDs = new HashMap<>(); - private final Map foundNames = new HashMap<>(); - - public BukkitUserImportRefiner(Plan plugin, List importers) { - this.plugin = plugin; - this.timings = plugin.getTimings(); - this.importers.addAll(importers); - - onlineMode = plugin.getServer().getOnlineMode(); - } - - public List refineData() { - String benchmarkName = "Refining UserImportData"; - - timings.start(benchmarkName); - processMissingIdentifiers(); - timings.end(DebugChannels.IMPORTING, benchmarkName); - - return importers; - } - - private void processMissingIdentifiers() { - String benchmarkName = "Processing missing identifiers"; - - timings.start(benchmarkName); - - List invalidData = new ArrayList<>(); - - importers.parallelStream().forEach(importer -> { - String name = importer.getName(); - UUID uuid = importer.getUuid(); - - boolean nameNull = name == null; - boolean uuidNull = uuid == null; - - if (nameNull && uuidNull) { - invalidData.add(importer); - } else if (nameNull) { - missingNames.put(importer, uuid.toString()); - } else if (uuidNull) { - missingUUIDs.put(importer, name); - } - }); - - importers.removeAll(invalidData); - - processMissingUUIDs(); - processMissingNames(); - - timings.end(DebugChannels.IMPORTING, benchmarkName); - } - - private void processMissingUUIDs() { - String benchmarkName = "Processing missing UUIDs"; - - timings.start(benchmarkName); - - if (onlineMode) { - addMissingUUIDsOverFetcher(); - addMissingUUIDsOverOfflinePlayer(); - } else { - addMissingUUIDsOverOfflinePlayer(); - addMissingUUIDsOverFetcher(); - } - - foundUUIDs.entrySet().parallelStream() - .forEach(entry -> { - UserImportData userImportData = entry.getKey(); - UUID uuid = UUID.fromString(entry.getValue()); - - userImportData.setUuid(uuid); - }); - - importers.removeAll(missingUUIDs.keySet()); - - timings.end(DebugChannels.IMPORTING, benchmarkName); - } - - private void addMissingUUIDsOverFetcher() { - UUIDFetcher uuidFetcher = new UUIDFetcher(new ArrayList<>(missingUUIDs.values())); - - Map result; - - try { - result = uuidFetcher.call().entrySet().parallelStream() - .collect(Collectors.toMap(entry -> entry.getValue().toString(), Map.Entry::getKey)); - } catch (Exception e) { - return; - } - - addFoundUUIDs(result); - } - - private void addMissingUUIDsOverOfflinePlayer() { - Map result = new HashMap<>(); - - for (String name : missingUUIDs.values()) { - String uuid = getUuidByOfflinePlayer(name); - - if (uuid == null) { - continue; - } - - result.put(name, uuid); - } - - addFoundUUIDs(result); - } - - private void addFoundUUIDs(Map foundUUIDs) { - List found = new ArrayList<>(); - - missingUUIDs.entrySet().parallelStream().forEach(entry -> { - UserImportData importer = entry.getKey(); - String name = entry.getValue(); - - String uuid = foundUUIDs.get(name); - - this.foundUUIDs.put(importer, uuid); - found.add(importer); - }); - - missingUUIDs.keySet().removeAll(found); - } - - @SuppressWarnings("deprecation") - private String getUuidByOfflinePlayer(String name) { - OfflinePlayer player = plugin.getServer().getOfflinePlayer(name); - - if (!player.hasPlayedBefore()) { - return null; - } - - return player.getUniqueId().toString(); - } - - private void processMissingNames() { - String benchmarkNames = "Processing missing names"; - - timings.start(benchmarkNames); - - findMissingNames(); - - foundNames.entrySet().parallelStream().forEach(entry -> entry.getKey().setName(entry.getValue())); - - importers.removeAll(missingNames.keySet()); - - timings.end(DebugChannels.IMPORTING, benchmarkNames); - } - - private void findMissingNames() { - Map result = new HashMap<>(); - - missingNames.values().parallelStream().forEach(uuid -> { - String name = getNameByOfflinePlayer(uuid); - - result.put(uuid, name); - }); - - addFoundNames(result); - } - - private void addFoundNames(Map foundNames) { - List found = new ArrayList<>(); - - missingNames.entrySet().parallelStream().forEach(entry -> { - UserImportData importer = entry.getKey(); - String uuid = entry.getValue(); - - String name = foundNames.get(uuid); - - this.foundNames.put(importer, name); - found.add(importer); - }); - - missingNames.keySet().removeAll(found); - } - - private String getNameByOfflinePlayer(String uuid) { - OfflinePlayer player = plugin.getServer().getOfflinePlayer(UUID.fromString(uuid)); - - if (!player.hasPlayedBefore()) { - return null; - } - - return player.getName(); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/importers/BukkitImporter.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/importers/BukkitImporter.java deleted file mode 100644 index f387b3a80..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/importers/BukkitImporter.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.importing.importers; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.data.container.BaseUser; -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.container.UserInfo; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.LargeStoreQueries; -import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.system.cache.GeolocationCache; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.importing.data.BukkitUserImportRefiner; -import com.djrapitops.plan.system.importing.data.ServerImportData; -import com.djrapitops.plan.system.importing.data.UserImportData; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -/** - * Generic importer for user data into Plan on the Bukkit platform. - * - * @author Fuzzlemann - */ -public abstract class BukkitImporter implements Importer { - - protected final Supplier serverUUID; - private final GeolocationCache geolocationCache; - private final DBSystem dbSystem; - private final String name; - private final Plan plugin; - - protected BukkitImporter( - Plan plugin, - GeolocationCache geolocationCache, - DBSystem dbSystem, - ServerInfo serverInfo, - String name - ) { - this.geolocationCache = geolocationCache; - this.dbSystem = dbSystem; - this.serverUUID = serverInfo::getServerUUID; - - this.name = name; - this.plugin = plugin; - } - - @Deprecated - public List getNames() { - return new ArrayList<>(); - } - - @Override - public String getName() { - return name; - } - - public abstract ServerImportData getServerImportData(); - - public abstract List getUserImportData(); - - @Override - public final void processImport() { - ExecutorService service = Executors.newCachedThreadPool(); - - try { - service.submit(this::processServerData); - service.submit(this::processUserData); - } finally { - shutdownService(service); - } - } - - private void processServerData() { - ServerImportData serverImportData = getServerImportData(); - - if (serverImportData == null) { - return; - } - - dbSystem.getDatabase().executeTransaction(new Transaction() { - @Override - protected void performOperations() { - execute(LargeStoreQueries.storeAllTPSData(Collections.singletonMap(serverUUID.get(), serverImportData.getTpsData()))); - execute(LargeStoreQueries.storeAllCommandUsageData(Collections.singletonMap(serverUUID.get(), serverImportData.getCommandUsages()))); - } - }); - } - - private void processUserData() { - List userImportData = getUserImportData(); - - if (Verify.isEmpty(userImportData)) { - return; - } - - BukkitUserImportRefiner userImportRefiner = new BukkitUserImportRefiner(plugin, userImportData); - userImportData = userImportRefiner.refineData(); - - Database db = dbSystem.getDatabase(); - - Set existingUUIDs = db.query(UserIdentifierQueries.fetchAllPlayerUUIDs()); - Set existingUserInfoTableUUIDs = db.query(UserIdentifierQueries.fetchPlayerUUIDsOfServer(serverUUID.get())); - - Map users = new HashMap<>(); - List userInfo = new ArrayList<>(); - Map> nickNames = new HashMap<>(); - List sessions = new ArrayList<>(); - Map> geoInfo = new HashMap<>(); - - userImportData.parallelStream().forEach(data -> { - UUID uuid = data.getUuid(); - - if (!existingUUIDs.contains(uuid)) { - users.put(uuid, toBaseUser(data)); - } - - if (!existingUserInfoTableUUIDs.contains(uuid)) { - userInfo.add(toUserInfo(data)); - } - - nickNames.put(uuid, data.getNicknames()); - geoInfo.put(uuid, convertGeoInfo(data)); - sessions.add(toSession(data)); - }); - - db.executeTransaction(new Transaction() { - @Override - protected void performOperations() { - execute(LargeStoreQueries.storeAllCommonUserInformation(users.values())); - execute(LargeStoreQueries.storeAllSessionsWithKillAndWorldData(sessions)); - Map> userInformation = Collections.singletonMap(serverUUID.get(), userInfo); - execute(LargeStoreQueries.storePerServerUserInformation(userInformation)); - execute(LargeStoreQueries.storeAllNicknameData(Collections.singletonMap(serverUUID.get(), nickNames))); - execute(LargeStoreQueries.storeAllGeoInformation(geoInfo)); - } - }); - } - - private void shutdownService(ExecutorService service) { - service.shutdown(); - try { - if (!service.awaitTermination(20, TimeUnit.MINUTES)) { - service.shutdownNow(); - } - } catch (InterruptedException e) { - service.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - - private BaseUser toBaseUser(UserImportData userImportData) { - UUID playerUUID = userImportData.getUuid(); - String playerName = userImportData.getName(); - long registered = userImportData.getRegistered(); - int timesKicked = userImportData.getTimesKicked(); - return new BaseUser(playerUUID, playerName, registered, timesKicked); - } - - private UserInfo toUserInfo(UserImportData userImportData) { - UUID uuid = userImportData.getUuid(); - long registered = userImportData.getRegistered(); - boolean op = userImportData.isOp(); - boolean banned = userImportData.isBanned(); - - return new UserInfo(uuid, serverUUID.get(), registered, op, banned); - } - - private Session toSession(UserImportData userImportData) { - int mobKills = userImportData.getMobKills(); - int deaths = userImportData.getDeaths(); - - Session session = new Session(0, userImportData.getUuid(), serverUUID.get(), 0L, 0L, mobKills, deaths, 0); - - session.setPlayerKills(userImportData.getKills()); - session.setWorldTimes(new WorldTimes(userImportData.getWorldTimes())); - - return session; - } - - private List convertGeoInfo(UserImportData userImportData) { - long date = System.currentTimeMillis(); - - return userImportData.getIps().parallelStream() - .map(ip -> { - String geoLoc = geolocationCache.getCountry(ip); - return new GeoInfo(ip, geoLoc, date); - }).collect(Collectors.toList()); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/importers/OfflinePlayerImporter.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/importers/OfflinePlayerImporter.java deleted file mode 100644 index e57a0044e..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/importing/importers/OfflinePlayerImporter.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.importing.importers; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.system.cache.GeolocationCache; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.importing.data.ServerImportData; -import com.djrapitops.plan.system.importing.data.UserImportData; -import com.djrapitops.plan.system.info.server.ServerInfo; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -/** - * @author Fuzzlemann - */ -@Singleton -public class OfflinePlayerImporter extends BukkitImporter { - - @Inject - public OfflinePlayerImporter( - Plan plugin, - GeolocationCache geolocationCache, - DBSystem dbSystem, - ServerInfo serverInfo - ) { - super(plugin, geolocationCache, dbSystem, serverInfo, "offline"); - } - - @Override - public ServerImportData getServerImportData() { - return null; - } - - @Override - public List getUserImportData() { - List dataList = new ArrayList<>(); - - Set operators = Bukkit.getOperators(); - Set banned = Bukkit.getBannedPlayers(); - - Arrays.stream(Bukkit.getOfflinePlayers()).parallel().forEach(player -> { - UserImportData.UserImportDataBuilder builder = UserImportData.builder(serverUUID.get()); - builder.name(player.getName()) - .uuid(player.getUniqueId()) - .registered(player.getFirstPlayed()); - - if (operators.contains(player)) { - builder.op(); - } - - if (banned.contains(player)) { - builder.banned(); - } - - dataList.add(builder.build()); - }); - - return dataList; - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/info/server/properties/BukkitServerProperties.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/info/server/properties/BukkitServerProperties.java deleted file mode 100644 index 09bb86b44..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/info/server/properties/BukkitServerProperties.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server.properties; - -import org.bukkit.Server; - -/** - * ServerProperties for Bukkit. - * - * @author Rsl1122 - */ -public class BukkitServerProperties extends ServerProperties { - - public BukkitServerProperties(Server server) { - super( - server.getName(), - server.getPort(), - server.getVersion(), - server.getBukkitVersion(), - server::getIp, - server.getMaxPlayers(), - () -> server.getOnlinePlayers().size() - ); - } - -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java deleted file mode 100644 index 6a00fe207..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.api.events.PlanBukkitEnableEvent; -import com.djrapitops.plan.capability.CapabilityServiceImplementation; -import com.djrapitops.plan.system.listeners.bukkit.*; -import com.djrapitops.plan.system.status.Status; -import org.bukkit.Bukkit; -import org.bukkit.event.HandlerList; - -import javax.inject.Inject; - -public class BukkitListenerSystem extends ListenerSystem { - - private final Plan plugin; - - private final Status status; - private final PlayerOnlineListener playerOnlineListener; - private final ChatListener chatListener; - private final GameModeChangeListener gamemodeChangeListener; - private final WorldChangeListener worldChangeListener; - private final CommandListener commandListener; - private final DeathEventListener deathEventListener; - private final AFKListener afkListener; - - @Inject - public BukkitListenerSystem(Plan plugin, - Status status, - PlayerOnlineListener playerOnlineListener, - ChatListener chatListener, - GameModeChangeListener gamemodeChangeListener, - WorldChangeListener worldChangeListener, - CommandListener commandListener, - DeathEventListener deathEventListener, - AFKListener afkListener - ) { - this.plugin = plugin; - this.status = status; - - this.playerOnlineListener = playerOnlineListener; - this.chatListener = chatListener; - this.gamemodeChangeListener = gamemodeChangeListener; - this.worldChangeListener = worldChangeListener; - this.commandListener = commandListener; - this.deathEventListener = deathEventListener; - this.afkListener = afkListener; - } - - @Override - protected void registerListeners() { - plugin.registerListener( - playerOnlineListener, - chatListener, - gamemodeChangeListener, - worldChangeListener, - commandListener, - deathEventListener, - afkListener - ); - status.setCountKicks(true); - } - - @Override - protected void unregisterListeners() { - HandlerList.unregisterAll(plugin); - } - - @Override - public void callEnableEvent(PlanPlugin plugin) { - boolean isEnabled = plugin.isSystemEnabled(); - PlanBukkitEnableEvent event = new PlanBukkitEnableEvent(isEnabled); - Bukkit.getServer().getPluginManager().callEvent(event); - CapabilityServiceImplementation.notifyAboutEnable(isEnabled); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/AFKListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/AFKListener.java deleted file mode 100644 index f7acecc79..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/AFKListener.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners.bukkit; - -import com.djrapitops.plan.system.afk.AFKTracker; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.AsyncPlayerChatEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerEvent; -import org.bukkit.event.player.PlayerMoveEvent; - -import javax.inject.Inject; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -/** - * Listener that keeps track of actions that are not considered being AFK. - *

- * Additional Listener calls in PlayerOnlineListener to avoid having HIGHEST priority listeners. - * - * @author Rsl1122 - * @see PlayerOnlineListener - */ -public class AFKListener implements Listener { - - // Static so that /reload does not cause afk tracking to fail. - static AFKTracker AFK_TRACKER; - - private final Map ignorePermissionInfo; - private final ErrorHandler errorHandler; - - @Inject - public AFKListener(PlanConfig config, ErrorHandler errorHandler) { - this.errorHandler = errorHandler; - this.ignorePermissionInfo = new HashMap<>(); - - AFKListener.assignAFKTracker(config); - } - - private static void assignAFKTracker(PlanConfig config) { - if (AFK_TRACKER == null) { - AFK_TRACKER = new AFKTracker(config); - } - } - - private void event(PlayerEvent event) { - try { - Player player = event.getPlayer(); - UUID uuid = player.getUniqueId(); - long time = System.currentTimeMillis(); - - Boolean ignored = ignorePermissionInfo.get(uuid); - if (ignored == null) { - ignored = player.hasPermission(Permissions.IGNORE_AFK.getPermission()); - } - if (ignored) { - AFK_TRACKER.hasIgnorePermission(uuid); - ignorePermissionInfo.put(uuid, true); - } else { - ignorePermissionInfo.put(uuid, false); - } - - AFK_TRACKER.performedAction(uuid, time); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onMove(PlayerMoveEvent event) { - event(event); - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerChat(AsyncPlayerChatEvent event) { - event(event); - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerCommand(PlayerCommandPreprocessEvent event) { - event(event); - boolean isAfkCommand = event.getMessage().substring(1).toLowerCase().startsWith("afk"); - if (isAfkCommand) { - UUID uuid = event.getPlayer().getUniqueId(); - AFK_TRACKER.usedAfkCommand(uuid, System.currentTimeMillis()); - } - } - -} \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java deleted file mode 100644 index 2cb5c0d1e..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners.bukkit; - -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.db.access.transactions.events.NicknameStoreTransaction; -import com.djrapitops.plan.system.cache.NicknameCache; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.AsyncPlayerChatEvent; - -import javax.inject.Inject; -import java.util.UUID; - -/** - * Event Listener for AsyncPlayerChatEvents. - * - * @author Rsl1122 - */ -public class ChatListener implements Listener { - - private final ServerInfo serverInfo; - private final DBSystem dbSystem; - private final NicknameCache nicknameCache; - private final ErrorHandler errorHandler; - - @Inject - public ChatListener( - ServerInfo serverInfo, - DBSystem dbSystem, - NicknameCache nicknameCache, - ErrorHandler errorHandler - ) { - this.serverInfo = serverInfo; - this.dbSystem = dbSystem; - this.nicknameCache = nicknameCache; - this.errorHandler = errorHandler; - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onChat(AsyncPlayerChatEvent event) { - if (event.isCancelled()) { - return; - } - - try { - actOnChatEvent(event); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - private void actOnChatEvent(AsyncPlayerChatEvent event) { - long time = System.currentTimeMillis(); - Player player = event.getPlayer(); - UUID uuid = player.getUniqueId(); - String displayName = player.getDisplayName(); - - dbSystem.getDatabase().executeTransaction(new NicknameStoreTransaction( - uuid, new Nickname(displayName, time, serverInfo.getServerUUID()), - (playerUUID, name) -> name.equals(nicknameCache.getDisplayName(playerUUID)) - )); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandListener.java deleted file mode 100644 index fe0931511..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandListener.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners.bukkit; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.db.access.transactions.events.CommandStoreTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DataGatheringSettings; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.command.Command; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; - -import javax.inject.Inject; - -/** - * Event Listener for PlayerCommandPreprocessEvents. - * - * @author Rsl1122 - */ -public class CommandListener implements Listener { - - private final Plan plugin; - private final PlanConfig config; - private final ServerInfo serverInfo; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public CommandListener( - Plan plugin, - PlanConfig config, - ServerInfo serverInfo, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - this.plugin = plugin; - this.config = config; - this.serverInfo = serverInfo; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerCommand(PlayerCommandPreprocessEvent event) { - boolean hasIgnorePermission = event.getPlayer().hasPermission(Permissions.IGNORE_COMMAND_USE.getPermission()); - if (event.isCancelled() || hasIgnorePermission) { - return; - } - - try { - actOnCommandEvent(event); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - private void actOnCommandEvent(PlayerCommandPreprocessEvent event) { - String commandName = event.getMessage().substring(1).split(" ")[0].toLowerCase(); - - boolean logUnknownCommands = config.isTrue(DataGatheringSettings.LOG_UNKNOWN_COMMANDS); - boolean combineCommandAliases = config.isTrue(DataGatheringSettings.COMBINE_COMMAND_ALIASES); - - if (!logUnknownCommands || combineCommandAliases) { - Command command = getBukkitCommand(commandName); - if (command == null) { - if (!logUnknownCommands) { - return; - } - } else if (combineCommandAliases) { - commandName = command.getName(); - } - } - dbSystem.getDatabase().executeTransaction(new CommandStoreTransaction(serverInfo.getServerUUID(), commandName)); - } - - private Command getBukkitCommand(String commandName) { - Command command = plugin.getServer().getPluginCommand(commandName); - if (command == null) { - try { - command = plugin.getServer().getCommandMap().getCommand(commandName); - } catch (NoSuchMethodError ignored) { - /* Ignored, Bukkit 1.8 has no such method. This method is from Paper */ - } - } - return command; - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/DeathEventListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/DeathEventListener.java deleted file mode 100644 index 021039bcd..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/DeathEventListener.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners.bukkit; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.player.MobKillProcessor; -import com.djrapitops.plan.system.processing.processors.player.PlayerKillProcessor; -import com.djrapitops.plan.utilities.formatting.EntityNameFormatter; -import com.djrapitops.plan.utilities.formatting.ItemNameFormatter; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.Material; -import org.bukkit.entity.*; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.projectiles.ProjectileSource; - -import javax.inject.Inject; -import java.util.UUID; - -/** - * Event Listener for EntityDeathEvents. - * - * @author Rsl1122 - */ -public class DeathEventListener implements Listener { - - private final Processing processing; - private final ErrorHandler errorHandler; - - @Inject - public DeathEventListener( - Processing processing, - ErrorHandler errorHandler - ) { - this.processing = processing; - this.errorHandler = errorHandler; - } - - @SuppressWarnings("deprecation") - @EventHandler(priority = EventPriority.MONITOR) - public void onDeath(EntityDeathEvent event) { - long time = System.currentTimeMillis(); - LivingEntity dead = event.getEntity(); - - if (dead instanceof Player) { - // Process Death - SessionCache.getCachedSession(dead.getUniqueId()).ifPresent(Session::died); - } - - try { - EntityDamageEvent entityDamageEvent = dead.getLastDamageCause(); - if (!(entityDamageEvent instanceof EntityDamageByEntityEvent)) { - return; - } - - EntityDamageByEntityEvent entityDamageByEntityEvent = (EntityDamageByEntityEvent) entityDamageEvent; - Entity killerEntity = entityDamageByEntityEvent.getDamager(); - - UUID uuid = dead instanceof Player ? dead.getUniqueId() : null; - handleKill(time, uuid, killerEntity); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - private void handleKill(long time, UUID victimUUID, Entity killerEntity) { - Runnable processor = null; - if (killerEntity instanceof Player) { - processor = handlePlayerKill(time, victimUUID, (Player) killerEntity); - } else if (killerEntity instanceof Tameable) { - processor = handlePetKill(time, victimUUID, (Tameable) killerEntity); - } else if (killerEntity instanceof Projectile) { - processor = handleProjectileKill(time, victimUUID, (Projectile) killerEntity); - } - if (processor != null) { - processing.submit(processor); - } - } - - private Runnable handlePlayerKill(long time, UUID victimUUID, Player killer) { - Material itemInHand; - try { - itemInHand = killer.getInventory().getItemInMainHand().getType(); - } catch (NoSuchMethodError e) { - try { - itemInHand = killer.getInventory().getItemInHand().getType(); // Support for non dual wielding versions. - } catch (Exception | NoSuchMethodError | NoSuchFieldError e2) { - itemInHand = Material.AIR; - } - } - - String weaponName = new ItemNameFormatter().apply(itemInHand.name()); - - return victimUUID != null - ? new PlayerKillProcessor(killer.getUniqueId(), time, victimUUID, weaponName) - : new MobKillProcessor(killer.getUniqueId()); - } - - private Runnable handlePetKill(long time, UUID victimUUID, Tameable tameable) { - if (!tameable.isTamed()) { - return null; - } - - AnimalTamer owner = tameable.getOwner(); - if (!(owner instanceof Player)) { - return null; - } - - String name; - try { - name = tameable.getType().name(); - } catch (NoSuchMethodError oldVersionNoTypesError) { - // getType introduced in 1.9 - name = tameable.getClass().getSimpleName(); - } - - return victimUUID != null - ? new PlayerKillProcessor(owner.getUniqueId(), time, victimUUID, new EntityNameFormatter().apply(name)) - : new MobKillProcessor(owner.getUniqueId()); - } - - private Runnable handleProjectileKill(long time, UUID victimUUID, Projectile projectile) { - ProjectileSource source = projectile.getShooter(); - if (!(source instanceof Player)) { - return null; - } - - Player player = (Player) source; - String projectileName = new EntityNameFormatter().apply(projectile.getType().name()); - - return victimUUID != null - ? new PlayerKillProcessor(player.getUniqueId(), time, victimUUID, projectileName) - : new MobKillProcessor(player.getUniqueId()); - } -} - diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GameModeChangeListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GameModeChangeListener.java deleted file mode 100644 index 40ddc29d5..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GameModeChangeListener.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners.bukkit; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.db.access.transactions.events.WorldNameStoreTransaction; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.WorldAliasSettings; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerGameModeChangeEvent; - -import javax.inject.Inject; -import java.util.Optional; -import java.util.UUID; - -/** - * Event Listener for PlayerGameModeChangeEvents. - * - * @author Rsl1122 - */ -public class GameModeChangeListener implements Listener { - - private final WorldAliasSettings worldAliasSettings; - private final ServerInfo serverInfo; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public GameModeChangeListener( - WorldAliasSettings worldAliasSettings, - ServerInfo serverInfo, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - this.worldAliasSettings = worldAliasSettings; - this.serverInfo = serverInfo; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onGameModeChange(PlayerGameModeChangeEvent event) { - if (event.isCancelled()) { - return; - } - try { - actOnEvent(event); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - private void actOnEvent(PlayerGameModeChangeEvent event) { - Player player = event.getPlayer(); - UUID uuid = player.getUniqueId(); - long time = System.currentTimeMillis(); - String gameMode = event.getNewGameMode().name(); - String worldName = player.getWorld().getName(); - - dbSystem.getDatabase().executeTransaction(new WorldNameStoreTransaction(serverInfo.getServerUUID(), worldName)); - worldAliasSettings.addWorld(worldName); - - Optional cachedSession = SessionCache.getCachedSession(uuid); - cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java deleted file mode 100644 index e1e4ef45b..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners.bukkit; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.events.*; -import com.djrapitops.plan.extension.CallEvents; -import com.djrapitops.plan.extension.ExtensionServiceImplementation; -import com.djrapitops.plan.system.cache.GeolocationCache; -import com.djrapitops.plan.system.cache.NicknameCache; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.Processors; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DataGatheringSettings; -import com.djrapitops.plan.system.status.Status; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerKickEvent; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import javax.inject.Inject; -import java.net.InetAddress; -import java.util.UUID; - -/** - * Event Listener for PlayerJoin, PlayerQuit and PlayerKickEvents. - * - * @author Rsl1122 - */ -public class PlayerOnlineListener implements Listener { - - private final PlanConfig config; - private final Processors processors; - private final Processing processing; - private final ServerInfo serverInfo; - private final DBSystem dbSystem; - private final ExtensionServiceImplementation extensionService; - private final GeolocationCache geolocationCache; - private final NicknameCache nicknameCache; - private final SessionCache sessionCache; - private final ErrorHandler errorHandler; - private final Status status; - - @Inject - public PlayerOnlineListener( - PlanConfig config, - Processors processors, - Processing processing, - ServerInfo serverInfo, - DBSystem dbSystem, - ExtensionServiceImplementation extensionService, - GeolocationCache geolocationCache, - NicknameCache nicknameCache, - SessionCache sessionCache, - Status status, - ErrorHandler errorHandler - ) { - this.config = config; - this.processors = processors; - this.processing = processing; - this.serverInfo = serverInfo; - this.dbSystem = dbSystem; - this.extensionService = extensionService; - this.geolocationCache = geolocationCache; - this.nicknameCache = nicknameCache; - this.sessionCache = sessionCache; - this.status = status; - this.errorHandler = errorHandler; - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerLogin(PlayerLoginEvent event) { - try { - PlayerLoginEvent.Result result = event.getResult(); - UUID playerUUID = event.getPlayer().getUniqueId(); - boolean operator = event.getPlayer().isOp(); - boolean banned = result == PlayerLoginEvent.Result.KICK_BANNED; - dbSystem.getDatabase().executeTransaction(new BanStatusTransaction(playerUUID, () -> banned)); - dbSystem.getDatabase().executeTransaction(new OperatorStatusTransaction(playerUUID, operator)); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - /** - * PlayerKickEvent Listener. - *

- * Adds processing information to the ProcessingQueue. - * After KickEvent, the QuitEvent is automatically called. - * - * @param event Fired event - */ - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerKick(PlayerKickEvent event) { - try { - if (!status.areKicksCounted() || event.isCancelled()) { - return; - } - UUID uuid = event.getPlayer().getUniqueId(); - if (AFKListener.AFK_TRACKER.isAfk(uuid)) { - return; - } - - dbSystem.getDatabase().executeTransaction(new KickStoreTransaction(uuid)); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerJoin(PlayerJoinEvent event) { - try { - actOnJoinEvent(event); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - private void actOnJoinEvent(PlayerJoinEvent event) { - Player player = event.getPlayer(); - - UUID playerUUID = player.getUniqueId(); - UUID serverUUID = serverInfo.getServerUUID(); - long time = System.currentTimeMillis(); - - AFKListener.AFK_TRACKER.performedAction(playerUUID, time); - - String world = player.getWorld().getName(); - String gm = player.getGameMode().name(); - - Database database = dbSystem.getDatabase(); - database.executeTransaction(new WorldNameStoreTransaction(serverUUID, world)); - - InetAddress address = player.getAddress().getAddress(); - - String playerName = player.getName(); - String displayName = player.getDisplayName(); - - boolean gatheringGeolocations = config.isTrue(DataGatheringSettings.GEOLOCATIONS); - if (gatheringGeolocations) { - database.executeTransaction( - new GeoInfoStoreTransaction(playerUUID, address, time, geolocationCache::getCountry) - ); - } - - database.executeTransaction(new PlayerServerRegisterTransaction(playerUUID, player::getFirstPlayed, playerName, serverUUID)); - sessionCache.cacheSession(playerUUID, new Session(playerUUID, serverUUID, time, world, gm)) - .ifPresent(previousSession -> database.executeTransaction(new SessionEndTransaction(previousSession))); - - database.executeTransaction(new NicknameStoreTransaction( - playerUUID, new Nickname(displayName, time, serverUUID), - (uuid, name) -> name.equals(nicknameCache.getDisplayName(uuid)) - )); - - processing.submitNonCritical(processors.info().playerPageUpdateProcessor(playerUUID)); - processing.submitNonCritical(() -> extensionService.updatePlayerValues(playerUUID, playerName, CallEvents.PLAYER_JOIN)); - } - - @EventHandler(priority = EventPriority.NORMAL) - public void beforePlayerQuit(PlayerQuitEvent event) { - Player player = event.getPlayer(); - UUID playerUUID = player.getUniqueId(); - String playerName = player.getName(); - processing.submitNonCritical(() -> extensionService.updatePlayerValues(playerUUID, playerName, CallEvents.PLAYER_LEAVE)); - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onPlayerQuit(PlayerQuitEvent event) { - try { - actOnQuitEvent(event); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - private void actOnQuitEvent(PlayerQuitEvent event) { - long time = System.currentTimeMillis(); - Player player = event.getPlayer(); - UUID playerUUID = player.getUniqueId(); - - AFKListener.AFK_TRACKER.loggedOut(playerUUID, time); - - nicknameCache.removeDisplayName(playerUUID); - - dbSystem.getDatabase().executeTransaction(new BanStatusTransaction(playerUUID, player::isBanned)); - - sessionCache.endSession(playerUUID, time) - .ifPresent(endedSession -> dbSystem.getDatabase().executeTransaction(new SessionEndTransaction(endedSession))); - - processing.submit(processors.info().playerPageUpdateProcessor(playerUUID)); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/WorldChangeListener.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/WorldChangeListener.java deleted file mode 100644 index 2f8c89af0..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/bukkit/WorldChangeListener.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners.bukkit; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.db.access.transactions.events.WorldNameStoreTransaction; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.WorldAliasSettings; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerChangedWorldEvent; - -import javax.inject.Inject; -import java.util.Optional; -import java.util.UUID; - -public class WorldChangeListener implements Listener { - - private final WorldAliasSettings worldAliasSettings; - private final ServerInfo serverInfo; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public WorldChangeListener( - WorldAliasSettings worldAliasSettings, - ServerInfo serverInfo, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - this.worldAliasSettings = worldAliasSettings; - this.serverInfo = serverInfo; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onWorldChange(PlayerChangedWorldEvent event) { - try { - actOnEvent(event); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - private void actOnEvent(PlayerChangedWorldEvent event) { - long time = System.currentTimeMillis(); - - Player player = event.getPlayer(); - UUID uuid = player.getUniqueId(); - - String worldName = player.getWorld().getName(); - String gameMode = player.getGameMode().name(); - - dbSystem.getDatabase().executeTransaction(new WorldNameStoreTransaction(serverInfo.getServerUUID(), worldName)); - worldAliasSettings.addWorld(worldName); - - Optional cachedSession = SessionCache.getCachedSession(uuid); - cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java deleted file mode 100644 index cd2d4ea14..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.ShutdownHook; -import com.djrapitops.plan.db.tasks.DBCleanTask; -import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DataGatheringSettings; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.system.tasks.bukkit.BukkitTPSCountTimer; -import com.djrapitops.plan.system.tasks.bukkit.PaperTPSCountTimer; -import com.djrapitops.plan.system.tasks.bukkit.PingCountTimerBukkit; -import com.djrapitops.plan.system.tasks.server.BootAnalysisTask; -import com.djrapitops.plan.system.tasks.server.ConfigStoreTask; -import com.djrapitops.plan.system.tasks.server.PeriodicAnalysisTask; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.task.RunnableFactory; -import org.bukkit.Bukkit; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -/** - * TaskSystem responsible for registering tasks for Bukkit. - * - * @author Rsl1122 - */ -@Singleton -public class BukkitTaskSystem extends ServerTaskSystem { - - private final Plan plugin; - private final ShutdownHook shutdownHook; - private final PingCountTimerBukkit pingCountTimer; - private final ConfigStoreTask configStoreTask; - private final DBCleanTask dbCleanTask; - private final ExtensionServerMethodCallerTask extensionServerMethodCallerTask; - - @Inject - public BukkitTaskSystem( - Plan plugin, - PlanConfig config, - ShutdownHook shutdownHook, - RunnableFactory runnableFactory, - PaperTPSCountTimer paperTPSCountTimer, - BukkitTPSCountTimer bukkitTPSCountTimer, - BootAnalysisTask bootAnalysisTask, - PeriodicAnalysisTask periodicAnalysisTask, - PingCountTimerBukkit pingCountTimer, - LogsFolderCleanTask logsFolderCleanTask, - PlayersPageRefreshTask playersPageRefreshTask, - ConfigStoreTask configStoreTask, - DBCleanTask dbCleanTask, - ExtensionServerMethodCallerTask extensionServerMethodCallerTask - ) { - super( - runnableFactory, - Check.isPaperAvailable() ? paperTPSCountTimer : bukkitTPSCountTimer, - config, - bootAnalysisTask, - periodicAnalysisTask, - logsFolderCleanTask, - playersPageRefreshTask); - this.plugin = plugin; - this.shutdownHook = shutdownHook; - this.pingCountTimer = pingCountTimer; - this.configStoreTask = configStoreTask; - this.dbCleanTask = dbCleanTask; - this.extensionServerMethodCallerTask = extensionServerMethodCallerTask; - } - - @Override - public void enable() { - super.enable(); - try { - Long pingDelay = config.get(TimeSettings.PING_SERVER_ENABLE_DELAY); - if (pingDelay < TimeUnit.HOURS.toMillis(1L) && config.get(DataGatheringSettings.PING)) { - plugin.registerListener(pingCountTimer); - long startDelay = TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS); - registerTask(pingCountTimer).runTaskTimer(startDelay, 40L); - } - } catch (ExceptionInInitializerError | NoClassDefFoundError ignore) { - // Running CraftBukkit - } - - // +40 ticks / 2 seconds so that update check task runs first. - long storeDelay = TimeAmount.toTicks(config.get(TimeSettings.CONFIG_UPDATE_INTERVAL), TimeUnit.MILLISECONDS) + 40; - registerTask(configStoreTask).runTaskLaterAsynchronously(storeDelay); - - registerTask(dbCleanTask).runTaskTimerAsynchronously( - TimeAmount.toTicks(20, TimeUnit.SECONDS), - TimeAmount.toTicks(config.get(TimeSettings.CLEAN_DATABASE_PERIOD), TimeUnit.MILLISECONDS) - ); - - long extensionRefreshPeriod = TimeAmount.toTicks(config.get(TimeSettings.EXTENSION_DATA_REFRESH_PERIOD), TimeUnit.MILLISECONDS); - registerTask(extensionServerMethodCallerTask).runTaskTimerAsynchronously( - TimeAmount.toTicks(30, TimeUnit.SECONDS), extensionRefreshPeriod - ); - shutdownHook.register(); - } - - @Override - public void disable() { - super.disable(); - Optional.ofNullable(Bukkit.getScheduler()).ifPresent(scheduler -> scheduler.cancelTasks(plugin)); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BukkitTPSCountTimer.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BukkitTPSCountTimer.java deleted file mode 100644 index fd1b1206f..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/BukkitTPSCountTimer.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks.bukkit; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.builders.TPSBuilder; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.system.tasks.TPSCountTimer; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.World; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.concurrent.TimeUnit; - -@Singleton -public class BukkitTPSCountTimer extends TPSCountTimer { - - protected final Plan plugin; - private ServerProperties serverProperties; - private long lastCheckNano; - - @Inject - public BukkitTPSCountTimer( - Plan plugin, - DBSystem dbSystem, - ServerInfo serverInfo, - ServerProperties serverProperties, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(dbSystem, serverInfo, logger, errorHandler); - this.plugin = plugin; - this.serverProperties = serverProperties; - lastCheckNano = -1; - } - - @Override - public void addNewTPSEntry(long nanoTime, long now) { - long diff = nanoTime - lastCheckNano; - - lastCheckNano = nanoTime; - - if (diff > nanoTime) { // First run's diff = nanoTime + 1, no calc possible. - logger.debug("First run of TPSCountTimer Task."); - return; - } - - history.add(calculateTPS(diff, now)); - } - - /** - * Calculates the TPS - * - * @param diff The time difference between the last run and the new run - * @param now The time right now - * @return the TPS - */ - private TPS calculateTPS(long diff, long now) { - double averageCPUUsage = getCPUUsage(); - long usedMemory = getUsedMemory(); - long freeDiskSpace = getFreeDiskSpace(); - - int playersOnline = serverProperties.getOnlinePlayers(); - latestPlayersOnline = playersOnline; - int loadedChunks = getLoadedChunks(); - int entityCount = getEntityCount(); - - return getTPS(diff, now, averageCPUUsage, usedMemory, entityCount, loadedChunks, playersOnline, freeDiskSpace); - } - - protected TPS getTPS(long diff, long now, - double cpuUsage, long usedMemory, - int entityCount, int chunksLoaded, - int playersOnline, long freeDiskSpace) { - long difference = diff; - if (difference < TimeUnit.SECONDS.toNanos(1L)) { // No tick count above 20 - difference = TimeUnit.SECONDS.toNanos(1L); - } - - long twentySeconds = TimeUnit.SECONDS.toNanos(20L); - while (difference > twentySeconds) { - // Add 0 TPS since more than 20 ticks has passed. - history.add(TPSBuilder.get() - .date(now) - .tps(0) - .playersOnline(playersOnline) - .usedCPU(cpuUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(chunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS()); - difference -= twentySeconds; - } - - double tpsN = twentySeconds * 1.0 / difference; - - return TPSBuilder.get() - .date(now) - .tps(tpsN) - .playersOnline(playersOnline) - .usedCPU(cpuUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(chunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS(); - } - - /** - * Gets the amount of loaded chunks - * - * @return amount of loaded chunks - */ - private int getLoadedChunks() { - int sum = 0; - for (World world : plugin.getServer().getWorlds()) { - sum += world.getLoadedChunks().length; - } - return sum; - } - - /** - * Gets the amount of entities on the server for Bukkit / Spigot - * - * @return amount of entities - */ - protected int getEntityCount() { - int sum = 0; - for (World world : plugin.getServer().getWorlds()) { - sum += world.getEntities().size(); - } - return sum; - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PaperTPSCountTimer.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PaperTPSCountTimer.java deleted file mode 100644 index d0092fa3a..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PaperTPSCountTimer.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks.bukkit; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.builders.TPSBuilder; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.World; - -import javax.inject.Inject; - -public class PaperTPSCountTimer extends BukkitTPSCountTimer { - - @Inject - public PaperTPSCountTimer( - Plan plugin, - DBSystem dbSystem, - ServerInfo serverInfo, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(plugin, dbSystem, serverInfo, serverInfo.getServerProperties(), logger, errorHandler); - } - - @Override - protected TPS getTPS(long diff, long now, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded, int playersOnline, long freeDiskSpace) { - double tps; - try { - tps = plugin.getServer().getTPS()[0]; - } catch (NoSuchMethodError e) { - // This method is from Paper - return super.getTPS(diff, now, cpuUsage, usedMemory, entityCount, chunksLoaded, playersOnline, freeDiskSpace); - } - - if (tps > 20) { - tps = 20; - } - - return TPSBuilder.get() - .date(now) - .tps(tps) - .playersOnline(playersOnline) - .usedCPU(cpuUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(chunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS(); - } - - @Override - protected int getEntityCount() { - try { - return plugin.getServer().getWorlds().stream().mapToInt(World::getEntityCount).sum(); - } catch (BootstrapMethodError | NoSuchMethodError e) { - return super.getEntityCount(); - } - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PingCountTimerBukkit.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PingCountTimerBukkit.java deleted file mode 100644 index 3d98d62ba..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/tasks/bukkit/PingCountTimerBukkit.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2018 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.djrapitops.plan.system.tasks.bukkit; - -import com.djrapitops.plan.data.store.objects.DateObj; -import com.djrapitops.plan.db.access.transactions.events.PingStoreTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.utilities.java.Reflection; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandles.Lookup; -import java.lang.reflect.Method; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Task that handles player ping calculation on Bukkit based servers. - *

- * Modified PingManager from LagMonitor plugin. - * https://github.com/games647/LagMonitor/blob/master/src/main/java/com/github/games647/lagmonitor/task/PingManager.java - * - * @author games647 - */ -@Singleton -public class PingCountTimerBukkit extends AbsRunnable implements Listener { - - //the server is pinging the client every 40 Ticks (2 sec) - so check it then - //https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178 - - private static final boolean PING_METHOD_AVAILABLE; - - private static final MethodHandle PING_FIELD; - private static final MethodHandle GET_HANDLE_METHOD; - - static { - PING_METHOD_AVAILABLE = isPingMethodAvailable(); - - MethodHandle localHandle = null; - MethodHandle localPing = null; - if (!PING_METHOD_AVAILABLE) { - try { - Class craftPlayerClass = Reflection.getCraftBukkitClass("entity.CraftPlayer"); - Class entityPlayer = Reflection.getMinecraftClass("EntityPlayer"); - - Lookup lookup = MethodHandles.publicLookup(); - - Method getHandleMethod = craftPlayerClass.getDeclaredMethod("getHandle"); - localHandle = lookup.unreflect(getHandleMethod); - - localPing = lookup.findGetter(entityPlayer, "ping", Integer.TYPE); - } catch (NoSuchMethodException | IllegalAccessException | NoSuchFieldException reflectiveEx) { - Logger.getGlobal().log( - Level.WARNING, - "Plan: Reflective exception in static initializer of PingCountTimer", - reflectiveEx - ); - } catch (IllegalArgumentException e) { - Logger.getGlobal().log( - Level.WARNING, - "Plan: No Ping method handle found - Ping will not be recorded." - ); - } - } - - GET_HANDLE_METHOD = localHandle; - PING_FIELD = localPing; - } - - private final Map>> playerHistory; - - private final PlanConfig config; - private final DBSystem dbSystem; - private final ServerInfo serverInfo; - private final RunnableFactory runnableFactory; - - @Inject - public PingCountTimerBukkit( - PlanConfig config, - DBSystem dbSystem, - ServerInfo serverInfo, - RunnableFactory runnableFactory - ) { - this.config = config; - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.runnableFactory = runnableFactory; - playerHistory = new HashMap<>(); - } - - private static boolean isPingMethodAvailable() { - try { - //Only available in Paper - Class.forName("org.bukkit.entity.Player$Spigot").getDeclaredMethod("getPing"); - return true; - } catch (ClassNotFoundException | NoSuchMethodException noSuchMethodEx) { - return false; - } - } - - @Override - public void run() { - long time = System.currentTimeMillis(); - Iterator>>> iterator = playerHistory.entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry>> entry = iterator.next(); - UUID uuid = entry.getKey(); - List> history = entry.getValue(); - Player player = Bukkit.getPlayer(uuid); - if (player != null) { - int ping = getPing(player); - if (ping < -1 || ping > TimeUnit.SECONDS.toMillis(8L)) { - // Don't accept bad values - continue; - } - history.add(new DateObj<>(time, ping)); - if (history.size() >= 30) { - dbSystem.getDatabase().executeTransaction( - new PingStoreTransaction(uuid, serverInfo.getServerUUID(), new ArrayList<>(history)) - ); - history.clear(); - } - } else { - iterator.remove(); - } - } - } - - public void addPlayer(Player player) { - playerHistory.put(player.getUniqueId(), new ArrayList<>()); - } - - public void removePlayer(Player player) { - playerHistory.remove(player.getUniqueId()); - } - - private int getPing(Player player) { - if (PING_METHOD_AVAILABLE) { - // This method is from Paper - return player.spigot().getPing(); - } - - return getReflectionPing(player); - } - - private int getReflectionPing(Player player) { - try { - Object entityPlayer = GET_HANDLE_METHOD.invoke(player); - return (int) PING_FIELD.invoke(entityPlayer); - } catch (Exception ex) { - return -1; - } catch (Throwable throwable) { - throw (Error) throwable; - } - } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent joinEvent) { - Player player = joinEvent.getPlayer(); - Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY); - if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) { - return; - } - runnableFactory.create("Add Player to Ping list", new AbsRunnable() { - @Override - public void run() { - if (player.isOnline()) { - addPlayer(player); - } - } - }).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS)); - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent quitEvent) { - removePlayer(quitEvent.getPlayer()); - } - - public void clear() { - playerHistory.clear(); - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/utilities/java/Reflection.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/utilities/java/Reflection.java deleted file mode 100644 index b1a143beb..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/utilities/java/Reflection.java +++ /dev/null @@ -1,432 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2018 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.djrapitops.plan.utilities.java; - -import org.bukkit.Bukkit; -import org.bukkit.Server; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * An utility class that simplifies reflection in Bukkit plugins. - *

- * Modified Reflection utility from LagMonitor plugin. - * https://github.com/games647/LagMonitor/blob/master/src/main/java/com/github/games647/lagmonitor/traffic/Reflection.java - * - * @author Kristian - */ -public final class Reflection { - - // Deduce the net.minecraft.server.v* package - private static final String OBC_PREFIX = getOBCPrefix(); - private static final String NMS_PREFIX = OBC_PREFIX.replace("org.bukkit.craftbukkit", "net.minecraft.server"); - private static final String VERSION = OBC_PREFIX.replace("org.bukkit.craftbukkit", "").replace(".", ""); - // Variable replacement - private static final Pattern MATCH_VARIABLE = Pattern.compile("\\{([^\\}]+)\\}"); - - private Reflection() { - // Seal class - } - - private static String getOBCPrefix() { - Server server = Bukkit.getServer(); - return server != null ? server.getClass().getPackage().getName() : Server.class.getPackage().getName(); - } - - /** - * Retrieve a field accessor for a specific field type and name. - * - * @param target - the target type. - * @param name - the name of the field, or NULL to ignore. - * @param fieldType - a compatible field type. - * @return The field accessor. - */ - public static FieldAccessor getField(Class target, String name, Class fieldType) { - return getField(target, name, fieldType, 0); - } - - /** - * Retrieve a field accessor for a specific field type and name. - * - * @param className - lookup name of the class, see {@link #getClass(String)}. - * @param name - the name of the field, or NULL to ignore. - * @param fieldType - a compatible field type. - * @return The field accessor. - */ - public static FieldAccessor getField(String className, String name, Class fieldType) { - return getField(getClass(className), name, fieldType, 0); - } - - /** - * Retrieve a field accessor for a specific field type and name. - * - * @param target - the target type. - * @param fieldType - a compatible field type. - * @param index - the number of compatible fields to skip. - * @return The field accessor. - */ - public static FieldAccessor getField(Class target, Class fieldType, int index) { - return getField(target, null, fieldType, index); - } - - /** - * Retrieve a field accessor for a specific field type and name. - * - * @param className - lookup name of the class, see {@link #getClass(String)}. - * @param fieldType - a compatible field type. - * @param index - the number of compatible fields to skip. - * @return The field accessor. - */ - public static FieldAccessor getField(String className, Class fieldType, int index) { - return getField(getClass(className), fieldType, index); - } - - // Common method - private static FieldAccessor getField(Class target, String name, Class fieldType, int index) { - for (final Field field : target.getDeclaredFields()) { - if ((name == null || field.getName().equals(name)) && fieldType.isAssignableFrom(field.getType()) && index-- <= 0) { - field.setAccessible(true); - - // A function for retrieving a specific field value - return new FieldAccessor() { - - @Override - @SuppressWarnings("unchecked") - public T get(Object target) { - try { - return (T) field.get(target); - } catch (IllegalAccessException e) { - throw new IllegalStateException("Cannot access reflection.", e); - } - } - - @Override - public void set(Object target, Object value) { - try { - field.set(target, value); - } catch (IllegalAccessException e) { - throw new IllegalStateException("Cannot access reflection.", e); - } - } - - @Override - public boolean hasField(Object target) { - // target instanceof DeclaringClass - return field.getDeclaringClass().isAssignableFrom(target.getClass()); - } - }; - } - } - - // Search in parent classes - if (target.getSuperclass() != null) { - return getField(target.getSuperclass(), name, fieldType, index); - } - - throw new IllegalArgumentException("Cannot find field with type " + fieldType); - } - - /** - * Search for the first publicly and privately defined method of the given name and parameter count. - * - * @param className - lookup name of the class, see {@link #getClass(String)}. - * @param methodName - the method name, or NULL to skip. - * @param params - the expected parameters. - * @return An object that invokes this specific method. - * @throws IllegalStateException If we cannot find this method. - */ - public static MethodInvoker getMethod(String className, String methodName, Class... params) { - return getTypedMethod(getClass(className), methodName, null, params); - } - - /** - * Search for the first publicly and privately defined method of the given name and parameter count. - * - * @param clazz - a class to start with. - * @param methodName - the method name, or NULL to skip. - * @param params - the expected parameters. - * @return An object that invokes this specific method. - * @throws IllegalStateException If we cannot find this method. - */ - public static MethodInvoker getMethod(Class clazz, String methodName, Class... params) { - return getTypedMethod(clazz, methodName, null, params); - } - - /** - * Search for the first publicly and privately defined method of the given name and parameter count. - * - * @param clazz - a class to start with. - * @param methodName - the method name, or NULL to skip. - * @param returnType - the expected return type, or NULL to ignore. - * @param params - the expected parameters. - * @return An object that invokes this specific method. - * @throws IllegalStateException If we cannot find this method. - */ - public static MethodInvoker getTypedMethod(Class clazz, String methodName, Class returnType, Class... params) { - for (final Method method : clazz.getDeclaredMethods()) { - if ((methodName == null || method.getName().equals(methodName)) && (returnType == null) || method.getReturnType().equals(returnType) && Arrays.equals(method.getParameterTypes(), params)) { - method.setAccessible(true); - - return (target, arguments) -> { - try { - return method.invoke(target, arguments); - } catch (Exception e) { - throw new IllegalStateException("Cannot invoke method " + method, e); - } - }; - } - } - - // Search in every superclass - if (clazz.getSuperclass() != null) { - return getMethod(clazz.getSuperclass(), methodName, params); - } - - throw new IllegalStateException(String.format("Unable to find method %s (%s).", methodName, Arrays.asList(params))); - } - - /** - * Search for the first publicly and privately defined constructor of the given name and parameter count. - * - * @param className - lookup name of the class, see {@link #getClass(String)}. - * @param params - the expected parameters. - * @return An object that invokes this constructor. - * @throws IllegalStateException If we cannot find this method. - */ - public static ConstructorInvoker getConstructor(String className, Class... params) { - return getConstructor(getClass(className), params); - } - - /** - * Search for the first publicly and privately defined constructor of the given name and parameter count. - * - * @param clazz - a class to start with. - * @param params - the expected parameters. - * @return An object that invokes this constructor. - * @throws IllegalStateException If we cannot find this method. - */ - public static ConstructorInvoker getConstructor(Class clazz, Class... params) { - for (final Constructor constructor : clazz.getDeclaredConstructors()) { - if (Arrays.equals(constructor.getParameterTypes(), params)) { - constructor.setAccessible(true); - - return arguments -> { - try { - return constructor.newInstance(arguments); - } catch (Exception e) { - throw new IllegalStateException("Cannot invoke constructor " + constructor, e); - } - }; - } - } - - throw new IllegalStateException(String.format("Unable to find constructor for %s (%s).", clazz, Arrays.asList(params))); - } - - /** - * Retrieve a class from its full name, without knowing its type on compile time. - *

- * This is useful when looking up fields by a NMS or OBC type. - *

- * - * @param lookupName - the class name with variables. - * @return The class. - * @see Object#getClass() - */ - public static Class getUntypedClass(String lookupName) { - @SuppressWarnings({"rawtypes", "unchecked"}) - Class clazz = (Class) getClass(lookupName); - return clazz; - } - - /** - * Retrieve a class from its full name. - *

- * Strings enclosed with curly brackets - such as {TEXT} - will be replaced according to the following table: - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
VariableContent
{nms}Actual package name of net.minecraft.server.VERSION
{obc}Actual package name of org.bukkit.craftbukkit.VERSION
{version}The current Minecraft package VERSION, if any.
- * - * @param lookupName - the class name with variables. - * @return The looked up class. - * @throws IllegalArgumentException If a variable or class could not be found. - */ - public static Class getClass(String lookupName) { - return getCanonicalClass(expandVariables(lookupName)); - } - - /** - * Retrieve a class in the net.minecraft.server.VERSION.* package. - * - * @param name - the name of the class, excluding the package. - * @throws IllegalArgumentException If the class doesn't exist. - */ - public static Class getMinecraftClass(String name) { - return getCanonicalClass(NMS_PREFIX + '.' + name); - } - - /** - * Retrieve a class in the org.bukkit.craftbukkit.VERSION.* package. - * - * @param name - the name of the class, excluding the package. - * @throws IllegalArgumentException If the class doesn't exist. - */ - public static Class getCraftBukkitClass(String name) { - return getCanonicalClass(OBC_PREFIX + '.' + name); - } - - /** - * Retrieve a class by its canonical name. - * - * @param canonicalName - the canonical name. - * @return The class. - */ - private static Class getCanonicalClass(String canonicalName) { - try { - return Class.forName(canonicalName); - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Cannot find " + canonicalName, e); - } - } - - /** - * Expand variables such as "{nms}" and "{obc}" to their corresponding packages. - * - * @param name - the full name of the class. - * @return The expanded string. - */ - private static String expandVariables(String name) { - StringBuffer output = new StringBuffer(); - Matcher matcher = MATCH_VARIABLE.matcher(name); - - while (matcher.find()) { - String variable = matcher.group(1); - String replacement; - - // Expand all detected variables - if ("nms".equalsIgnoreCase(variable)) { - replacement = NMS_PREFIX; - } else if ("obc".equalsIgnoreCase(variable)) { - replacement = OBC_PREFIX; - } else if ("version".equalsIgnoreCase(variable)) { - replacement = VERSION; - } else { - throw new IllegalArgumentException("Unknown variable: " + variable); - } - - // Assume the expanded variables are all packages, and append a dot - if (!replacement.isEmpty() && matcher.end() < name.length() && name.charAt(matcher.end()) != '.') { - replacement += "."; - } - matcher.appendReplacement(output, Matcher.quoteReplacement(replacement)); - } - - matcher.appendTail(output); - return output.toString(); - } - - /** - * An interface for invoking a specific constructor. - */ - @FunctionalInterface - public interface ConstructorInvoker { - - /** - * Invoke a constructor for a specific class. - * - * @param arguments - the arguments to pass to the constructor. - * @return The constructed object. - */ - Object invoke(Object... arguments); - } - - /** - * An interface for invoking a specific method. - */ - @FunctionalInterface - public interface MethodInvoker { - - /** - * Invoke a method on a specific target object. - * - * @param target - the target object, or NULL for a static method. - * @param arguments - the arguments to pass to the method. - * @return The return value, or NULL if is void. - */ - Object invoke(Object target, Object... arguments); - } - - /** - * An interface for retrieving the field content. - * - * @param - field type. - */ - public interface FieldAccessor { - - /** - * Retrieve the content of a field. - * - * @param target - the target object, or NULL for a static field. - * @return The value of the field. - */ - T get(Object target); - - /** - * Set the content of a field. - * - * @param target - the target object, or NULL for a static field. - * @param value - the new value of the field. - */ - void set(Object target, Object value); - - /** - * Determine if the given object has this field. - * - * @param target - the object to test. - * @return TRUE if it does, FALSE otherwise. - */ - boolean hasField(Object target); - } -} diff --git a/Plan/bukkit/src/test/java/com/djrapitops/plan/BukkitSystemTest.java b/Plan/bukkit/src/test/java/com/djrapitops/plan/BukkitSystemTest.java deleted file mode 100644 index 65f0fabcc..000000000 --- a/Plan/bukkit/src/test/java/com/djrapitops/plan/BukkitSystemTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.system.PlanSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.settings.ConfigSettingKeyTest; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.WebserverSettings; -import com.djrapitops.plan.system.settings.paths.key.Setting; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import rules.BukkitComponentMocker; -import rules.ComponentMocker; -import utilities.OptionalAssert; -import utilities.RandomData; - -import java.util.Collection; -import java.util.Optional; - -import static org.junit.Assert.assertTrue; - -/** - * Test for Bukkit PlanSystem. - * - * @author Rsl1122 - */ -@RunWith(MockitoJUnitRunner.Silent.class) -public class BukkitSystemTest { - - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @Rule - public ComponentMocker component = new BukkitComponentMocker(temporaryFolder); - - private final int TEST_PORT_NUMBER = RandomData.randomInt(9005, 9500); - private PlanSystem system; - - @Before - public void prepareSystem() { - system = component.getPlanSystem(); - system.getConfigSystem().getConfig() - .set(WebserverSettings.PORT, TEST_PORT_NUMBER); - } - - @Test - public void bukkitSystemEnables() throws EnableException { - try { - system.enable(); - assertTrue(system.isEnabled()); - } finally { - system.disable(); - } - } - - @Test - public void correctWebAddressInDatabaseAfterEnable() throws EnableException { - try { - system.enable(); - Database database = system.getDatabaseSystem().getDatabase(); - String expectedAddress = system.getWebServerSystem().getWebServer().getAccessAddress(); - Optional found = database.query(ServerQueries.fetchServerMatchingIdentifier(system.getServerInfo().getServerUUID())) - .map(Server::getWebAddress); - - OptionalAssert.equals(expectedAddress, found); - } finally { - system.disable(); - } - } - - @Test - public void bukkitSystemHasDefaultConfigValuesAfterEnable() throws EnableException, IllegalAccessException { - try { - system.enable(); - PlanConfig config = system.getConfigSystem().getConfig(); - - Collection serverSettings = ConfigSettingKeyTest.getServerSettings(); - ConfigSettingKeyTest.assertValidDefaultValuesForAllSettings(config, serverSettings); - } finally { - system.disable(); - } - } -} diff --git a/Plan/bukkit/src/test/java/com/djrapitops/plan/system/listeners/AFKListenerTest.java b/Plan/bukkit/src/test/java/com/djrapitops/plan/system/listeners/AFKListenerTest.java deleted file mode 100644 index a7e5270ca..000000000 --- a/Plan/bukkit/src/test/java/com/djrapitops/plan/system/listeners/AFKListenerTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners; - -import com.djrapitops.plan.system.listeners.bukkit.AFKListener; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plugin.logging.console.TestPluginLogger; -import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerMoveEvent; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; -import utilities.TestConstants; - -import java.util.concurrent.TimeUnit; - -import static org.mockito.Mockito.*; - -/** - * Test for {@link AFKListener} - * - * @author Rsl1122 - */ -public class AFKListenerTest { - - private AFKListener underTest; - - @Before - public void setUp() { - PlanConfig config = Mockito.mock(PlanConfig.class); - when(config.get(TimeSettings.AFK_THRESHOLD)).thenReturn(TimeUnit.MINUTES.toMillis(3)); - underTest = new AFKListener(config, new ConsoleErrorLogger(new TestPluginLogger())); - } - - @Test - public void afkPermissionIsNotCalledMoreThanOnce() { - Player player = mockPlayer(); - PlayerMoveEvent event = mockMoveEvent(player); - - underTest.onMove(event); - underTest.onMove(event); - - verify(player, times(1)).hasPermission(anyString()); - } - - private PlayerMoveEvent mockMoveEvent(Player player) { - PlayerMoveEvent event = Mockito.mock(PlayerMoveEvent.class); - when(event.getPlayer()).thenReturn(player); - return event; - } - - private Player mockPlayer() { - Player player = Mockito.mock(Player.class); - when(player.getUniqueId()).thenReturn(TestConstants.PLAYER_ONE_UUID); - when(player.hasPermission(anyString())).thenReturn(true); - return player; - } - -} \ No newline at end of file diff --git a/Plan/bukkit/src/test/java/rules/BukkitComponentMocker.java b/Plan/bukkit/src/test/java/rules/BukkitComponentMocker.java deleted file mode 100644 index 090dbde41..000000000 --- a/Plan/bukkit/src/test/java/rules/BukkitComponentMocker.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package rules; - -import com.djrapitops.plan.DaggerPlanBukkitComponent; -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.PlanBukkitComponent; -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.PlanSystem; -import org.junit.rules.ExternalResource; -import org.junit.rules.TemporaryFolder; -import utilities.mocks.PlanBukkitMocker; - -public class BukkitComponentMocker extends ExternalResource implements ComponentMocker { - - private final TemporaryFolder testFolder; - - private Plan planMock; - private PlanBukkitComponent component; - - public BukkitComponentMocker(TemporaryFolder testFolder) { - this.testFolder = testFolder; - } - - @Override - protected void before() throws Throwable { - PlanBukkitMocker mocker = PlanBukkitMocker.setUp() - .withDataFolder(testFolder.newFolder()) - .withPluginDescription() - .withResourceFetchingFromJar() - .withServer(); - planMock = mocker.getPlanMock(); - component = DaggerPlanBukkitComponent.builder().plan(planMock).build(); - } - - public PlanPlugin getPlanMock() { - return planMock; - } - - public PlanSystem getPlanSystem() { - return component.system(); - } -} diff --git a/Plan/bukkit/src/test/java/utilities/mocks/PlanBukkitMocker.java b/Plan/bukkit/src/test/java/utilities/mocks/PlanBukkitMocker.java deleted file mode 100644 index 0b3312349..000000000 --- a/Plan/bukkit/src/test/java/utilities/mocks/PlanBukkitMocker.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package utilities.mocks; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plugin.benchmarking.Timings; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.console.TestPluginLogger; -import com.djrapitops.plugin.logging.debug.CombineDebugLogger; -import com.djrapitops.plugin.logging.debug.DebugLogger; -import com.djrapitops.plugin.logging.debug.MemoryDebugLogger; -import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.RunnableFactory; -import org.bukkit.Server; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.plugin.InvalidDescriptionException; -import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.scheduler.BukkitScheduler; -import org.mockito.Mockito; -import utilities.TestConstants; -import utilities.mocks.objects.TestLogger; -import utilities.mocks.objects.TestRunnableFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; - -import static org.mockito.Mockito.doReturn; - -/** - * Mocking Utility for Bukkit version of Plan. - * - * @author Rsl1122 - */ -public class PlanBukkitMocker extends Mocker { - - private Plan planMock; - - private PlanBukkitMocker() { - } - - public static PlanBukkitMocker setUp() { - return new PlanBukkitMocker().mockPlugin(); - } - - private PlanBukkitMocker mockPlugin() { - planMock = Mockito.mock(Plan.class); - super.planMock = planMock; - - doReturn(new ColorScheme("§1", "§2", "§3")).when(planMock).getColorScheme(); - doReturn("1.0.0").when(planMock).getVersion(); - - TestLogger testLogger = new TestLogger(); - RunnableFactory runnableFactory = new TestRunnableFactory(); - PluginLogger testPluginLogger = new TestPluginLogger(); - DebugLogger debugLogger = new CombineDebugLogger(new MemoryDebugLogger()); - ErrorHandler consoleErrorLogger = new ConsoleErrorLogger(testPluginLogger); - Timings timings = new Timings(debugLogger); - - Mockito.doReturn(testLogger).when(planMock).getLogger(); - doReturn(runnableFactory).when(planMock).getRunnableFactory(); - doReturn(testPluginLogger).when(planMock).getPluginLogger(); - doReturn(debugLogger).when(planMock).getDebugLogger(); - doReturn(consoleErrorLogger).when(planMock).getErrorHandler(); - doReturn(timings).when(planMock).getTimings(); - - return this; - } - - public PlanBukkitMocker withDataFolder(File tempFolder) { - doReturn(tempFolder).when(planMock).getDataFolder(); - return this; - } - - @Deprecated - public PlanBukkitMocker withLogging() { - return this; - } - - public PlanBukkitMocker withPluginDescription() { - try { - File pluginYml = getFile("/plugin.yml"); - PluginDescriptionFile description = new PluginDescriptionFile(new FileInputStream(pluginYml)); - doReturn(description).when(planMock).getDescription(); - } catch (FileNotFoundException | InvalidDescriptionException e) { - System.out.println("Error while setting plugin description"); - } - return this; - } - - public PlanBukkitMocker withResourceFetchingFromJar() throws IOException { - withPluginFiles(); - return this; - } - - public PlanBukkitMocker withServer() { - Server serverMock = Mockito.mock(Server.class); - doReturn("").when(serverMock).getIp(); - doReturn("Bukkit").when(serverMock).getName(); - doReturn("Bukkit").when(serverMock).getServerName(); - doReturn(25565).when(serverMock).getPort(); - doReturn("1.12.2").when(serverMock).getVersion(); - doReturn("32423").when(serverMock).getBukkitVersion(); - Mockito.doReturn(TestConstants.BUKKIT_MAX_PLAYERS).when(serverMock).getMaxPlayers(); - ConsoleCommandSender sender = Mockito.mock(ConsoleCommandSender.class); - doReturn(sender).when(serverMock).getConsoleSender(); - - BukkitScheduler bukkitScheduler = Mockito.mock(BukkitScheduler.class); - doReturn(bukkitScheduler).when(serverMock).getScheduler(); - - doReturn(serverMock).when(planMock).getServer(); - return this; - } - - public Plan getPlanMock() { - return planMock; - } -} diff --git a/Plan/bukkit/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/Plan/bukkit/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea..000000000 --- a/Plan/bukkit/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/Plan/bungeecord/build.gradle b/Plan/bungeecord/build.gradle deleted file mode 100644 index 8c5548cc6..000000000 --- a/Plan/bungeecord/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ -dependencies { - compile project(path: ":common", configuration: 'shadow') - - compile "com.djrapitops:AbstractPluginFramework-bungeecord:$abstractPluginFrameworkVersion" - compile "org.bstats:bstats-bungeecord:$bstatsVersion" - - compileOnly "net.md-5:bungeecord-api:$bungeeVersion" - compileOnly "com.imaginarycode.minecraft:RedisBungee:$redisBungeeVersion" - testCompile "net.md-5:bungeecord-api:$bungeeVersion" - testCompile "com.imaginarycode.minecraft:RedisBungee:$redisBungeeVersion" - - testCompile project(path: ":common", configuration: 'testArtifacts') -} - -shadowJar { - configurations = [project.configurations.compile] - - relocate 'org.bstats', 'com.djrapitops.plan.utilities.metrics' - relocate 'org.slf4j', 'plan.org.slf4j' -} \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/BStatsBungee.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/BStatsBungee.java deleted file mode 100644 index 52d524a72..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/BStatsBungee.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import org.bstats.bungeecord.Metrics; - -import java.io.Serializable; - -public class BStatsBungee { - - private final PlanBungee plugin; - private final Database database; - private final ConnectionSystem connectionSystem; - - private Metrics metrics; - - public BStatsBungee(PlanBungee plugin, Database database, ConnectionSystem connectionSystem) { - this.plugin = plugin; - this.database = database; - this.connectionSystem = connectionSystem; - } - - public void registerMetrics() { - if (metrics == null) { - metrics = new Metrics(plugin); - } - registerConfigSettingGraphs(); - } - - private void registerConfigSettingGraphs() { - String serverType = plugin.getProxy().getName(); - String databaseType = database.getType().getName(); - - addStringSettingPie("server_type", serverType); - addStringSettingPie("database_type", databaseType); - addStringSettingPie("network_servers", connectionSystem.getDataServers().size()); - } - - protected void addStringSettingPie(String id, Serializable setting) { - metrics.addCustomChart(new Metrics.SimplePie(id, setting::toString)); - } -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/PlanBungee.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/PlanBungee.java deleted file mode 100644 index 8972a7d3e..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/PlanBungee.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.command.PlanProxyCommand; -import com.djrapitops.plan.system.PlanSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.settings.theme.PlanColorScheme; -import com.djrapitops.plugin.BungeePlugin; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.logging.L; - -import java.io.InputStream; - -/** - * Bungee Main class. - * - * @author Rsl1122 - */ -public class PlanBungee extends BungeePlugin implements PlanPlugin { - - private PlanSystem system; - private Locale locale; - - @Override - public void onEnable() { - PlanBungeeComponent component = DaggerPlanBungeeComponent.builder().plan(this).build(); - try { - system = component.system(); - locale = system.getLocaleSystem().getLocale(); - system.enable(); - - new BStatsBungee( - this, - system.getDatabaseSystem().getDatabase(), - system.getInfoSystem().getConnectionSystem() - ).registerMetrics(); - - logger.info(locale.getString(PluginLang.ENABLED)); - } catch (AbstractMethodError e) { - logger.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); - } catch (EnableException e) { - logger.error("----------------------------------------"); - logger.error("Error: " + e.getMessage()); - logger.error("----------------------------------------"); - logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planbungee reload"); - onDisable(); - } catch (Exception e) { - errorHandler.log(L.CRITICAL, this.getClass(), e); - logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planbungee reload"); - logger.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); - onDisable(); - } - PlanProxyCommand command = component.planCommand(); - command.registerCommands(); - registerCommand("planbungee", command); - if (system != null) { - system.getProcessing().submitNonCritical(() -> system.getListenerSystem().callEnableEvent(this)); - } - } - - @Override - public void onDisable() { - if (system != null) system.disable(); - - logger.info(locale.getString(PluginLang.DISABLED)); - } - - @Override - public String getVersion() { - return super.getDescription().getVersion(); - } - - @Override - public void onReload() { - // Nothing to be done, systems are disabled - } - - @Override - public InputStream getResource(String resource) { - return getResourceAsStream(resource); - } - - @Override - public ColorScheme getColorScheme() { - return PlanColorScheme.create(system.getConfigSystem().getConfig(), logger); - } - - @Override - public PlanSystem getSystem() { - return system; - } - - @Override - public boolean isReloading() { - return reloading; - } -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/PlanBungeeComponent.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/PlanBungeeComponent.java deleted file mode 100644 index 9fba65e39..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/PlanBungeeComponent.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.command.PlanProxyCommand; -import com.djrapitops.plan.modules.APFModule; -import com.djrapitops.plan.modules.FilesModule; -import com.djrapitops.plan.modules.ProxySuperClassBindingModule; -import com.djrapitops.plan.modules.SystemObjectProvidingModule; -import com.djrapitops.plan.modules.bungee.BungeeCommandModule; -import com.djrapitops.plan.modules.bungee.BungeePlanModule; -import com.djrapitops.plan.modules.bungee.BungeeServerPropertiesModule; -import com.djrapitops.plan.modules.bungee.BungeeSuperClassBindingModule; -import com.djrapitops.plan.system.PlanSystem; -import com.djrapitops.pluginbridge.plan.PluginBridgeModule; -import dagger.BindsInstance; -import dagger.Component; - -import javax.inject.Singleton; - -/** - * Dagger Component that constructs the plugin systems running on Bungee. - * - * @author Rsl1122 - */ -@Singleton -@Component(modules = { - BungeePlanModule.class, - BungeeCommandModule.class, - SystemObjectProvidingModule.class, - APFModule.class, - FilesModule.class, - ProxySuperClassBindingModule.class, - BungeeSuperClassBindingModule.class, - BungeeServerPropertiesModule.class, - PluginBridgeModule.Bungee.class -}) -public interface PlanBungeeComponent { - - PlanProxyCommand planCommand(); - - PlanSystem system(); - - @Component.Builder - interface Builder { - - @BindsInstance - Builder plan(PlanBungee plan); - - PlanBungeeComponent build(); - } -} \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/api/events/PlanBungeeEnableEvent.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/api/events/PlanBungeeEnableEvent.java deleted file mode 100644 index 0d074caed..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/api/events/PlanBungeeEnableEvent.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.events; - -import net.md_5.bungee.api.plugin.Event; - -/** - * Event that is called when Plan is enabled. - *

- * This includes, but might not be limited to: - * - First time the plugin enables successfully - * - Plan is reloaded - * - Plan is enabled after it was disabled - *

- * {@code event.isPlanSystemEnabled()} can be called to determine if the enable was successful. - * It is not guaranteed that this event is called when the plugin fails to enable properly. - * - * @author Rsl1122 - */ -public class PlanBungeeEnableEvent extends Event { - - private final boolean enabled; - - public PlanBungeeEnableEvent(boolean enabled) { - this.enabled = enabled; - } - - public boolean isPlanSystemEnabled() { - return enabled; - } - -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeCommandModule.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeCommandModule.java deleted file mode 100644 index 9c5952c9b..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeCommandModule.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules.bungee; - -import dagger.Module; -import dagger.Provides; - -import javax.inject.Named; - -@Module -public class BungeeCommandModule { - - @Provides - @Named("mainCommandName") - String provideMainCommandName() { - return "planbungee"; - } -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeePlanModule.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeePlanModule.java deleted file mode 100644 index 39b041797..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeePlanModule.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules.bungee; - -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.command.PlanProxyCommand; -import com.djrapitops.plugin.command.CommandNode; -import dagger.Binds; -import dagger.Module; - -import javax.inject.Named; - -/** - * Dagger module for binding PlanBungee instance. - * - * @author Rsl1122 - */ -@Module -public interface BungeePlanModule { - - @Binds - PlanPlugin bindPlanPlugin(PlanBungee plugin); - - @Binds - @Named("mainCommand") - CommandNode bindMainCommand(PlanProxyCommand command); -} \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeServerPropertiesModule.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeServerPropertiesModule.java deleted file mode 100644 index 222e7838b..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeServerPropertiesModule.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules.bungee; - -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plan.system.info.server.properties.BungeeServerProperties; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import dagger.Module; -import dagger.Provides; - -import javax.inject.Singleton; - -/** - * Dagger module for Bungee ServerProperties. - * - * @author Rsl1122 - */ -@Module -public class BungeeServerPropertiesModule { - - @Provides - @Singleton - ServerProperties provideServerProperties(PlanBungee plugin, PlanConfig config) { - return new BungeeServerProperties(plugin.getProxy(), config); - } -} \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeSuperClassBindingModule.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeSuperClassBindingModule.java deleted file mode 100644 index 6727fd74b..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeSuperClassBindingModule.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules.bungee; - -import com.djrapitops.plan.system.info.server.BungeeServerInfo; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.listeners.BungeeListenerSystem; -import com.djrapitops.plan.system.listeners.ListenerSystem; -import com.djrapitops.plan.system.tasks.BungeeTaskSystem; -import com.djrapitops.plan.system.tasks.TaskSystem; -import dagger.Binds; -import dagger.Module; - -/** - * Module for binding Bungee specific classes to the interface implementations. - * - * @author Rsl1122 - */ -@Module -public interface BungeeSuperClassBindingModule { - - @Binds - ServerInfo bindBungeeServerInfo(BungeeServerInfo bungeeServerInfo); - - @Binds - TaskSystem bindBungeeTaskSystem(BungeeTaskSystem bungeeTaskSystem); - - @Binds - ListenerSystem bindBungeeListenerSystem(BungeeListenerSystem bungeeListenerSystem); -} \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java deleted file mode 100644 index dfa5627b4..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.transactions.StoreServerInformationTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.logging.console.PluginLogger; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.ExecutionException; - -/** - * Manages Server information on the Bungee instance. - * - * @author Rsl1122 - */ -@Singleton -public class BungeeServerInfo extends ServerInfo { - - private final DBSystem dbSystem; - private final Lazy webServer; - private final PluginLogger logger; - - @Inject - public BungeeServerInfo( - ServerProperties serverProperties, - DBSystem dbSystem, - Lazy webServer, - PluginLogger logger - ) { - super(serverProperties); - this.dbSystem = dbSystem; - this.webServer = webServer; - this.logger = logger; - } - - @Override - public void loadServerInfo() throws EnableException { - checkIfDefaultIP(); - - try { - Database database = dbSystem.getDatabase(); - Optional proxyInfo = database.query(ServerQueries.fetchProxyServerInformation()); - if (proxyInfo.isPresent()) { - server = proxyInfo.get(); - updateServerInfo(database); - } else { - server = registerBungeeInfo(database); - } - } catch (DBOpException | ExecutionException e) { - throw new EnableException("Failed to read Server information from Database."); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - private void updateServerInfo(Database db) { - String accessAddress = webServer.get().getAccessAddress(); - if (!accessAddress.equals(server.getWebAddress())) { - server.setWebAddress(accessAddress); - db.executeTransaction(new StoreServerInformationTransaction(server)); - } - } - - private void checkIfDefaultIP() throws EnableException { - String ip = serverProperties.getIp(); - if ("0.0.0.0".equals(ip)) { - logger.error("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); - logger.info("Player Analytics partially enabled (Use /planbungee to reload config)"); - throw new EnableException("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); - } - } - - private Server registerBungeeInfo(Database db) throws EnableException, ExecutionException, InterruptedException { - UUID serverUUID = generateNewUUID(); - String accessAddress = webServer.get().getAccessAddress(); - - Server proxy = new Server(-1, serverUUID, "BungeeCord", accessAddress, serverProperties.getMaxPlayers()); - db.executeTransaction(new StoreServerInformationTransaction(proxy)) - .get(); - - Optional proxyInfo = db.query(ServerQueries.fetchProxyServerInformation()); - if (proxyInfo.isPresent()) { - return proxyInfo.get(); - } - throw new EnableException("BungeeCord registration failed (DB)"); - } -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java deleted file mode 100644 index 424ac8494..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server.properties; - -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.ProxySettings; -import net.md_5.bungee.api.ProxyServer; - -/** - * ServerProperties for Bungee. - *

- * Supports RedisBungee for Players online getting. - * - * @author Rsl1122 - */ -public class BungeeServerProperties extends ServerProperties { - - public BungeeServerProperties(ProxyServer server, PlanConfig config) { - super( - "BungeeCord", - -1, - server.getVersion(), - server.getVersion(), - () -> config.get(ProxySettings.IP), - server.getConfig().getPlayerLimit(), - RedisCheck.isClassAvailable() ? new RedisPlayersOnlineSupplier() : server::getOnlineCount - ); - } -} \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisCheck.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisCheck.java deleted file mode 100644 index b2aafd857..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisCheck.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server.properties; - -import com.djrapitops.plugin.api.Check; - -/** - * Utility class for checking if RedisBungee API is available. - * - * @author Rsl1122 - */ -public class RedisCheck { - - private RedisCheck() { - /* Static method class */ - } - - public static boolean isClassAvailable() { - return Check.isAvailable("com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI"); - } - -} \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisPlayersOnlineSupplier.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisPlayersOnlineSupplier.java deleted file mode 100644 index bfbc2898d..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/properties/RedisPlayersOnlineSupplier.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server.properties; - -import com.imaginarycode.minecraft.redisbungee.RedisBungee; - -import java.util.function.IntSupplier; - -/** - * Players online supplier when using RedisBungee. - * - * @author Rsl1122 - */ -public class RedisPlayersOnlineSupplier implements IntSupplier { - - @Override - public int getAsInt() { - return RedisBungee.getApi().getPlayerCount(); - } -} \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java deleted file mode 100644 index 722ed46dd..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners; - -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.api.events.PlanBungeeEnableEvent; -import com.djrapitops.plan.capability.CapabilityServiceImplementation; -import com.djrapitops.plan.system.listeners.bungee.PlayerOnlineListener; - -import javax.inject.Inject; - -public class BungeeListenerSystem extends ListenerSystem { - - private final PlanBungee plugin; - private PlayerOnlineListener playerOnlineListener; - - @Inject - public BungeeListenerSystem(PlanBungee plugin, PlayerOnlineListener playerOnlineListener) { - this.plugin = plugin; - this.playerOnlineListener = playerOnlineListener; - } - - @Override - protected void registerListeners() { - plugin.registerListener(playerOnlineListener); - } - - @Override - protected void unregisterListeners() { - plugin.getProxy().getPluginManager().unregisterListeners(plugin); - } - - @Override - public void callEnableEvent(PlanPlugin plugin) { - boolean isEnabled = plugin.isSystemEnabled(); - PlanBungeeEnableEvent event = new PlanBungeeEnableEvent(isEnabled); - ((PlanBungee) plugin).getProxy().getPluginManager().callEvent(event); - CapabilityServiceImplementation.notifyAboutEnable(isEnabled); - } -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java deleted file mode 100644 index 6b7863b98..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners.bungee; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.events.GeoInfoStoreTransaction; -import com.djrapitops.plan.db.access.transactions.events.PlayerRegisterTransaction; -import com.djrapitops.plan.extension.CallEvents; -import com.djrapitops.plan.extension.ExtensionServiceImplementation; -import com.djrapitops.plan.system.cache.GeolocationCache; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.Processors; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DataGatheringSettings; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.PlayerDisconnectEvent; -import net.md_5.bungee.api.event.PostLoginEvent; -import net.md_5.bungee.api.event.ServerSwitchEvent; -import net.md_5.bungee.api.plugin.Listener; -import net.md_5.bungee.event.EventHandler; -import net.md_5.bungee.event.EventPriority; - -import javax.inject.Inject; -import java.net.InetAddress; -import java.util.UUID; - -/** - * Player Join listener for Bungee. - * - * @author Rsl1122 - */ -public class PlayerOnlineListener implements Listener { - - private final PlanConfig config; - private final Processors processors; - private final Processing processing; - private final DBSystem dbSystem; - private final ExtensionServiceImplementation extensionService; - private final GeolocationCache geolocationCache; - private final SessionCache sessionCache; - private final ServerInfo serverInfo; - private final ErrorHandler errorHandler; - - @Inject - public PlayerOnlineListener( - PlanConfig config, - Processors processors, - Processing processing, - DBSystem dbSystem, - ExtensionServiceImplementation extensionService, - GeolocationCache geolocationCache, - SessionCache sessionCache, - ServerInfo serverInfo, - ErrorHandler errorHandler - ) { - this.config = config; - this.processors = processors; - this.processing = processing; - this.dbSystem = dbSystem; - this.extensionService = extensionService; - this.geolocationCache = geolocationCache; - this.sessionCache = sessionCache; - this.serverInfo = serverInfo; - this.errorHandler = errorHandler; - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onPostLogin(PostLoginEvent event) { - try { - ProxiedPlayer player = event.getPlayer(); - UUID playerUUID = player.getUniqueId(); - String playerName = player.getName(); - InetAddress address = player.getAddress().getAddress(); - long time = System.currentTimeMillis(); - - sessionCache.cacheSession(playerUUID, new Session(playerUUID, serverInfo.getServerUUID(), time, null, null)); - Database database = dbSystem.getDatabase(); - - boolean gatheringGeolocations = config.isTrue(DataGatheringSettings.GEOLOCATIONS); - if (gatheringGeolocations) { - database.executeTransaction( - new GeoInfoStoreTransaction(playerUUID, address, time, geolocationCache::getCountry) - ); - } - - database.executeTransaction(new PlayerRegisterTransaction(playerUUID, () -> time, playerName)); - processing.submit(processors.info().playerPageUpdateProcessor(playerUUID)); - processing.submitNonCritical(() -> extensionService.updatePlayerValues(playerUUID, playerName, CallEvents.PLAYER_JOIN)); - ResponseCache.clearResponse(PageId.SERVER.of(serverInfo.getServerUUID())); - } catch (Exception e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - @EventHandler(priority = EventPriority.NORMAL) - public void beforeLogout(PlayerDisconnectEvent event) { - ProxiedPlayer player = event.getPlayer(); - UUID playerUUID = player.getUniqueId(); - String playerName = player.getName(); - processing.submitNonCritical(() -> extensionService.updatePlayerValues(playerUUID, playerName, CallEvents.PLAYER_LEAVE)); - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onLogout(PlayerDisconnectEvent event) { - try { - ProxiedPlayer player = event.getPlayer(); - UUID playerUUID = player.getUniqueId(); - - sessionCache.endSession(playerUUID, System.currentTimeMillis()); - processing.submit(processors.info().playerPageUpdateProcessor(playerUUID)); - ResponseCache.clearResponse(PageId.SERVER.of(serverInfo.getServerUUID())); - } catch (Exception e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - @EventHandler(priority = EventPriority.HIGHEST) - public void onServerSwitch(ServerSwitchEvent event) { - try { - ProxiedPlayer player = event.getPlayer(); - UUID playerUUID = player.getUniqueId(); - - long time = System.currentTimeMillis(); - // Replaces the current session in the cache. - sessionCache.cacheSession(playerUUID, new Session(playerUUID, serverInfo.getServerUUID(), time, null, null)); - processing.submit(processors.info().playerPageUpdateProcessor(playerUUID)); - } catch (Exception e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java deleted file mode 100644 index dca6baaa5..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks; - -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plan.db.tasks.DBCleanTask; -import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DataGatheringSettings; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.system.tasks.bungee.BungeeTPSCountTimer; -import com.djrapitops.plan.system.tasks.bungee.PingCountTimerBungee; -import com.djrapitops.plan.system.tasks.proxy.NetworkConfigStoreTask; -import com.djrapitops.plan.system.tasks.proxy.NetworkPageRefreshTask; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.task.RunnableFactory; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.concurrent.TimeUnit; - -/** - * TaskSystem responsible for registering tasks for Bungee. - * - * @author Rsl1122 - */ -@Singleton -public class BungeeTaskSystem extends TaskSystem { - - private final PlanBungee plugin; - private final PlanConfig config; - private final NetworkPageRefreshTask networkPageRefreshTask; - private final PingCountTimerBungee pingCountTimer; - private final LogsFolderCleanTask logsFolderCleanTask; - private final PlayersPageRefreshTask playersPageRefreshTask; - private final NetworkConfigStoreTask networkConfigStoreTask; - private final DBCleanTask dbCleanTask; - private final ExtensionServerMethodCallerTask extensionServerMethodCallerTask; - - @Inject - public BungeeTaskSystem( - PlanBungee plugin, - PlanConfig config, - RunnableFactory runnableFactory, - BungeeTPSCountTimer bungeeTPSCountTimer, - NetworkPageRefreshTask networkPageRefreshTask, - PingCountTimerBungee pingCountTimer, - LogsFolderCleanTask logsFolderCleanTask, - PlayersPageRefreshTask playersPageRefreshTask, - NetworkConfigStoreTask networkConfigStoreTask, - DBCleanTask dbCleanTask, - ExtensionServerMethodCallerTask extensionServerMethodCallerTask - ) { - super(runnableFactory, bungeeTPSCountTimer); - this.plugin = plugin; - this.config = config; - - this.networkPageRefreshTask = networkPageRefreshTask; - this.pingCountTimer = pingCountTimer; - this.logsFolderCleanTask = logsFolderCleanTask; - this.playersPageRefreshTask = playersPageRefreshTask; - this.networkConfigStoreTask = networkConfigStoreTask; - this.dbCleanTask = dbCleanTask; - this.extensionServerMethodCallerTask = extensionServerMethodCallerTask; - } - - @Override - public void enable() { - registerTasks(); - } - - private void registerTasks() { - registerTask(tpsCountTimer).runTaskTimerAsynchronously(1000, TimeAmount.toTicks(1L, TimeUnit.SECONDS)); - registerTask(networkPageRefreshTask).runTaskTimerAsynchronously(1500, TimeAmount.toTicks(5L, TimeUnit.MINUTES)); - registerTask(logsFolderCleanTask).runTaskLaterAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS)); - - Long pingDelay = config.get(TimeSettings.PING_SERVER_ENABLE_DELAY); - if (pingDelay < TimeUnit.HOURS.toMillis(1L) && config.get(DataGatheringSettings.PING)) { - plugin.registerListener(pingCountTimer); - long startDelay = TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS); - registerTask(pingCountTimer).runTaskTimer(startDelay, 40L); - } - - registerTask(playersPageRefreshTask) - .runTaskTimerAsynchronously(TimeAmount.toTicks(5L, TimeUnit.MINUTES), TimeAmount.toTicks(5L, TimeUnit.MINUTES)); - - // +40 ticks / 2 seconds so that update check task runs first. - long storeDelay = TimeAmount.toTicks(config.get(TimeSettings.CONFIG_UPDATE_INTERVAL), TimeUnit.MILLISECONDS) + 40; - registerTask(networkConfigStoreTask).runTaskLaterAsynchronously(storeDelay); - - registerTask(dbCleanTask).runTaskTimerAsynchronously( - TimeAmount.toTicks(20, TimeUnit.SECONDS), - TimeAmount.toTicks(config.get(TimeSettings.CLEAN_DATABASE_PERIOD), TimeUnit.MILLISECONDS) - ); - - long extensionRefreshPeriod = TimeAmount.toTicks(config.get(TimeSettings.EXTENSION_DATA_REFRESH_PERIOD), TimeUnit.MILLISECONDS); - registerTask(extensionServerMethodCallerTask).runTaskTimerAsynchronously( - TimeAmount.toTicks(30, TimeUnit.SECONDS), extensionRefreshPeriod - ); - } -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java deleted file mode 100644 index 57f249b3e..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks.bungee; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.builders.TPSBuilder; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.system.tasks.TPSCountTimer; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class BungeeTPSCountTimer extends TPSCountTimer { - - private final ServerProperties serverProperties; - - @Inject - public BungeeTPSCountTimer( - DBSystem dbSystem, - ServerInfo serverInfo, - ServerProperties serverProperties, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(dbSystem, serverInfo, logger, errorHandler); - this.serverProperties = serverProperties; - } - - @Override - public void addNewTPSEntry(long nanoTime, long now) { - int onlineCount = serverProperties.getOnlinePlayers(); - TPS tps = TPSBuilder.get() - .date(now) - .playersOnline(onlineCount) - .usedCPU(getCPUUsage()) - .usedMemory(getUsedMemory()) - .entities(-1) - .chunksLoaded(-1) - .freeDiskSpace(getFreeDiskSpace()) - .toTPS(); - - history.add(tps); - latestPlayersOnline = onlineCount; - } -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/bungee/PingCountTimerBungee.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/bungee/PingCountTimerBungee.java deleted file mode 100644 index b9245fb62..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/tasks/bungee/PingCountTimerBungee.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2018 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.djrapitops.plan.system.tasks.bungee; - -import com.djrapitops.plan.data.store.objects.DateObj; -import com.djrapitops.plan.db.access.transactions.events.PingStoreTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.ServerConnectedEvent; -import net.md_5.bungee.api.event.ServerDisconnectEvent; -import net.md_5.bungee.api.plugin.Listener; -import net.md_5.bungee.event.EventHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.*; -import java.util.concurrent.TimeUnit; - -/** - * Task that handles player ping calculation on Bungee based servers. - * - * @author BrainStone - */ -@Singleton -public class PingCountTimerBungee extends AbsRunnable implements Listener { - - private final Map>> playerHistory; - - private final PlanConfig config; - private final DBSystem dbSystem; - private final ServerInfo serverInfo; - private final RunnableFactory runnableFactory; - - @Inject - public PingCountTimerBungee( - PlanConfig config, - DBSystem dbSystem, - ServerInfo serverInfo, - RunnableFactory runnableFactory - ) { - this.config = config; - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.runnableFactory = runnableFactory; - playerHistory = new HashMap<>(); - } - - @Override - public void run() { - long time = System.currentTimeMillis(); - Iterator>>> iterator = playerHistory.entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry>> entry = iterator.next(); - UUID uuid = entry.getKey(); - List> history = entry.getValue(); - ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid); - if (player != null) { - int ping = getPing(player); - if (ping < -1 || ping > TimeUnit.SECONDS.toMillis(8L)) { - // Don't accept bad values - continue; - } - history.add(new DateObj<>(time, ping)); - if (history.size() >= 30) { - dbSystem.getDatabase().executeTransaction( - new PingStoreTransaction(uuid, serverInfo.getServerUUID(), new ArrayList<>(history)) - ); - history.clear(); - } - } else { - iterator.remove(); - } - } - } - - public void addPlayer(ProxiedPlayer player) { - playerHistory.put(player.getUniqueId(), new ArrayList<>()); - } - - public void removePlayer(ProxiedPlayer player) { - playerHistory.remove(player.getUniqueId()); - } - - private int getPing(ProxiedPlayer player) { - return player.getPing(); - } - - @EventHandler - public void onPlayerJoin(ServerConnectedEvent joinEvent) { - ProxiedPlayer player = joinEvent.getPlayer(); - Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY); - if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) { - return; - } - runnableFactory.create("Add Player to Ping list", new AbsRunnable() { - @Override - public void run() { - if (player.isConnected()) { - addPlayer(player); - } - } - }).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS)); - } - - @EventHandler - public void onPlayerQuit(ServerDisconnectEvent quitEvent) { - removePlayer(quitEvent.getPlayer()); - } - - public void clear() { - playerHistory.clear(); - } -} diff --git a/Plan/bungeecord/src/test/java/com/djrapitops/plan/BungeeSystemTest.java b/Plan/bungeecord/src/test/java/com/djrapitops/plan/BungeeSystemTest.java deleted file mode 100644 index ab4a66fb0..000000000 --- a/Plan/bungeecord/src/test/java/com/djrapitops/plan/BungeeSystemTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.db.SQLiteDB; -import com.djrapitops.plan.system.PlanSystem; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DatabaseSettings; -import com.djrapitops.plan.system.settings.paths.ProxySettings; -import com.djrapitops.plan.system.settings.paths.WebserverSettings; -import com.google.common.util.concurrent.MoreExecutors; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import rules.BungeeComponentMocker; -import rules.ComponentMocker; -import utilities.CIProperties; -import utilities.RandomData; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -/** - * Test for Bungee PlanSystem. - * - * @author Rsl1122 - */ -@RunWith(MockitoJUnitRunner.Silent.class) -public class BungeeSystemTest { - - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - - private final int TEST_PORT_NUMBER = RandomData.randomInt(9005, 9500); - - @Rule - public ComponentMocker component = new BungeeComponentMocker(temporaryFolder); - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void bungeeEnables() throws Exception { - PlanSystem bungeeSystem = component.getPlanSystem(); - try { - PlanConfig config = bungeeSystem.getConfigSystem().getConfig(); - config.set(WebserverSettings.PORT, TEST_PORT_NUMBER); - config.set(ProxySettings.IP, "8.8.8.8"); - - DBSystem dbSystem = bungeeSystem.getDatabaseSystem(); - SQLiteDB db = dbSystem.getSqLiteFactory().usingDefaultFile(); - db.setTransactionExecutorServiceProvider(MoreExecutors::newDirectExecutorService); - dbSystem.setActiveDatabase(db); - - bungeeSystem.enable(); - assertTrue(bungeeSystem.isEnabled()); - } finally { - bungeeSystem.disable(); - } - } - - @Test - public void bungeeDoesNotEnableWithDefaultIP() throws Exception { - thrown.expect(EnableException.class); - thrown.expectMessage("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); - - PlanSystem bungeeSystem = component.getPlanSystem(); - try { - PlanConfig config = bungeeSystem.getConfigSystem().getConfig(); - config.set(WebserverSettings.PORT, TEST_PORT_NUMBER); - config.set(ProxySettings.IP, "0.0.0.0"); - - DBSystem dbSystem = bungeeSystem.getDatabaseSystem(); - SQLiteDB db = dbSystem.getSqLiteFactory().usingDefaultFile(); - db.setTransactionExecutorServiceProvider(MoreExecutors::newDirectExecutorService); - dbSystem.setActiveDatabase(db); - - bungeeSystem.enable(); // Throws EnableException - } finally { - bungeeSystem.disable(); - } - } - - @Test - public void testEnableNoMySQL() throws EnableException { - thrown.expect(EnableException.class); - - PlanSystem bungeeSystem = component.getPlanSystem(); - try { - PlanConfig config = bungeeSystem.getConfigSystem().getConfig(); - config.set(WebserverSettings.PORT, TEST_PORT_NUMBER); - config.set(ProxySettings.IP, "8.8.8.8"); - - bungeeSystem.enable(); // Throws EnableException - } finally { - bungeeSystem.disable(); - } - } - - @Test - public void testEnableWithMySQL() throws EnableException { - boolean isCI = Boolean.parseBoolean(System.getenv(CIProperties.IS_CI_SERVICE)); - assumeTrue(isCI); - - PlanSystem bungeeSystem = component.getPlanSystem(); - try { - PlanConfig config = bungeeSystem.getConfigSystem().getConfig(); - config.set(DatabaseSettings.MYSQL_DATABASE, "Plan"); - config.set(DatabaseSettings.MYSQL_USER, "travis"); - config.set(DatabaseSettings.MYSQL_PASS, ""); - config.set(DatabaseSettings.MYSQL_HOST, "127.0.0.1"); - config.set(DatabaseSettings.TYPE, "MySQL"); - - config.set(WebserverSettings.PORT, TEST_PORT_NUMBER); - config.set(ProxySettings.IP, "8.8.8.8"); - - bungeeSystem.enable(); - assertTrue(bungeeSystem.isEnabled()); - } finally { - bungeeSystem.disable(); - } - } -} diff --git a/Plan/bungeecord/src/test/java/rules/BungeeComponentMocker.java b/Plan/bungeecord/src/test/java/rules/BungeeComponentMocker.java deleted file mode 100644 index 3b9858a35..000000000 --- a/Plan/bungeecord/src/test/java/rules/BungeeComponentMocker.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package rules; - -import com.djrapitops.plan.DaggerPlanBungeeComponent; -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plan.PlanBungeeComponent; -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.PlanSystem; -import org.junit.rules.ExternalResource; -import org.junit.rules.TemporaryFolder; -import utilities.mocks.PlanBungeeMocker; - -public class BungeeComponentMocker extends ExternalResource implements ComponentMocker { - - private final TemporaryFolder testFolder; - - private PlanBungee planMock; - private PlanBungeeComponent component; - - public BungeeComponentMocker(TemporaryFolder testFolder) { - this.testFolder = testFolder; - } - - @Override - protected void before() throws Throwable { - PlanBungeeMocker mocker = PlanBungeeMocker.setUp() - .withDataFolder(testFolder.newFolder()) - .withPluginDescription() - .withResourceFetchingFromJar() - .withProxy(); - planMock = mocker.getPlanMock(); - component = DaggerPlanBungeeComponent.builder().plan(planMock).build(); - } - - public PlanPlugin getPlanMock() { - return planMock; - } - - public PlanSystem getPlanSystem() { - return component.system(); - } -} diff --git a/Plan/bungeecord/src/test/java/utilities/mocks/PlanBungeeMocker.java b/Plan/bungeecord/src/test/java/utilities/mocks/PlanBungeeMocker.java deleted file mode 100644 index dd08f610a..000000000 --- a/Plan/bungeecord/src/test/java/utilities/mocks/PlanBungeeMocker.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package utilities.mocks; - -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plugin.benchmarking.Timings; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.console.TestPluginLogger; -import com.djrapitops.plugin.logging.debug.CombineDebugLogger; -import com.djrapitops.plugin.logging.debug.DebugLogger; -import com.djrapitops.plugin.logging.debug.MemoryDebugLogger; -import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.RunnableFactory; -import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.ProxyConfig; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.plugin.PluginDescription; -import net.md_5.bungee.api.plugin.PluginManager; -import org.mockito.Mockito; -import utilities.TestConstants; -import utilities.mocks.objects.TestLogger; -import utilities.mocks.objects.TestRunnableFactory; - -import java.io.File; -import java.util.HashSet; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.when; - -/** - * Mocking Utility for Bungee version of Plan (PlanBungee). - * - * @author Rsl1122 - */ -public class PlanBungeeMocker extends Mocker { - - private PlanBungee planMock; - - private PlanBungeeMocker() { - } - - public static PlanBungeeMocker setUp() { - return new PlanBungeeMocker().mockPlugin(); - } - - private PlanBungeeMocker mockPlugin() { - planMock = Mockito.mock(PlanBungee.class); - super.planMock = planMock; - - doReturn(new ColorScheme("§1", "§2", "§3")).when(planMock).getColorScheme(); - doReturn("1.0.0").when(planMock).getVersion(); - - TestLogger testLogger = new TestLogger(); - RunnableFactory runnableFactory = new TestRunnableFactory(); - PluginLogger testPluginLogger = new TestPluginLogger(); - DebugLogger debugLogger = new CombineDebugLogger(new MemoryDebugLogger()); - ErrorHandler consoleErrorLogger = new ConsoleErrorLogger(testPluginLogger); - Timings timings = new Timings(debugLogger); - - doReturn(testLogger).when(planMock).getLogger(); - doReturn(runnableFactory).when(planMock).getRunnableFactory(); - doReturn(testPluginLogger).when(planMock).getPluginLogger(); - doReturn(debugLogger).when(planMock).getDebugLogger(); - doReturn(consoleErrorLogger).when(planMock).getErrorHandler(); - doReturn(timings).when(planMock).getTimings(); - - return this; - } - - public PlanBungeeMocker withDataFolder(File tempFolder) { - when(planMock.getDataFolder()).thenReturn(tempFolder); - return this; - } - - public PlanBungeeMocker withResourceFetchingFromJar() throws Exception { - withPluginFiles(); - return this; - } - - @Deprecated - public PlanBungeeMocker withLogging() { - return this; - } - - @SuppressWarnings("deprecation") - public PlanBungeeMocker withProxy() { - ProxyServer proxyMock = Mockito.mock(ProxyServer.class); - doReturn("1.12.2").when(proxyMock).getVersion(); - - CommandSender console = Mockito.mock(CommandSender.class); - doReturn(console).when(proxyMock).getConsole(); - - ProxyConfig proxyConfig = Mockito.mock(ProxyConfig.class); - doReturn(TestConstants.BUNGEE_MAX_PLAYERS).when(proxyConfig).getPlayerLimit(); - doReturn(proxyConfig).when(proxyMock).getConfig(); - - PluginManager pm = Mockito.mock(PluginManager.class); - doReturn(pm).when(proxyMock).getPluginManager(); - - doReturn(proxyMock).when(planMock).getProxy(); - return this; - } - - public PlanBungeeMocker withPluginDescription() { - File pluginYml = getFile("/bungee.yml"); - HashSet empty = new HashSet<>(); - PluginDescription pluginDescription = new PluginDescription("Plan", "", "9.9.9", "Rsl1122", empty, empty, pluginYml, ""); - when(planMock.getDescription()).thenReturn(pluginDescription); - return this; - } - - public PlanBungee getPlanMock() { - return planMock; - } -} diff --git a/Plan/bungeecord/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/Plan/bungeecord/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea..000000000 --- a/Plan/bungeecord/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/Plan/checkstyle.xml b/Plan/checkstyle.xml deleted file mode 100644 index 7a9660a0b..000000000 --- a/Plan/checkstyle.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Plan/common/build.gradle b/Plan/common/build.gradle deleted file mode 100644 index 983d891c1..000000000 --- a/Plan/common/build.gradle +++ /dev/null @@ -1,56 +0,0 @@ -dependencies { - compile "com.djrapitops:AbstractPluginFramework-api:$abstractPluginFrameworkVersion" - compile project(":api") - compile project(path: ":extensions", configuration: 'shadow') - compile "com.djrapitops:PlanPluginBridge:$planPluginBridgeVersion" - compile "org.apache.httpcomponents:httpclient:$httpClientVersion" - compile "org.apache.commons:commons-text:$commonsTextVersion" - compile "com.googlecode.htmlcompressor:htmlcompressor:$htmlCompressorVersion" - compile "com.github.ben-manes.caffeine:caffeine:$caffeineVersion" - compile "com.h2database:h2:$h2Version" - compile "mysql:mysql-connector-java:$mysqlVersion" - compile "com.zaxxer:HikariCP:$hikariVersion" - compile "org.slf4j:slf4j-nop:$slf4jVersion" - compile "org.slf4j:slf4j-api:$slf4jVersion" - compile "com.maxmind.geoip2:geoip2:$geoIpVersion" - compileOnly "com.google.guava:guava:$guavaVersion" - - testCompile project(":api") - testCompile "com.google.code.gson:gson:2.8.5" -} - -shadowJar { - configurations = [project.configurations.compile] - - // Exclude these files - exclude "**/*.svg" - exclude "**/*.ttf" - exclude "**/*.woff" - exclude "**/*.eot" - exclude "**/*.woff2" - exclude "**/*.psd" - - exclude "**/module-info.class" - exclude 'META-INF/versions/' // Causes Sponge to crash - - relocate('org.apache', 'plan.org.apache') { - exclude 'org/apache/logging/**' - } - relocate 'com.maxmind', 'plan.com.maxmind' - relocate 'com.fasterxml', 'plan.com.fasterxml' - relocate 'com.zaxxer', 'plan.com.zaxxer' - relocate 'com.github.benmanes', 'plan.com.github.benmanes' - relocate 'com.googlecode', 'plan.com.googlecode' - relocate 'org.h2', 'plan.org.h2' - relocate 'org.bstats', 'plan.org.bstats' - relocate 'org.slf4j', 'plan.org.slf4j' - - // Exclude test dependencies - exclude "org/junit/**/*" - exclude "org/opentest4j/**/*" - exclude "org/checkerframework/**/*" - exclude "org/apiguardian/**/*" - exclude "org/mockito/**/*" - exclude "org/selenium/**/*" - exclude "org/jayway/**/*" -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/PlanPlugin.java b/Plan/common/src/main/java/com/djrapitops/plan/PlanPlugin.java deleted file mode 100644 index 6f42757e2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/PlanPlugin.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.system.PlanSystem; -import com.djrapitops.plugin.IPlugin; -import com.djrapitops.plugin.command.ColorScheme; - -import java.io.File; -import java.io.InputStream; - -/** - * Abstraction interface for both Plan and PlanBungee. - * - * @author Rsl1122 - */ -public interface PlanPlugin extends IPlugin { - - @Override - File getDataFolder(); - - InputStream getResource(String resource); - - ColorScheme getColorScheme(); - - @Override - boolean isReloading(); - - PlanSystem getSystem(); - - default boolean isSystemEnabled() { - return getSystem().isEnabled(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/ServerShutdownSave.java b/Plan/common/src/main/java/com/djrapitops/plan/ServerShutdownSave.java deleted file mode 100644 index 847e54f4e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/ServerShutdownSave.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.events.ServerShutdownTransaction; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.ExecutionException; - -/** - * Class in charge of performing save operations when the server shuts down. - * - * @author Rsl1122 - */ -public abstract class ServerShutdownSave { - - protected final PluginLogger logger; - private final DBSystem dbSystem; - private final Locale locale; - private final ErrorHandler errorHandler; - private boolean shuttingDown = false; - - public ServerShutdownSave( - Locale locale, - DBSystem dbSystem, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.locale = locale; - this.dbSystem = dbSystem; - this.logger = logger; - this.errorHandler = errorHandler; - } - - protected abstract boolean checkServerShuttingDownStatus(); - - public void serverIsKnownToBeShuttingDown() { - shuttingDown = true; - } - - public void performSave() { - if (!checkServerShuttingDownStatus() && !shuttingDown) { - return; - } - - Map activeSessions = SessionCache.getActiveSessions(); - if (activeSessions.isEmpty()) { - return; - } - - // This check ensures that logging is not attempted on JVM shutdown. - // Underlying Logger might not be available leading to an exception. - if (!shuttingDown) { - logger.info(locale.getString(PluginLang.DISABLED_UNSAVED_SESSIONS)); - } - attemptSave(activeSessions); - - SessionCache.clear(); - } - - private void attemptSave(Map activeSessions) { - try { - prepareSessionsForStorage(activeSessions, System.currentTimeMillis()); - saveActiveSessions(activeSessions); - } catch (DBInitException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } catch (IllegalStateException ignored) { - /* Database is not initialized */ - } finally { - closeDatabase(dbSystem.getDatabase()); - } - } - - private void saveActiveSessions(Map activeSessions) { - Database database = dbSystem.getDatabase(); - if (database.getState() == Database.State.CLOSED) { - // Ensure that database is not closed when performing the transaction. - database.init(); - } - - saveSessions(activeSessions, database); - } - - private void prepareSessionsForStorage(Map activeSessions, long now) { - for (Session session : activeSessions.values()) { - Optional end = session.getValue(SessionKeys.END); - if (!end.isPresent()) { - session.endSession(now); - } - } - } - - private void saveSessions(Map activeSessions, Database database) { - try { - database.executeTransaction(new ServerShutdownTransaction(activeSessions.values())) - .get(); // Ensure that the transaction is executed before shutdown. - } catch (ExecutionException | DBOpException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - private void closeDatabase(Database database) { - database.close(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/ShutdownHook.java b/Plan/common/src/main/java/com/djrapitops/plan/ShutdownHook.java deleted file mode 100644 index b10c621f0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/ShutdownHook.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Thread that is run when JVM shuts down. - *

- * Saves active sessions to the Database (PlayerQuitEvent is not called) - * - * @author Rsl1122 - */ -@Singleton -public class ShutdownHook extends Thread { - - private static ShutdownHook activated; - - private final ServerShutdownSave serverShutdownSave; - - @Inject - public ShutdownHook(ServerShutdownSave serverShutdownSave) { - this.serverShutdownSave = serverShutdownSave; - } - - private static boolean isActivated() { - return activated != null; - } - - private static void activate(ShutdownHook hook) { - activated = hook; - Runtime.getRuntime().addShutdownHook(hook); - } - - private static void deactivate() { - Runtime.getRuntime().removeShutdownHook(activated); - activated = null; - } - - public void register() { - if (isActivated()) { - deactivate(); - } - activate(this); - } - - @Override - public void run() { - serverShutdownSave.serverIsKnownToBeShuttingDown(); - serverShutdownSave.performSave(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/CommonAPI.java b/Plan/common/src/main/java/com/djrapitops/plan/api/CommonAPI.java deleted file mode 100644 index 97bc6b8b9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/CommonAPI.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api; - -import com.djrapitops.plan.api.data.PlayerContainer; -import com.djrapitops.plan.api.data.ServerContainer; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.queries.containers.ContainerFetchQueries; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.database.databases.operation.FetchOperations; -import com.djrapitops.plan.system.database.databases.sql.operation.SQLFetchOps; -import com.djrapitops.plan.utilities.uuid.UUIDUtility; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -/** - * PlanAPI extension for all implementations. - * - * @author Rsl1122 - */ -@Singleton -public class CommonAPI implements PlanAPI { - - private final DBSystem dbSystem; - private final UUIDUtility uuidUtility; - private final HookHandler hookHandler; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - @Inject - public CommonAPI( - DBSystem dbSystem, - UUIDUtility uuidUtility, - HookHandler hookHandler, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.dbSystem = dbSystem; - this.uuidUtility = uuidUtility; - this.hookHandler = hookHandler; - this.logger = logger; - this.errorHandler = errorHandler; - PlanAPIHolder.set(this); - } - - @Override - public void addPluginDataSource(PluginData pluginData) { - hookHandler.addPluginDataSource(pluginData); - } - - @Override - public String getPlayerInspectPageLink(UUID uuid) { - return getPlayerInspectPageLink(getPlayerName(uuid)); - } - - @Override - public String getPlayerInspectPageLink(String playerName) { - return "../player/" + playerName; - } - - @Override - public UUID playerNameToUUID(String playerName) { - return uuidUtility.getUUIDOf(playerName); - } - - @Override - public Map getKnownPlayerNames() { - try { - return queryDB(UserIdentifierQueries.fetchAllPlayerNames()); - } catch (DBOpException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - return new HashMap<>(); - } - } - - @Override - public PlayerContainer fetchPlayerContainer(UUID uuid) { - return new PlayerContainer(queryDB(ContainerFetchQueries.fetchPlayerContainer(uuid))); - } - - @Override - public ServerContainer fetchServerContainer(UUID serverUUID) { - return new ServerContainer(queryDB(ContainerFetchQueries.fetchServerContainer(serverUUID))); - } - - @Override - public Collection fetchServerUUIDs() { - return queryDB(ServerQueries.fetchPlanServerInformation()).keySet(); - } - - @Override - public String getPlayerName(UUID playerUUID) { - return queryDB(UserIdentifierQueries.fetchPlayerNameOf(playerUUID)).orElse(null); - } - - @Override - public FetchOperations fetchFromPlanDB() { - logger.warn("PlanAPI#fetchFromPlanDB has been deprecated and will be removed in the future. Stack trace to follow"); - for (StackTraceElement element : Thread.currentThread().getStackTrace()) { - logger.warn(element.toString()); - } - return new SQLFetchOps(dbSystem.getDatabase()); - } - - private T queryDB(Query query) { - return dbSystem.getDatabase().query(query); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/PlanAPI.java b/Plan/common/src/main/java/com/djrapitops/plan/api/PlanAPI.java deleted file mode 100644 index 91516d0c9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/PlanAPI.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api; - -import com.djrapitops.plan.api.data.PlayerContainer; -import com.djrapitops.plan.api.data.ServerContainer; -import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.system.database.databases.operation.FetchOperations; - -import java.util.Collection; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -/** - * Interface for PlanAPI methods. - * - * @author Rsl1122 - */ -public interface PlanAPI { - - static PlanAPI getInstance() { - return Optional.ofNullable(PlanAPIHolder.API) - .orElseThrow(() -> new IllegalStateException("PlanAPI has not been initialised yet.")); - } - - class PlanAPIHolder { - static PlanAPI API; - - static void set(PlanAPI api) { - PlanAPIHolder.API = api; - } - - private PlanAPIHolder() { - /* Static variable holder */ - } - } - - /** - * @deprecated PluginData API has been deprecated - see https://github.com/plan-player-analytics/Plan/wiki/APIv5---DataExtension-API for new API. - */ - @Deprecated - void addPluginDataSource(PluginData pluginData); - - String getPlayerInspectPageLink(UUID uuid); - - String getPlayerInspectPageLink(String playerName); - - String getPlayerName(UUID uuid); - - UUID playerNameToUUID(String playerName); - - Map getKnownPlayerNames(); - - /** - * Fetch things from the database. - * - * @return FetchOperations object. - * @deprecated FetchOperations interface is going to removed since it is too rigid. - */ - @Deprecated - FetchOperations fetchFromPlanDB(); - - /** - * Fetch PlayerContainer from the database. - *

- * Blocking operation. - * - * @param uuid UUID of the player. - * @return a {@link PlayerContainer}. - */ - PlayerContainer fetchPlayerContainer(UUID uuid); - - /** - * Fetch a ServerContainer from the database. - *

- * Blocking operation. - * - * @param serverUUID UUID of the server. - * @return a {@link ServerContainer}. - */ - ServerContainer fetchServerContainer(UUID serverUUID); - - /** - * Fetch server UUIDs. - * - * @return All Plan server UUIDs. - */ - Collection fetchServerUUIDs(); -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/data/PlayerContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/api/data/PlayerContainer.java deleted file mode 100644 index 76d0c728e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/data/PlayerContainer.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.data; - -import com.djrapitops.plan.data.store.Key; - -import java.util.Optional; - -/** - * Wrapper for a PlayerContainer. - *

- * The actual object is wrapped to avoid exposing too much API that might change. - * See {@link com.djrapitops.plan.data.store.keys.PlayerKeys} for Key objects. - *

- * The Keys might change in the future, but the Optional API should help dealing with those cases. - * - * @author Rsl1122 - */ -public class PlayerContainer { - - private final com.djrapitops.plan.data.store.containers.PlayerContainer container; - - public PlayerContainer(com.djrapitops.plan.data.store.containers.PlayerContainer container) { - this.container = container; - } - - public double getActivityIndex(long date, long playtimeMsThreshold, int loginThreshold) { - return container.getActivityIndex(date, playtimeMsThreshold, loginThreshold).getValue(); - } - - public boolean playedBetween(long after, long before) { - return container.playedBetween(after, before); - } - - public Optional getValue(Key key) { - return container.getValue(key); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/data/ServerContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/api/data/ServerContainer.java deleted file mode 100644 index e002f70c0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/data/ServerContainer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.data; - -import com.djrapitops.plan.data.store.Key; - -import java.util.Optional; - -/** - * Wrapper for a ServerContainer. - *

- * The actual object is wrapped to avoid exposing too much API that might change. - * See {@link com.djrapitops.plan.data.store.keys.ServerKeys} for Key objects. - *

- * The Keys might change in the future, but the Optional API should help dealing with those cases. - * - * @author Rsl1122 - */ -public class ServerContainer { - - private final com.djrapitops.plan.data.store.containers.ServerContainer container; - - public ServerContainer(com.djrapitops.plan.data.store.containers.ServerContainer container) { - this.container = container; - } - - public Optional getValue(Key key) { - return container.getValue(key); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/DataExtensionMethodCallException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/DataExtensionMethodCallException.java deleted file mode 100644 index 342d9cb2b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/DataExtensionMethodCallException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions; - -import com.djrapitops.plan.extension.implementation.providers.MethodWrapper; - -/** - * Exception that is thrown when a call to a DataExtension method throws an exception. - * - * @author Rsl1122 - */ -public class DataExtensionMethodCallException extends IllegalStateException { - - private final String pluginName; - private final MethodWrapper method; - - public DataExtensionMethodCallException(Throwable cause, String pluginName, MethodWrapper method) { - super(cause); - this.pluginName = pluginName; - this.method = method; - } - - public String getPluginName() { - return pluginName; - } - - public MethodWrapper getMethod() { - return method; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/EnableException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/EnableException.java deleted file mode 100644 index 209fe9201..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/EnableException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions; - -/** - * Thrown when something goes wrong with Plan initialization. - * - * @author Rsl1122 - */ -public class EnableException extends Exception { - - public EnableException(String message, Throwable cause) { - super(message, cause); - } - - public EnableException(String message) { - super(message); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/ParseException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/ParseException.java deleted file mode 100644 index 5b765d85a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/ParseException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions; - -/** - * Exception thrown when Page encounters an Exception. - * - * @author Rsl1122 - */ -public class ParseException extends Exception { - - public ParseException(Throwable cause) { - super(cause); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/PassEncryptException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/PassEncryptException.java deleted file mode 100644 index ac618d786..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/PassEncryptException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions; - -public class PassEncryptException extends Exception { - - public PassEncryptException(String s) { - super(s); - } - - public PassEncryptException(String s, Throwable throwable) { - super(s, throwable); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/WebUserAuthException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/WebUserAuthException.java deleted file mode 100644 index 592100be4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/WebUserAuthException.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions; - -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.webserver.auth.FailReason; - -/** - * Thrown when WebUser can not be authorized (WebServer). - * - * @author Rsl1122 - */ -public class WebUserAuthException extends WebException { - - private final FailReason failReason; - - public WebUserAuthException(FailReason failReason) { - super(failReason.getReason()); - this.failReason = failReason; - } - - public WebUserAuthException(FailReason failReason, String additionalInfo) { - super(failReason.getReason() + ": " + additionalInfo); - this.failReason = failReason; - } - - public WebUserAuthException(Throwable cause) { - super(FailReason.ERROR.getReason(), cause); - this.failReason = FailReason.ERROR; - } - - public FailReason getFailReason() { - return failReason; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/BadRequestException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/BadRequestException.java deleted file mode 100644 index 24d46856b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/BadRequestException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.webserver.response.ResponseCode; - -/** - * Thrown when connection is returned 401 Bad Request. - * - * @author Rsl1122 - */ -public class BadRequestException extends WebException { - - public BadRequestException(String message) { - super(message, ResponseCode.BAD_REQUEST); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/ConnectionFailException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/ConnectionFailException.java deleted file mode 100644 index db6c7dbed..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/ConnectionFailException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.webserver.response.ResponseCode; - -/** - * Thrown when Connection fails to connect to an address. - * - * @author Rsl1122 - */ -public class ConnectionFailException extends WebException { - - public ConnectionFailException(String message, Throwable cause) { - super(message, cause, ResponseCode.CONNECTION_REFUSED); - } - - public ConnectionFailException(Throwable cause) { - super(cause, ResponseCode.CONNECTION_REFUSED); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/ForbiddenException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/ForbiddenException.java deleted file mode 100644 index de9e1473d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/ForbiddenException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.webserver.response.ResponseCode; - -/** - * Thrown when Connection gets a 403 response. - * - * @author Rsl1122 - */ -public class ForbiddenException extends WebFailException { - public ForbiddenException(String url) { - super("Forbidden: " + url, ResponseCode.FORBIDDEN); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/GatewayException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/GatewayException.java deleted file mode 100644 index a5c064323..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/GatewayException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.webserver.response.ResponseCode; - -/** - * Thrown when InfoRequest can not connect to the other server. - * - * @author Rsl1122 - */ -public class GatewayException extends WebException { - - public GatewayException(String message) { - super(message, ResponseCode.GATEWAY_ERROR); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/InternalErrorException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/InternalErrorException.java deleted file mode 100644 index 1646f4713..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/InternalErrorException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.webserver.response.ResponseCode; - -/** - * Thrown when Connection returns 500. - * - * @author Rsl1122 - */ -public class InternalErrorException extends WebFailException { - public InternalErrorException() { - super("Internal Error occurred on receiving server", ResponseCode.INTERNAL_ERROR); - } - - public InternalErrorException(String message, Throwable cause) { - super(message, cause, ResponseCode.INTERNAL_ERROR); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/NoServersException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/NoServersException.java deleted file mode 100644 index 5e0b826a6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/NoServersException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -/** - * Thrown when ConnectionSystem can not find any servers to send request to. - * - * @author Rsl1122 - */ -public class NoServersException extends WebException { - - public NoServersException(String message) { - super(message); - } - - public NoServersException(String message, Throwable cause) { - super(message, cause); - } - - public NoServersException(Throwable cause) { - super(cause); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/NotFoundException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/NotFoundException.java deleted file mode 100644 index 67ee7e57a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/NotFoundException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.webserver.response.ResponseCode; - -/** - * Thrown when Connection returns 404, when page is not found. - * - * @author Rsl1122 - */ -public class NotFoundException extends WebFailException { - public NotFoundException(String message) { - super(message, ResponseCode.NOT_FOUND); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/TransferDatabaseException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/TransferDatabaseException.java deleted file mode 100644 index 55e9f45f6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/TransferDatabaseException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.info.request.InfoRequest; - -/** - * Thrown when {@link com.djrapitops.plan.api.exceptions.database.DBOpException} occurs during {@link InfoRequest#runLocally()}. - * - * @author Rsl1122 - */ -public class TransferDatabaseException extends WebException { - - public TransferDatabaseException(Exception cause) { - super(cause); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/UnauthorizedServerException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/UnauthorizedServerException.java deleted file mode 100644 index 735057577..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/UnauthorizedServerException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.webserver.response.ResponseCode; - -/** - * Thrown when Connection gets a 412 response due to ServerUUID not being in the database. - * - * @author Rsl1122 - */ -public class UnauthorizedServerException extends WebFailException { - - public UnauthorizedServerException(String message) { - super(message, ResponseCode.PRECONDITION_FAILED); - } - - public UnauthorizedServerException(String message, Throwable cause) { - super(message, cause, ResponseCode.PRECONDITION_FAILED); - } - - public UnauthorizedServerException(Throwable cause) { - super(cause, ResponseCode.PRECONDITION_FAILED); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/WebException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/WebException.java deleted file mode 100644 index 2bea242a0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/WebException.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.webserver.response.ResponseCode; - -/** - * Thrown when Connection POST-request fails, general Exception. - * - * @author Rsl1122 - */ -public class WebException extends Exception { - - private final ResponseCode responseCode; - - public WebException() { - responseCode = ResponseCode.NONE; - } - - public WebException(String message) { - super(message); - responseCode = ResponseCode.NONE; - } - - public WebException(String message, Throwable cause) { - super(message, cause); - responseCode = ResponseCode.NONE; - } - - public WebException(Throwable cause) { - super(cause); - responseCode = ResponseCode.NONE; - } - - public WebException(ResponseCode responseCode) { - this.responseCode = responseCode; - } - - public WebException(String message, ResponseCode responseCode) { - super(message); - this.responseCode = responseCode; - } - - public WebException(String message, Throwable cause, ResponseCode responseCode) { - super(message, cause); - this.responseCode = responseCode; - } - - public WebException(Throwable cause, ResponseCode responseCode) { - super(cause); - this.responseCode = responseCode; - } - - public ResponseCode getResponseCode() { - return responseCode; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/WebFailException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/WebFailException.java deleted file mode 100644 index f46eddcfd..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/connection/WebFailException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.connection; - -import com.djrapitops.plan.system.webserver.response.ResponseCode; - -/** - * Group of WebExceptions that can be considered a failed connection state on some occasions. - * - * @author Rsl1122 - */ -public class WebFailException extends WebException { - - public WebFailException(String message, Throwable cause) { - super(message, cause); - } - - public WebFailException(String message, ResponseCode responseCode) { - super(message, responseCode); - } - - public WebFailException(String message, Throwable cause, ResponseCode responseCode) { - super(message, cause, responseCode); - } - - public WebFailException(Throwable cause, ResponseCode responseCode) { - super(cause, responseCode); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/DBInitException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/DBInitException.java deleted file mode 100644 index 81734c977..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/DBInitException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.database; - -/** - * Thrown when something goes wrong with {@code Database#init}. - * - * @author Rsl1122 - */ -public class DBInitException extends DBOpException { - - public DBInitException(String message, Throwable cause) { - super(message, cause); - } - - public DBInitException(String message) { - super(message); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/DBOpException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/DBOpException.java deleted file mode 100644 index 5e8fc3448..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/DBOpException.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.database; - -import java.sql.SQLException; - -/** - * Runtime exception for wrapping database errors. - * - * @author Rsl1122 - */ -public class DBOpException extends IllegalStateException { - - public DBOpException(String message) { - super(message); - } - - public DBOpException(String message, Throwable cause) { - super(message, cause); - } - - public static DBOpException forCause(String sql, SQLException e) { - return new DBOpException("SQL Failed: " + sql + "; " + e.getMessage(), e); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/FatalDBException.java b/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/FatalDBException.java deleted file mode 100644 index f192b8e7e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/api/exceptions/database/FatalDBException.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.api.exceptions.database; - -public class FatalDBException extends DBOpException { - - public FatalDBException(String message) { - super(message); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/capability/CapabilityServiceImplementation.java b/Plan/common/src/main/java/com/djrapitops/plan/capability/CapabilityServiceImplementation.java deleted file mode 100644 index a4ea36896..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/capability/CapabilityServiceImplementation.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.capability; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -/** - * Singleton instance implementation for {@link CapabilityService}. - *

- * Only one instance exists per runtime in order to notify others when the plugin enables. - * - * @author Rsl1122 - */ -public class CapabilityServiceImplementation implements CapabilityService { - - private List> enableListeners; - - private CapabilityServiceImplementation() { - /* Inject required for dagger */ - CapabilityServiceHolder.set(this); - enableListeners = new ArrayList<>(); - } - - private static CapabilityServiceImplementation get() { - if (CapabilityServiceHolder.service == null) { - return new CapabilityServiceImplementation(); - } - return (CapabilityServiceImplementation) CapabilityServiceHolder.service; - } - - public static void initialize() { - get(); - } - - public static void notifyAboutEnable(boolean isEnabled) { - for (Consumer enableListener : get().enableListeners) { - enableListener.accept(isEnabled); - } - } - - @Override - public void registerEnableListener(Consumer enableListener) { - enableListeners.add(enableListener); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/PlanCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/PlanCommand.java deleted file mode 100644 index fe0bc7bc1..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/PlanCommand.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command; - -import com.djrapitops.plan.command.commands.*; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.TreeCmdNode; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * TreeCommand for the /plan command, and all SubCommands. - *

- * Uses the Abstract Plugin Framework for easier command management. - * - * @author Rsl1122 - */ -@Singleton -public class PlanCommand extends TreeCmdNode { - - private final PlanConfig config; - private final InspectCommand inspectCommand; - private final QInspectCommand qInspectCommand; - private final SearchCommand searchCommand; - private final ListPlayersCommand listPlayersCommand; - private final AnalyzeCommand analyzeCommand; - private final NetworkCommand networkCommand; - private final ListServersCommand listServersCommand; - private final Lazy webUserCommand; - private final RegisterCommand registerCommand; - private final InfoCommand infoCommand; - private final ReloadCommand reloadCommand; - private final Lazy manageCommand; - private final DevCommand devCommand; - - private boolean commandsRegistered; - - @Inject - public PlanCommand( - ColorScheme colorScheme, - Locale locale, - PlanConfig config, - // Group 1 - InspectCommand inspectCommand, - QInspectCommand qInspectCommand, - SearchCommand searchCommand, - ListPlayersCommand listPlayersCommand, - AnalyzeCommand analyzeCommand, - NetworkCommand networkCommand, - ListServersCommand listServersCommand, - // Group 2 - Lazy webUserCommand, - RegisterCommand registerCommand, - // Group 3 - InfoCommand infoCommand, - ReloadCommand reloadCommand, - Lazy manageCommand, - DevCommand devCommand - ) { - super("plan", "", CommandType.CONSOLE, null); - - commandsRegistered = false; - - this.config = config; - this.inspectCommand = inspectCommand; - this.qInspectCommand = qInspectCommand; - this.searchCommand = searchCommand; - this.listPlayersCommand = listPlayersCommand; - this.analyzeCommand = analyzeCommand; - this.networkCommand = networkCommand; - this.listServersCommand = listServersCommand; - this.webUserCommand = webUserCommand; - this.registerCommand = registerCommand; - this.infoCommand = infoCommand; - this.reloadCommand = reloadCommand; - this.manageCommand = manageCommand; - this.devCommand = devCommand; - - getHelpCommand().setPermission(Permissions.HELP.getPermission()); - setDefaultCommand("inspect"); - setColorScheme(colorScheme); - setInDepthHelp(locale.getArray(DeepHelpLang.PLAN)); - } - - public void registerCommands() { - if (commandsRegistered) { - return; - } - - CommandNode[] analyticsGroup = { - inspectCommand, - qInspectCommand, - searchCommand, - listPlayersCommand, - analyzeCommand, - networkCommand, - listServersCommand - }; - CommandNode[] webGroup = { - webUserCommand.get(), - registerCommand - }; - CommandNode[] manageGroup = { - infoCommand, - reloadCommand, - manageCommand.get(), - config.isTrue(PluginSettings.DEV_MODE) ? devCommand : null - }; - setNodeGroups(analyticsGroup, webGroup, manageGroup); - commandsRegistered = true; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/PlanProxyCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/PlanProxyCommand.java deleted file mode 100644 index 628bdb6b0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/PlanProxyCommand.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command; - -import com.djrapitops.plan.command.commands.*; -import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; -import com.djrapitops.plan.command.commands.manage.ManageRawDataCommand; -import com.djrapitops.plan.command.commands.manage.ManageUninstalledCommand; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.TreeCmdNode; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -/** - * TreeCommand for the /plan command, and all subcommands. - *

- * Uses the Abstract Plugin Framework for easier command management. - * - * @author Rsl1122 - */ -@Singleton -public class PlanProxyCommand extends TreeCmdNode { - - private final NetworkCommand networkCommand; - private final ListServersCommand listServersCommand; - private final ListPlayersCommand listPlayersCommand; - private final RegisterCommand registerCommand; - private final Lazy webUserCommand; - private final ManageConDebugCommand conDebugCommand; - private final ManageRawDataCommand rawDataCommand; - private final BungeeSetupToggleCommand setupToggleCommand; - private final ReloadCommand reloadCommand; - private final DisableCommand disableCommand; - private final ManageUninstalledCommand uninstalledCommand; - - private boolean commandsRegistered; - - @Inject - public PlanProxyCommand( - @Named("mainCommandName") String mainCommandName, - ColorScheme colorScheme, - Locale locale, - // Group 1 - NetworkCommand networkCommand, - ListServersCommand listServersCommand, - ListPlayersCommand listPlayersCommand, - // Group 2 - RegisterCommand registerCommand, - Lazy webUserCommand, - // Group 3 - ManageConDebugCommand conDebugCommand, - ManageRawDataCommand rawDataCommand, - BungeeSetupToggleCommand setupToggleCommand, - ManageUninstalledCommand uninstalledCommand, - ReloadCommand reloadCommand, - DisableCommand disableCommand - ) { - super(mainCommandName, Permissions.MANAGE.getPermission(), CommandType.CONSOLE, null); - this.uninstalledCommand = uninstalledCommand; - - commandsRegistered = false; - - this.networkCommand = networkCommand; - this.listServersCommand = listServersCommand; - this.listPlayersCommand = listPlayersCommand; - this.registerCommand = registerCommand; - this.webUserCommand = webUserCommand; - this.conDebugCommand = conDebugCommand; - this.rawDataCommand = rawDataCommand; - this.setupToggleCommand = setupToggleCommand; - this.reloadCommand = reloadCommand; - this.disableCommand = disableCommand; - - getHelpCommand().setPermission(Permissions.MANAGE.getPermission()); - setColorScheme(colorScheme); - setInDepthHelp(locale.getArray(DeepHelpLang.PLAN)); - } - - public void registerCommands() { - if (commandsRegistered) { - return; - } - - CommandNode[] analyticsGroup = { - networkCommand, - listServersCommand, - listPlayersCommand - }; - CommandNode[] webGroup = { - registerCommand, - webUserCommand.get() - }; - CommandNode[] manageGroup = { - conDebugCommand, - rawDataCommand, - setupToggleCommand, - uninstalledCommand, - reloadCommand, - disableCommand - }; - setNodeGroups(analyticsGroup, webGroup, manageGroup); - commandsRegistered = true; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java deleted file mode 100644 index 37b67efaf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.queries.objects.WebUserQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Optional; -import java.util.UUID; - -/** - * This SubCommand is used to run the analysis and access the /server link. - * - * @author Rsl1122 - */ -@Singleton -public class AnalyzeCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final InfoSystem infoSystem; - private final ServerInfo serverInfo; - private final WebServer webServer; - private final DBSystem dbSystem; - private final ConnectionSystem connectionSystem; - private final ErrorHandler errorHandler; - - @Inject - public AnalyzeCommand( - Locale locale, - Processing processing, - InfoSystem infoSystem, - ServerInfo serverInfo, - WebServer webServer, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - super("analyze|analyse|analysis|a", Permissions.ANALYZE.getPermission(), CommandType.CONSOLE); - - this.locale = locale; - this.processing = processing; - this.infoSystem = infoSystem; - connectionSystem = infoSystem.getConnectionSystem(); - this.serverInfo = serverInfo; - this.webServer = webServer; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - - setShortHelp(locale.getString(CmdHelpLang.ANALYZE)); - setInDepthHelp(locale.getArray(DeepHelpLang.ANALYZE)); - setArguments("[server/id]"); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - - processing.submitNonCritical(() -> { - try { - Server server = getServer(args).orElseGet(serverInfo::getServer); - UUID serverUUID = server.getUuid(); - - infoSystem.generateAnalysisPage(serverUUID); - sendWebUserNotificationIfNecessary(sender); - sendLink(server, sender); - } catch (DBOpException | WebException e) { - sender.sendMessage("§cError occurred: " + e.toString()); - errorHandler.log(L.ERROR, this.getClass(), e); - } - }); - } - - private void sendLink(Server server, Sender sender) { - String target = "/server/" + server.getName(); - String url = connectionSystem.getMainAddress() + target; - String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); - sender.sendMessage(locale.getString(CommandLang.HEADER_ANALYSIS)); - // Link - boolean console = !CommandUtils.isPlayer(sender); - if (console) { - sender.sendMessage(linkPrefix + url); - } else { - sender.sendMessage(linkPrefix); - sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); - } - sender.sendMessage(">"); - } - - private void sendWebUserNotificationIfNecessary(Sender sender) { - if (webServer.isAuthRequired() && - CommandUtils.isPlayer(sender) && - !dbSystem.getDatabase().query(WebUserQueries.fetchWebUser(sender.getName())).isPresent()) { - sender.sendMessage("§e" + locale.getString(CommandLang.NO_WEB_USER_NOTIFY)); - } - } - - private Optional getServer(String[] args) { - if (args.length >= 1 && connectionSystem.isServerAvailable()) { - String serverIdentifier = getGivenIdentifier(args); - return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverIdentifier)) - .filter(server -> !server.isProxy()); - } - return Optional.empty(); - } - - private String getGivenIdentifier(String[] args) { - StringBuilder idBuilder = new StringBuilder(args[0]); - if (args.length > 1) { - for (int i = 1; i < args.length; i++) { - idBuilder.append(" ").append(args[i]); - } - } - return idBuilder.toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java deleted file mode 100644 index 662e0fbcc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; - -import javax.inject.Inject; - -/** - * Command for Toggling whether or not BungeeCord accepts set up requests. - *

- * This was added as a security measure against unwanted MySQL snooping. - * - * @author Rsl1122 - */ -public class BungeeSetupToggleCommand extends CommandNode { - - private final Locale locale; - private final ConnectionSystem connectionSystem; - - @Inject - public BungeeSetupToggleCommand(Locale locale, ConnectionSystem connectionSystem) { - super("setup", Permissions.MANAGE.getPermission(), CommandType.ALL); - - this.locale = locale; - this.connectionSystem = connectionSystem; - - setShortHelp(locale.getString(CmdHelpLang.SETUP)); - setInDepthHelp(locale.getArray(DeepHelpLang.SETUP)); - } - - @Override - public void onCommand(Sender sender, String s, String[] strings) { - if (connectionSystem.isSetupAllowed()) { - connectionSystem.setSetupAllowed(false); - } else { - connectionSystem.setSetupAllowed(true); - } - - String msg = locale.getString(connectionSystem.isSetupAllowed() ? CommandLang.SETUP_ALLOWED : CommandLang.SETUP_FORBIDDEN); - sender.sendMessage(msg); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java deleted file mode 100644 index ba05e527d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import java.util.Arrays; - -/** - * Command used for testing functions that are too difficult to unit test. - * - * @author Rsl1122 - */ -public class DevCommand extends CommandNode { - - private final Locale locale; - - @Inject - public DevCommand(Locale locale) { - super("dev", "plan.*", CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - - setShortHelp(locale.get(CmdHelpLang.DEV).toString()); - setArguments(""); - } - - @Override - public void onCommand(Sender sender, String cmd, String[] args) { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - sender.sendMessage("No features currently implemented in the command."); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/DisableCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/DisableCommand.java deleted file mode 100644 index 4fbf5ea1a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/DisableCommand.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; - -import javax.inject.Inject; - -public class DisableCommand extends CommandNode { - - private final Locale locale; - private final PlanPlugin plugin; - - @Inject - public DisableCommand(PlanPlugin plugin, Locale locale) { - super("disable", "plan.reload", CommandType.ALL); - - this.plugin = plugin; - this.locale = locale; - - setShortHelp(locale.getString(CmdHelpLang.DISABLE)); - setInDepthHelp(locale.getArray(DeepHelpLang.DISABLE)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - plugin.onDisable(); - sender.sendMessage(locale.getString(CommandLang.DISABLE_DISABLED)); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java deleted file mode 100644 index d48de1777..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.GenericLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; - -import javax.inject.Inject; - -/** - * This SubCommand is used to view the version and the database type in use. - * - * @author Rsl1122 - */ -public class InfoCommand extends CommandNode { - - private final PlanPlugin plugin; - private final Locale locale; - private final DBSystem dbSystem; - private final ConnectionSystem connectionSystem; - private final VersionCheckSystem versionCheckSystem; - - @Inject - public InfoCommand( - PlanPlugin plugin, - Locale locale, - DBSystem dbSystem, - ConnectionSystem connectionSystem, - VersionCheckSystem versionCheckSystem - ) { - super("info", Permissions.INFO.getPermission(), CommandType.CONSOLE); - - this.plugin = plugin; - this.locale = locale; - this.dbSystem = dbSystem; - this.connectionSystem = connectionSystem; - this.versionCheckSystem = versionCheckSystem; - - setShortHelp(locale.get(CmdHelpLang.INFO).toString()); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - String yes = locale.getString(GenericLang.YES); - String no = locale.getString(GenericLang.NO); - - String updateAvailable = versionCheckSystem.isNewVersionAvailable() ? yes : no; - String connectedToBungee = connectionSystem.isServerAvailable() ? yes : no; - - Database database = dbSystem.getDatabase(); - - String[] messages = { - locale.getString(CommandLang.HEADER_INFO), - "", - locale.getString(CommandLang.INFO_VERSION, plugin.getVersion()), - locale.getString(CommandLang.INFO_UPDATE, updateAvailable), - locale.getString(CommandLang.INFO_DATABASE, database.getType().getName() + " (" + database.getState().name() + ")"), - locale.getString(CommandLang.INFO_PROXY_CONNECTION, connectedToBungee), - "", - ">" - }; - sender.sendMessage(messages); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java deleted file mode 100644 index c6e356c4c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.PlayerFetchQueries; -import com.djrapitops.plan.db.access.queries.objects.WebUserQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.info.InfoProcessors; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plan.utilities.uuid.UUIDUtility; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import java.util.UUID; - -/** - * This command is used to refresh Inspect page and display link. - * - * @author Rsl1122 - */ -public class InspectCommand extends CommandNode { - - private final Locale locale; - private final DBSystem dbSystem; - private final WebServer webServer; - private final InfoProcessors processorFactory; - private final Processing processing; - private final ConnectionSystem connectionSystem; - private final UUIDUtility uuidUtility; - private final ErrorHandler errorHandler; - - @Inject - public InspectCommand( - Locale locale, - InfoProcessors processorFactory, - Processing processing, - DBSystem dbSystem, - WebServer webServer, - ConnectionSystem connectionSystem, - UUIDUtility uuidUtility, - ErrorHandler errorHandler - ) { - super("inspect", Permissions.INSPECT.getPermission(), CommandType.PLAYER_OR_ARGS); - this.processorFactory = processorFactory; - this.processing = processing; - this.connectionSystem = connectionSystem; - setArguments(""); - - this.locale = locale; - this.dbSystem = dbSystem; - this.webServer = webServer; - this.uuidUtility = uuidUtility; - this.errorHandler = errorHandler; - - setShortHelp(locale.getString(CmdHelpLang.INSPECT)); - setInDepthHelp(locale.getArray(DeepHelpLang.INSPECT)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - String playerName = MiscUtils.getPlayerName(args, sender); - - if (playerName == null) { - sender.sendMessage(locale.getString(CommandLang.FAIL_NO_PERMISSION)); - } - - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - runInspectTask(playerName, sender); - } - - private void runInspectTask(String playerName, Sender sender) { - processing.submitNonCritical(() -> { - try { - UUID playerUUID = uuidUtility.getUUIDOf(playerName); - if (playerUUID == null) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_VALID)); - return; - } - - if (!dbSystem.getDatabase().query(PlayerFetchQueries.isPlayerRegistered(playerUUID))) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_KNOWN)); - return; - } - - checkWebUserAndNotify(sender); - processing.submit(processorFactory.inspectCacheRequestProcessor(playerUUID, sender, playerName, this::sendInspectMsg)); - } catch (DBOpException e) { - sender.sendMessage("§eDatabase exception occurred: " + e.getMessage()); - errorHandler.log(L.ERROR, this.getClass(), e); - } - }); - } - - private void checkWebUserAndNotify(Sender sender) { - if (CommandUtils.isPlayer(sender) && webServer.isAuthRequired()) { - boolean senderHasWebUser = dbSystem.getDatabase().query(WebUserQueries.fetchWebUser(sender.getName())).isPresent(); - - if (!senderHasWebUser) { - sender.sendMessage("§e" + locale.getString(CommandLang.NO_WEB_USER_NOTIFY)); - } - } - } - - private void sendInspectMsg(Sender sender, String playerName) { - sender.sendMessage(locale.getString(CommandLang.HEADER_INSPECT, playerName)); - - String url = connectionSystem.getMainAddress() + "/player/" + playerName; - String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); - - boolean console = !CommandUtils.isPlayer(sender); - if (console) { - sender.sendMessage(linkPrefix + url); - } else { - sender.sendMessage(linkPrefix); - sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); - } - - sender.sendMessage(">"); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ListPlayersCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ListPlayersCommand.java deleted file mode 100644 index e301fcba0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ListPlayersCommand.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.Sender; - -import javax.inject.Inject; - -/** - * Command used to display url to the player list page. - * - * @author Rsl1122 - */ -public class ListPlayersCommand extends CommandNode { - - private final Locale locale; - private final ConnectionSystem connectionSystem; - - @Inject - public ListPlayersCommand(Locale locale, ConnectionSystem connectionSystem) { - super("players|pl|playerlist|list", Permissions.INSPECT_OTHER.getPermission(), CommandType.CONSOLE); - - this.locale = locale; - this.connectionSystem = connectionSystem; - - setShortHelp(locale.getString(CmdHelpLang.PLAYERS)); - setInDepthHelp(locale.getArray(DeepHelpLang.PLAYERS)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - sendListMsg(sender); - } - - private void sendListMsg(Sender sender) { - sender.sendMessage(locale.getString(CommandLang.HEADER_PLAYERS)); - - // Link - String url = connectionSystem.getMainAddress() + "/players/"; - String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); - boolean console = !CommandUtils.isPlayer(sender); - if (console) { - sender.sendMessage(linkPrefix + url); - } else { - sender.sendMessage(linkPrefix); - sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); - } - sender.sendMessage(">"); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java deleted file mode 100644 index ab4867e7c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * This SubCommand is used to list all servers found in the database. - * - * @author Rsl1122 - */ -public class ListServersCommand extends CommandNode { - - private final Locale locale; - private final ColorScheme colorScheme; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public ListServersCommand( - Locale locale, - ColorScheme colorScheme, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - super("servers|serverlist|listservers|sl|ls", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); - - this.locale = locale; - this.colorScheme = colorScheme; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - - setShortHelp(locale.getString(CmdHelpLang.SERVERS)); - setInDepthHelp(locale.getArray(DeepHelpLang.SERVERS)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - String sCol = colorScheme.getSecondaryColor(); - String tCol = colorScheme.getTertiaryColor(); - Formatter serverFormatter = serverLister(sCol, tCol); - try { - sender.sendMessage(locale.getString(CommandLang.HEADER_SERVERS)); - sendServers(sender, serverFormatter); - sender.sendMessage(">"); - } catch (DBOpException e) { - sender.sendMessage("§cDatabase Exception occurred."); - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - private void sendServers(Sender sender, Formatter serverFormatter) { - List servers = new ArrayList<>(dbSystem.getDatabase().query(ServerQueries.fetchPlanServerInformation()).values()); - Collections.sort(servers); - for (Server server : servers) { - sender.sendMessage(serverFormatter.apply(server)); - } - } - - private Formatter serverLister(String tertiaryColor, String secondaryColor) { - return server -> " " + tertiaryColor + server.getId() + secondaryColor + " : " + server.getName() + " : " + server.getWebAddress(); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java deleted file mode 100644 index ad95725d6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.command.commands.manage.*; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.TreeCmdNode; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Named; - -/** - * This SubCommand is used to manage the the plugin's database and components. - * - * @author Rsl1122 - */ -public class ManageCommand extends TreeCmdNode { - - @Inject - public ManageCommand(ColorScheme colorScheme, Locale locale, @Named("mainCommand") Lazy parent, - // Group 1 - ManageRawDataCommand rawDataCommand, - ManageMoveCommand moveCommand, - ManageBackupCommand backupCommand, - ManageRemoveCommand removeCommand, - ManageRestoreCommand restoreCommand, - ManageHotSwapCommand hotSwapCommand, - ManageClearCommand clearCommand, - // Group 2 - ManageSetupCommand setupCommand, - ManageConDebugCommand conDebugCommand, - ManageImportCommand importCommand, - ManageExportCommand exportCommand, - ManageDisableCommand disableCommand, - ManageUninstalledCommand uninstalledCommand - ) { - super("manage|m", Permissions.MANAGE.getPermission(), CommandType.CONSOLE, parent.get()); - super.setColorScheme(colorScheme); - - setShortHelp(locale.getString(CmdHelpLang.MANAGE)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE)); - CommandNode[] databaseGroup = { - rawDataCommand, - moveCommand, - backupCommand, - restoreCommand, - hotSwapCommand, - removeCommand, - clearCommand, - }; - CommandNode[] pluginGroup = { - setupCommand, - conDebugCommand, - importCommand, - exportCommand, - disableCommand, - uninstalledCommand - }; - setNodeGroups(databaseGroup, pluginGroup); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java deleted file mode 100644 index 8d4a49bc0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.Sender; - -import javax.inject.Inject; - -/** - * Command used to display url to the network page. - * - * @author Rsl1122 - */ -public class NetworkCommand extends CommandNode { - - private final Locale locale; - private final ConnectionSystem connectionSystem; - - @Inject - public NetworkCommand(Locale locale, ConnectionSystem connectionSystem) { - super("network|n|netw", Permissions.ANALYZE.getPermission(), CommandType.CONSOLE); - - this.locale = locale; - this.connectionSystem = connectionSystem; - - setShortHelp(locale.getString(CmdHelpLang.NETWORK)); - setInDepthHelp(locale.getArray(DeepHelpLang.NETWORK)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - sendNetworkMsg(sender); - } - - private void sendNetworkMsg(Sender sender) { - sender.sendMessage(locale.getString(CommandLang.HEADER_NETWORK)); - - // Link - String url = connectionSystem.getMainAddress() + "/network/"; - String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); - boolean console = !CommandUtils.isPlayer(sender); - if (console) { - sender.sendMessage(linkPrefix + url); - } else { - sender.sendMessage(linkPrefix); - sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); - } - sender.sendMessage(">"); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java deleted file mode 100644 index 1e8786ae2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.mutators.ActivityIndex; -import com.djrapitops.plan.data.store.mutators.GeoInfoMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.containers.ContainerFetchQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.GenericLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.formatting.Formatters; -import com.djrapitops.plan.utilities.uuid.UUIDUtility; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -/** - * This command is used to cache UserInfo to InspectCache and display the link. - * - * @author Rsl1122 - */ -@Singleton -public class QInspectCommand extends CommandNode { - - private final Locale locale; - private final DBSystem dbSystem; - private final PlanConfig config; - private final Processing processing; - private final Formatters formatters; - private final UUIDUtility uuidUtility; - private final ErrorHandler errorHandler; - - @Inject - public QInspectCommand( - PlanConfig config, - Locale locale, - Processing processing, - DBSystem dbSystem, - UUIDUtility uuidUtility, - Formatters formatters, - ErrorHandler errorHandler - ) { - super("qinspect", Permissions.QUICK_INSPECT.getPermission(), CommandType.PLAYER_OR_ARGS); - this.config = config; - this.processing = processing; - this.formatters = formatters; - setArguments(""); - - this.locale = locale; - this.dbSystem = dbSystem; - this.uuidUtility = uuidUtility; - this.errorHandler = errorHandler; - - setShortHelp(locale.getString(CmdHelpLang.QINSPECT)); - setInDepthHelp(locale.getArray(DeepHelpLang.QINSPECT)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - String playerName = MiscUtils.getPlayerName(args, sender, Permissions.QUICK_INSPECT_OTHER); - - if (playerName == null) { - sender.sendMessage(locale.getString(CommandLang.FAIL_NO_PERMISSION)); - return; - } - - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - runInspectTask(playerName, sender); - } - - private void runInspectTask(String playerName, Sender sender) { - processing.submitNonCritical(() -> { - try { - UUID uuid = uuidUtility.getUUIDOf(playerName); - if (uuid == null) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_VALID)); - return; - } - - PlayerContainer container = dbSystem.getDatabase().query(ContainerFetchQueries.fetchPlayerContainer(uuid)); - if (!container.getValue(PlayerKeys.REGISTERED).isPresent()) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_KNOWN)); - return; - } - - sendMessages(sender, container); - } catch (DBOpException e) { - sender.sendMessage("§eDatabase exception occurred: " + e.getMessage()); - errorHandler.log(L.WARN, this.getClass(), e); - } - }); - } - - private void sendMessages(Sender sender, PlayerContainer player) { - long now = System.currentTimeMillis(); - - Formatter timestamp = formatters.year(); - Formatter length = formatters.timeAmount(); - - String playerName = player.getValue(PlayerKeys.NAME).orElse(locale.getString(GenericLang.UNKNOWN)); - - ActivityIndex activityIndex = player.getActivityIndex( - now, - config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), - config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD) - ); - Long registered = player.getValue(PlayerKeys.REGISTERED).orElse(0L); - Long lastSeen = player.getValue(PlayerKeys.LAST_SEEN).orElse(0L); - List geoInfo = player.getValue(PlayerKeys.GEO_INFO).orElse(new ArrayList<>()); - Optional mostRecentGeoInfo = new GeoInfoMutator(geoInfo).mostRecent(); - String geolocation = mostRecentGeoInfo.isPresent() ? mostRecentGeoInfo.get().getGeolocation() : "-"; - SessionsMutator sessionsMutator = SessionsMutator.forContainer(player); - - String[] messages = new String[]{ - locale.getString(CommandLang.HEADER_INSPECT, playerName), - locale.getString(CommandLang.QINSPECT_ACTIVITY_INDEX, activityIndex.getFormattedValue(formatters.decimals()), activityIndex.getGroup()), - locale.getString(CommandLang.QINSPECT_REGISTERED, timestamp.apply(() -> registered)), - locale.getString(CommandLang.QINSPECT_LAST_SEEN, timestamp.apply(() -> lastSeen)), - locale.getString(CommandLang.QINSPECT_GEOLOCATION, geolocation), - locale.getString(CommandLang.QINSPECT_PLAYTIME, length.apply(sessionsMutator.toPlaytime())), - locale.getString(CommandLang.QINSPECT_LONGEST_SESSION, length.apply(sessionsMutator.toLongestSessionLength())), - locale.getString(CommandLang.QINSPECT_TIMES_KICKED, player.getValue(PlayerKeys.KICK_COUNT).orElse(0)), - "", - locale.getString(CommandLang.QINSPECT_PLAYER_KILLS, sessionsMutator.toPlayerKillCount()), - locale.getString(CommandLang.QINSPECT_MOB_KILLS, sessionsMutator.toMobKillCount()), - locale.getString(CommandLang.QINSPECT_DEATHS, sessionsMutator.toDeathCount()), - ">" - }; - sender.sendMessage(messages); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java deleted file mode 100644 index 15ad88944..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.WebUserQueries; -import com.djrapitops.plan.db.access.transactions.commands.RegisterWebUserTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.utilities.PassEncryptUtil; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -/** - * Command for registering web users. - *

- * Registers a new WebUser to the database. - *

- * No permission required for self registration. (Super constructor string is empty). - * {@code Permissions.MANAGE_WEB} required for registering other users. - * - * @author Rsl1122 - */ -@Singleton -public class RegisterCommand extends CommandNode { - - private final String notEnoughArgsMsg; - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final ConnectionSystem connectionSystem; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - @Inject - public RegisterCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - ConnectionSystem connectionSystem, - PluginLogger logger, - ErrorHandler errorHandler - ) { - // No Permission Requirement - super("register", "", CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - this.processing = processing; - this.connectionSystem = connectionSystem; - this.logger = logger; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - - setArguments("", "[name]", "[lvl]"); - setShortHelp(locale.getString(CmdHelpLang.WEB_REGISTER)); - setInDepthHelp(locale.getArray(DeepHelpLang.WEB_REGISTER)); - - notEnoughArgsMsg = locale.getString(CommandLang.FAIL_REQ_ARGS, 3, Arrays.toString(getArguments())); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - try { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - if (CommandUtils.isPlayer(sender)) { - playerRegister(args, sender); - } else { - consoleRegister(args, sender, notEnoughArgsMsg); - } - } catch (PassEncryptUtil.CannotPerformOperationException e) { - errorHandler.log(L.WARN, this.getClass(), e); - sender.sendMessage("§cPassword hash error."); - } catch (NumberFormatException e) { - throw new NumberFormatException(args[2]); - } catch (IllegalArgumentException e) { - throw e; - } catch (Exception e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - private void consoleRegister(String[] args, Sender sender, String notEnoughArgsMsg) throws PassEncryptUtil.CannotPerformOperationException { - Verify.isTrue(args.length >= 3, () -> new IllegalArgumentException(notEnoughArgsMsg)); - - int permLevel; - permLevel = Integer.parseInt(args[2]); - String passHash = PassEncryptUtil.createHash(args[0]); - registerUser(new WebUser(args[1], passHash, permLevel), sender); - } - - private void playerRegister(String[] args, Sender sender) throws PassEncryptUtil.CannotPerformOperationException { - boolean registerSenderAsUser = args.length == 1; - if (registerSenderAsUser) { - String user = sender.getName(); - String pass = PassEncryptUtil.createHash(args[0]); - int permLvl = getPermissionLevel(sender); - registerUser(new WebUser(user, pass, permLvl), sender); - } else if (sender.hasPermission(Permissions.MANAGE_WEB.getPermission())) { - consoleRegister(args, sender, notEnoughArgsMsg); - } else { - sender.sendMessage(locale.getString(CommandLang.FAIL_NO_PERMISSION)); - } - } - - private int getPermissionLevel(Sender sender) { - final String permAnalyze = Permissions.ANALYZE.getPerm(); - final String permInspectOther = Permissions.INSPECT_OTHER.getPerm(); - final String permInspect = Permissions.INSPECT.getPerm(); - if (sender.hasPermission(permAnalyze)) { - return 0; - } - if (sender.hasPermission(permInspectOther)) { - return 1; - } - if (sender.hasPermission(permInspect)) { - return 2; - } - return 100; - } - - private void registerUser(WebUser webUser, Sender sender) { - processing.submitCritical(() -> { - String userName = webUser.getName(); - try { - Database database = dbSystem.getDatabase(); - boolean userExists = database.query(WebUserQueries.fetchWebUser(userName)).isPresent(); - if (userExists) { - sender.sendMessage(locale.getString(CommandLang.FAIL_WEB_USER_EXISTS)); - return; - } - database.executeTransaction(new RegisterWebUserTransaction(webUser)) - .get(); // Wait for completion - - sender.sendMessage(locale.getString(CommandLang.WEB_USER_REGISTER_SUCCESS, userName)); - sendLink(sender); - logger.info(locale.getString(CommandLang.WEB_USER_REGISTER_NOTIFY, userName, webUser.getPermLevel())); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (DBOpException | ExecutionException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - }); - } - - private void sendLink(Sender sender) { - String url = connectionSystem.getMainAddress(); - String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); - // Link - boolean console = !CommandUtils.isPlayer(sender); - if (console) { - sender.sendMessage(linkPrefix + url); - } else { - sender.sendMessage(linkPrefix); - sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java deleted file mode 100644 index a2a31d804..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; - -import javax.inject.Inject; - -/** - * This SubCommand is used to reload the plugin. - * - * @author Rsl1122 - */ -public class ReloadCommand extends CommandNode { - - private final PlanPlugin plugin; - private final Locale locale; - private final ErrorHandler errorHandler; - private final RunnableFactory runnableFactory; - - @Inject - public ReloadCommand(PlanPlugin plugin, Locale locale, RunnableFactory runnableFactory, ErrorHandler errorHandler) { - super("reload", Permissions.RELOAD.getPermission(), CommandType.CONSOLE); - - this.plugin = plugin; - this.locale = locale; - this.runnableFactory = runnableFactory; - this.errorHandler = errorHandler; - - setShortHelp(locale.getString(CmdHelpLang.RELOAD)); - setInDepthHelp(locale.getArray(DeepHelpLang.RELOAD)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - runnableFactory.create("Reload task", new AbsRunnable() { - @Override - public void run() { - try { - plugin.reloadPlugin(true); - } catch (Exception e) { - errorHandler.log(L.CRITICAL, this.getClass(), e); - sender.sendMessage(locale.getString(CommandLang.RELOAD_FAILED)); - } - sender.sendMessage(locale.getString(CommandLang.RELOAD_COMPLETE)); - } - }).runTaskAsynchronously(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java deleted file mode 100644 index 63e977156..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * This SubCommand is used to search for a user. - * - * @author Rsl1122 - */ -@Singleton -public class SearchCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public SearchCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - ErrorHandler errorHandler) { - super("search", Permissions.SEARCH.getPermission(), CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - - setArguments(""); - setShortHelp(locale.getString(CmdHelpLang.SEARCH)); - setInDepthHelp(locale.getArray(DeepHelpLang.SEARCH)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - - runSearchTask(args, sender); - } - - private void runSearchTask(String[] args, Sender sender) { - processing.submitNonCritical(() -> { - try { - String searchFor = args[0]; - List names = dbSystem.getDatabase().query(UserIdentifierQueries.fetchMatchingPlayerNames(searchFor)); - Collections.sort(names); - boolean empty = Verify.isEmpty(names); - - sender.sendMessage(locale.getString(CommandLang.HEADER_SEARCH, empty ? 0 : names.size(), searchFor)); - // Results - if (!empty) { - String message = names.toString(); - sender.sendMessage(message.substring(1, message.length() - 1)); - } - - sender.sendMessage(">"); - } catch (DBOpException e) { - sender.sendMessage("§cDatabase error occurred: " + e.getMessage()); - errorHandler.log(L.ERROR, this.getClass(), e); - } - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java deleted file mode 100644 index b8d311473..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.command.commands.webuser.WebCheckCommand; -import com.djrapitops.plan.command.commands.webuser.WebDeleteCommand; -import com.djrapitops.plan.command.commands.webuser.WebLevelCommand; -import com.djrapitops.plan.command.commands.webuser.WebListUsersCommand; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.TreeCmdNode; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Named; - -/** - * Web subcommand used to manage Web users. - * - * @author Rsl1122 - */ -public class WebUserCommand extends TreeCmdNode { - - @Inject - public WebUserCommand(ColorScheme colorScheme, Locale locale, @Named("mainCommand") Lazy parent, - RegisterCommand registerCommand, - WebLevelCommand levelCommand, - WebListUsersCommand listUsersCommand, - WebCheckCommand checkCommand, - WebDeleteCommand deleteCommand - ) { - super("webuser|web", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE, parent.get()); - super.setColorScheme(colorScheme); - - setShortHelp(locale.getString(CmdHelpLang.WEB)); - setInDepthHelp(locale.getArray(DeepHelpLang.WEB)); - CommandNode[] webGroup = { - registerCommand, - levelCommand, - listUsersCommand, - checkCommand, - deleteCommand - }; - setNodeGroups(webGroup); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java deleted file mode 100644 index 68b86db3f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.SQLiteDB; -import com.djrapitops.plan.db.access.queries.ServerAggregateQueries; -import com.djrapitops.plan.db.access.transactions.BackupCopyTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.formatting.Formatters; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -/** - * This command is used to backup a database to a .db file. - * - * @author Rsl1122 - */ -@Singleton -public class ManageBackupCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final SQLiteDB.Factory sqliteFactory; - private final ErrorHandler errorHandler; - - private final Formatter iso8601LongFormatter; - - @Inject - public ManageBackupCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - SQLiteDB.Factory sqliteFactory, - Formatters formatters, - ErrorHandler errorHandler - ) { - super("backup", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.sqliteFactory = sqliteFactory; - this.errorHandler = errorHandler; - - this.iso8601LongFormatter = formatters.iso8601NoClockLong(); - - setShortHelp(locale.getString(CmdHelpLang.MANAGE_BACKUP)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_BACKUP)); - setArguments(""); - - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - try { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - String dbName = args[0].toLowerCase(); - - boolean isCorrectDB = DBType.exists(dbName); - Verify.isTrue(isCorrectDB, - () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_INCORRECT_DB, dbName))); - - Database database = dbSystem.getActiveDatabaseByName(dbName); - database.init(); - - runBackupTask(sender, args, database); - } catch (DBInitException e) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - } - - private void runBackupTask(Sender sender, String[] args, Database database) { - processing.submitCritical(() -> { - try { - Database.State dbState = database.getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.WARN_DATABASE_NOT_OPEN, dbState.name())); - } - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - createNewBackup(args[0], database); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (Exception e) { - errorHandler.log(L.ERROR, ManageBackupCommand.class, e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - }); - } - - /** - * Creates a new backup sqlite file with the data of given database. - * - * @param dbName Name of database (mysql/sqlite) - * @param copyFromDB Database you want to backup. - */ - private void createNewBackup(String dbName, Database copyFromDB) { - Integer userCount = copyFromDB.query(ServerAggregateQueries.baseUserCount()); - if (userCount <= 0) { - return; - } - SQLiteDB backupDB = null; - try { - String timeStamp = iso8601LongFormatter.apply(System.currentTimeMillis()); - String fileName = dbName + "-backup-" + timeStamp; - backupDB = sqliteFactory.usingFileCalled(fileName); - backupDB.init(); - backupDB.executeTransaction(new BackupCopyTransaction(copyFromDB, backupDB)).get(); - } catch (DBOpException | ExecutionException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } catch (InterruptedException e) { - backupDB.close(); - Thread.currentThread().interrupt(); - } finally { - if (backupDB != null) { - backupDB.close(); - } - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java deleted file mode 100644 index f2ce884e2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.commands.RemoveEverythingTransaction; -import com.djrapitops.plan.query.QueryServiceImplementation; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; -import java.util.concurrent.ExecutionException; - -/** - * This manage SubCommand is used to clear a database of all data. - * - * @author Rsl1122 - */ -@Singleton -public class ManageClearCommand extends CommandNode { - - private final PlanPlugin plugin; - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final QueryServiceImplementation queryService; - private final ErrorHandler errorHandler; - - @Inject - public ManageClearCommand( - PlanPlugin plugin, - Locale locale, - Processing processing, - DBSystem dbSystem, - QueryServiceImplementation queryService, - ErrorHandler errorHandler - ) { - super("clear", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - this.plugin = plugin; - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.queryService = queryService; - this.errorHandler = errorHandler; - - setArguments("", "[-a]"); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_CLEAR)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_CLEAR)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - String dbName = args[0].toLowerCase(); - - boolean isCorrectDB = DBType.exists(dbName); - Verify.isTrue(isCorrectDB, - () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_INCORRECT_DB, dbName))); - - if (!Verify.contains("-a", args)) { - sender.sendMessage(locale.getString(ManageLang.CONFIRMATION, locale.getString(ManageLang.CONFIRM_REMOVAL, dbName))); - return; - } - - try { - Database database = dbSystem.getActiveDatabaseByName(dbName); - database.init(); - runClearTask(sender, database); - } catch (DBInitException e) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - } - - private void runClearTask(Sender sender, Database database) { - processing.submitCritical(() -> { - try { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - database.executeTransaction(new RemoveEverythingTransaction()) - .get(); // Wait for completion - queryService.dataCleared(); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - reloadPlugin(sender); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (DBOpException | ExecutionException e) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - errorHandler.log(L.ERROR, this.getClass(), e); - } - }); - } - - private void reloadPlugin(Sender sender) { - try { - plugin.reloadPlugin(true); - } catch (Exception e) { - errorHandler.log(L.CRITICAL, this.getClass(), e); - sender.sendMessage(locale.getString(CommandLang.RELOAD_FAILED)); - } - sender.sendMessage(locale.getString(CommandLang.RELOAD_COMPLETE)); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java deleted file mode 100644 index bed68b24f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.api.exceptions.connection.*; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.request.InfoRequestFactory; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Map; -import java.util.UUID; - -/** - * This manage SubCommand is used to request settings from Bungee so that connection can be established. - * - * @author Rsl1122 - */ -@Singleton -public class ManageConDebugCommand extends CommandNode { - - private final ColorScheme colorScheme; - private final Locale locale; - private final Processing processing; - private final ServerInfo serverInfo; - private final ConnectionSystem connectionSystem; - private final InfoRequestFactory infoRequestFactory; - private final WebServer webServer; - private final DBSystem dbSystem; - - @Inject - public ManageConDebugCommand( - ColorScheme colorScheme, - Locale locale, - Processing processing, - ServerInfo serverInfo, - ConnectionSystem connectionSystem, - InfoRequestFactory infoRequestFactory, - WebServer webServer, - DBSystem dbSystem - ) { - super("con", Permissions.MANAGE.getPermission(), CommandType.ALL); - - this.colorScheme = colorScheme; - this.locale = locale; - this.processing = processing; - this.serverInfo = serverInfo; - this.connectionSystem = connectionSystem; - this.infoRequestFactory = infoRequestFactory; - this.webServer = webServer; - this.dbSystem = dbSystem; - - boolean isProxy = serverInfo.getServer() != null && serverInfo.getServer().isProxy(); - setShortHelp(locale.getString(isProxy ? CmdHelpLang.CON : CmdHelpLang.MANAGE_CON)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_CON)); - } - - private void testServer(Sender sender, Server server, Locale locale) { - String address = server.getWebAddress().toLowerCase(); - boolean usingHttps = address.startsWith("https"); - boolean local = address.contains("localhost") - || address.startsWith("https://:") // IP empty = Localhost - || address.startsWith("http://:") // IP empty = Localhost - || address.contains("127.0.0.1"); - - try { - connectionSystem.sendInfoRequest(infoRequestFactory.checkConnectionRequest(address), server); - sender.sendMessage(getMsgFor(address, usingHttps, local, true, true)); - } catch (UnauthorizedServerException e) { - sender.sendMessage(getMsgFor(address, usingHttps, local, true, false)); - sender.sendMessage(locale.getString(ManageLang.CON_UNAUTHORIZED)); - } catch (ConnectionFailException e) { - sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); - sender.sendMessage(locale.getString(ManageLang.CON_GENERIC_FAIL) + e.getCause().getClass().getSimpleName() + " " + e.getCause().getMessage()); - if (!local) { - sender.sendMessage(locale.getString(ManageLang.CON_EXTERNAL_URL)); - } - } catch (GatewayException e) { - sender.sendMessage(getMsgFor(address, usingHttps, local, true, false)); - } catch (NotFoundException e) { - sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); - sender.sendMessage(locale.getString(ManageLang.CON_OLD_VERSION)); - } catch (WebException e) { - sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); - sender.sendMessage(locale.getString(ManageLang.CON_EXCEPTION, e.getClass().getSimpleName())); - } - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - if (!webServer.isEnabled()) { - sender.sendMessage(locale.getString(CommandLang.CONNECT_WEBSERVER_NOT_ENABLED)); - return; - } - - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - processing.submitNonCritical(() -> testServers(sender)); - } - - private void testServers(Sender sender) { - Map servers = dbSystem.getDatabase().query(ServerQueries.fetchPlanServerInformation()); - - if (servers.isEmpty()) { - sender.sendMessage(locale.getString(ManageLang.CON_NO_SERVERS)); - } - - UUID thisServer = serverInfo.getServerUUID(); - for (Server server : servers.values()) { - if (thisServer.equals(server.getUuid())) { - continue; - } - testServer(sender, server, locale); - } - } - - private String getMsgFor(String address, boolean usingHttps, boolean local, boolean successTo, boolean successFrom) { - String tCol = colorScheme.getTertiaryColor(); - String sCol = colorScheme.getSecondaryColor(); - return tCol + address + sCol + ": " - + (usingHttps ? "HTTPS" : "HTTP") + " : " - + (local ? "Local" : "External") + " : " - + "To:" + (successTo ? "§aOK" : "§cFail") + sCol + " : " - + "From:" + (successFrom ? "§aOK" : "§cFail"); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java deleted file mode 100644 index 913c32886..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.status.Status; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import java.util.Arrays; - -/** - * This manage SubCommand is used to disable some features of the plugin temporarily. - * - * @author Rsl1122 - */ -public class ManageDisableCommand extends CommandNode { - - private final Locale locale; - private final Status status; - - @Inject - public ManageDisableCommand( - Locale locale, - Status status - ) { - super("disable", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - this.status = status; - - setArguments(""); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_DISABLE)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_DISABLE)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - if ("kickcount".equalsIgnoreCase(args[0])) { - status.setCountKicks(false); - sender.sendMessage(locale.getString(CommandLang.FEATURE_DISABLED, "Kick Counting")); - } else { - sender.sendMessage(locale.getString(CommandLang.FAIL_NO_SUCH_FEATURE, "'kickcount'")); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageExportCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageExportCommand.java deleted file mode 100644 index d2a6fd570..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageExportCommand.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.export.HtmlExport; -import com.djrapitops.plan.system.export.JSONExport; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.ExportSettings; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; -import java.util.Map; -import java.util.UUID; -import java.util.function.Consumer; - -/** - * This manage SubCommand is used to import data from 3rd party plugins. - * - * @author Rsl1122 - */ -@Singleton -public class ManageExportCommand extends CommandNode { - - private final Locale locale; - private final ColorScheme colorScheme; - private final PlanConfig config; - private final DBSystem dbSystem; - private final ServerInfo serverInfo; - private final HtmlExport htmlExport; - private final JSONExport jsonExport; - private final Processing processing; - - @Inject - public ManageExportCommand( - Locale locale, - ColorScheme colorScheme, - PlanConfig config, - DBSystem dbSystem, - ServerInfo serverInfo, - Processing processing, - HtmlExport htmlExport, - JSONExport jsonExport - ) { - super("export", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); - - this.locale = locale; - this.colorScheme = colorScheme; - this.config = config; - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.htmlExport = htmlExport; - this.jsonExport = jsonExport; - this.processing = processing; - - setArguments("/list"); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_EXPORT)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_EXPORT)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, "1+", Arrays.toString(this.getArguments())))); - - String exportArg = args[0]; - - if ("list".equals(exportArg)) { - sender.sendMessage("> " + colorScheme.getMainColor() + "players, server_json"); - return; - } - - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - getExportFunction(exportArg).accept(sender); - } - - private Consumer getExportFunction(String exportArg) { - switch (exportArg) { - case "players": - return this::exportPlayers; - case "server_json": - return this::exportServerJSON; - default: - return sender -> sender.sendMessage(locale.getString(ManageLang.FAIL_EXPORTER_NOT_FOUND, exportArg)); - } - } - - private void exportServerJSON(Sender sender) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - processing.submitNonCritical(() -> { - jsonExport.exportServerJSON(serverInfo.getServerUUID()); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - }); - } - - private void exportPlayers(Sender sender) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - if (config.get(ExportSettings.PLAYERS_PAGE)) { - processing.submitNonCritical(htmlExport::exportPlayersPage); - } - Boolean exportPlayerJSON = config.get(ExportSettings.PLAYER_JSON); - Boolean exportPlayerHTML = config.get(ExportSettings.PLAYER_PAGES); - processing.submitNonCritical(() -> { - Map players = dbSystem.getDatabase().query(UserIdentifierQueries.fetchAllPlayerNames()); - int size = players.size(); - int i = 1; - for (Map.Entry entry : players.entrySet()) { - if (exportPlayerJSON) { - jsonExport.exportPlayerJSON(entry.getKey()); - } - if (exportPlayerHTML) { - htmlExport.exportPlayerPage(entry.getKey(), entry.getValue()); - } - i++; - if (i % 1000 == 0) { - sender.sendMessage(i + " / " + size + " processed.."); - } - } - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java deleted file mode 100644 index e4179e6ed..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DatabaseSettings; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import java.io.IOException; -import java.util.Arrays; - -/** - * This manage SubCommand is used to swap to a different database and reload the - * plugin if the connection to the new database can be established. - * - * @author Rsl1122 - */ -public class ManageHotSwapCommand extends CommandNode { - - private final PlanPlugin plugin; - private final Locale locale; - private final DBSystem dbSystem; - private final PlanConfig config; - private final ErrorHandler errorHandler; - - @Inject - public ManageHotSwapCommand(PlanPlugin plugin, Locale locale, DBSystem dbSystem, PlanConfig config, ErrorHandler errorHandler) { - super("hotswap", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - - this.plugin = plugin; - this.locale = locale; - this.dbSystem = dbSystem; - this.config = config; - this.errorHandler = errorHandler; - - setArguments(""); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_HOTSWAP)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - String dbName = args[0].toLowerCase(); - - boolean isCorrectDB = DBType.exists(dbName); - Verify.isTrue(isCorrectDB, - () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_INCORRECT_DB, dbName))); - - Verify.isFalse(dbName.equals(dbSystem.getDatabase().getType().getConfigName()), - () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_SAME_DB))); - - try { - Database database = dbSystem.getActiveDatabaseByName(dbName); - database.init(); - - if (database.getState() == Database.State.CLOSED) { - return; - } - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - return; - } - - try { - config.set(DatabaseSettings.TYPE, dbName); - config.save(); - } catch (IOException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - return; - } - plugin.reloadPlugin(true); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java deleted file mode 100644 index 608baae6a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.importing.ImportSystem; -import com.djrapitops.plan.system.importing.importers.Importer; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; -import java.util.Optional; - -/** - * This manage SubCommand is used to import data from 3rd party plugins. - * - * @author Rsl1122 - */ -@Singleton -public class ManageImportCommand extends CommandNode { - - private final Locale locale; - private final DBSystem dbSystem; - private final Processing processing; - private final ImportSystem importSystem; - - @Inject - public ManageImportCommand( - Locale locale, - DBSystem dbSystem, - Processing processing, - ImportSystem importSystem - ) { - super("import", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); - - this.locale = locale; - this.dbSystem = dbSystem; - this.processing = processing; - this.importSystem = importSystem; - - setArguments("/list", "[import args]"); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_IMPORT)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_IMPORT)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, "1+", Arrays.toString(this.getArguments())))); - - String importArg = args[0]; - - if ("list".equals(importArg)) { - sender.sendMessage(locale.getString(ManageLang.IMPORTERS)); - importSystem.getImporterNames().forEach(name -> sender.sendMessage("- " + name)); - return; - } - - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - findAndProcessImporter(sender, importArg); - } - - private void findAndProcessImporter(Sender sender, String importArg) { - Optional foundImporter = importSystem.getImporter(importArg); - if (foundImporter.isPresent()) { - Importer importer = foundImporter.get(); - processing.submitNonCritical(() -> { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - importer.processImport(); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - }); - } else { - sender.sendMessage(locale.getString(ManageLang.FAIL_IMPORTER_NOT_FOUND, importArg)); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java deleted file mode 100644 index 2dec242fd..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.BackupCopyTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; - -/** - * This manage SubCommand is used to move all data from one database to another. - *

- * Destination database will be cleared. - * - * @author Rsl1122 - */ -@Singleton -public class ManageMoveCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public ManageMoveCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - super("move", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - - setArguments("", "", "[-a]"); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_MOVE)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_MOVE)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 2, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 2, Arrays.toString(this.getArguments())))); - - DBType fromDB = DBType.getForName(args[0]) - .orElseThrow(() -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_INCORRECT_DB, args[0]))); - - DBType toDB = DBType.getForName(args[1]) - .orElseThrow(() -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_INCORRECT_DB, args[1]))); - - Verify.isFalse(fromDB == toDB, - () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_SAME_DB))); - - if (!Verify.contains("-a", args)) { - sender.sendMessage(locale.getString(ManageLang.CONFIRMATION, locale.getString(ManageLang.CONFIRM_OVERWRITE, toDB.getConfigName()))); - return; - } - - // Temporarily disabled due to issues - boolean transferH2 = fromDB == DBType.H2 || toDB == DBType.H2; - boolean transferMySQL = fromDB == DBType.MYSQL || toDB == DBType.MYSQL; - - if (transferH2 && transferMySQL) { - sender.sendMessage("§cDirect transfers between H2 and MySQL are temporarily disabled due to a bug: See the issue link for workaround"); - sender.sendLink("Link to Github Issue", "https://github.com/plan-player-analytics/Plan/issues/1111"); - return; - } - - try { - final Database fromDatabase = dbSystem.getActiveDatabaseByType(fromDB); - final Database toDatabase = dbSystem.getActiveDatabaseByType(toDB); - fromDatabase.init(); - toDatabase.init(); - - runMoveTask(fromDatabase, toDatabase, sender); - } catch (Exception e) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - } - - private void runMoveTask(final Database fromDatabase, final Database toDatabase, Sender sender) { - processing.submitCritical(() -> { - try { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - - toDatabase.executeTransaction(new BackupCopyTransaction(fromDatabase, toDatabase)).get(); - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - - boolean movingToCurrentDB = toDatabase.getType() == dbSystem.getDatabase().getType(); - if (movingToCurrentDB) { - sender.sendMessage(locale.getString(ManageLang.HOTSWAP_REMINDER, toDatabase.getType().getConfigName())); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java deleted file mode 100644 index 7a8822883..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import java.util.Arrays; - -/** - * This manage subcommand is used to remove a single player's data from the - * database. - * - * @author Rsl1122 - */ -public class ManageRawDataCommand extends CommandNode { - - private final Locale locale; - private final ConnectionSystem connectionSystem; - - @Inject - public ManageRawDataCommand(Locale locale, ConnectionSystem connectionSystem) { - super("raw", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - this.connectionSystem = connectionSystem; - - setArguments(""); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_RAW_DATA)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_RAW_DATA)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - String playerName = MiscUtils.getPlayerName(args, sender, Permissions.MANAGE); - - sender.sendMessage(locale.getString(CommandLang.HEADER_INSPECT, playerName)); - // Link - String url = connectionSystem.getMainAddress() + "/player/" + playerName + "/raw"; - String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); - boolean console = !CommandUtils.isPlayer(sender); - if (console) { - sender.sendMessage(linkPrefix + url); - } else { - sender.sendMessage(linkPrefix); - sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); - } - - sender.sendMessage(">"); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java deleted file mode 100644 index fcc9efb76..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.PlayerFetchQueries; -import com.djrapitops.plan.db.access.transactions.commands.RemovePlayerTransaction; -import com.djrapitops.plan.query.QueryServiceImplementation; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plan.utilities.uuid.UUIDUtility; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; -import java.util.UUID; -import java.util.concurrent.ExecutionException; - -/** - * This manage subcommand is used to remove a single player's data from the - * dbSystem. - * - * @author Rsl1122 - */ -@Singleton -public class ManageRemoveCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final QueryServiceImplementation queryService; - private final UUIDUtility uuidUtility; - private final ErrorHandler errorHandler; - - @Inject - public ManageRemoveCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - QueryServiceImplementation queryService, - UUIDUtility uuidUtility, - ErrorHandler errorHandler - ) { - super("remove|delete", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.queryService = queryService; - this.uuidUtility = uuidUtility; - this.errorHandler = errorHandler; - - setArguments("", "[-a]"); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_REMOVE)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_REMOVE)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - String playerName = MiscUtils.getPlayerName(args, sender, Permissions.MANAGE); - - if (playerName == null) { - sender.sendMessage(locale.getString(CommandLang.FAIL_NO_PERMISSION)); - return; - } - - runRemoveTask(playerName, sender, args); - } - - private void runRemoveTask(String playerName, Sender sender, String[] args) { - processing.submitCritical(() -> { - try { - UUID playerUUID = uuidUtility.getUUIDOf(playerName); - - if (playerUUID == null) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_VALID)); - return; - } - - Database db = dbSystem.getDatabase(); - if (!db.query(PlayerFetchQueries.isPlayerRegistered(playerUUID))) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_KNOWN)); - return; - } - - if (!Verify.contains("-a", args)) { - sender.sendMessage( - locale.getString(ManageLang.CONFIRMATION, - locale.getString(ManageLang.CONFIRM_REMOVAL, db.getType().getName()) - ) - ); - return; - } - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - queryService.playerRemoved(playerUUID); - db.executeTransaction(new RemovePlayerTransaction(playerUUID)) - .get(); // Wait for completion - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (DBOpException | ExecutionException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java deleted file mode 100644 index c23b7f581..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.SQLiteDB; -import com.djrapitops.plan.db.access.transactions.BackupCopyTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import java.io.File; -import java.util.Arrays; - -/** - * This manage SubCommand is used to restore a backup.db file in the - * /plugins/Plan folder. - * - * @author Rsl1122 - */ -public class ManageRestoreCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - private final SQLiteDB.Factory sqliteFactory; - private final PlanFiles files; - - @Inject - public ManageRestoreCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - SQLiteDB.Factory sqliteFactory, - PlanFiles files, - ErrorHandler errorHandler - ) { - super("restore", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.sqliteFactory = sqliteFactory; - this.files = files; - this.errorHandler = errorHandler; - - setArguments("", "", "[-a]"); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_RESTORE)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_RESTORE)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 2, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 2, Arrays.toString(this.getArguments())))); - - String backupDbName = args[0]; - - String dbName = args[1].toLowerCase(); - boolean isCorrectDB = DBType.exists(dbName); - Verify.isTrue(isCorrectDB, - () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_INCORRECT_DB, dbName))); - - try { - Database database = dbSystem.getActiveDatabaseByName(dbName); - - Verify.isFalse(backupDbName.contains("database") && database instanceof SQLiteDB, - () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_SAME_DB))); - database.init(); - - if (!Verify.contains("-a", args)) { - sender.sendMessage(locale.getString(ManageLang.CONFIRMATION, locale.getString(ManageLang.CONFIRM_OVERWRITE, database.getType().getName()))); - return; - } - - runRestoreTask(backupDbName, sender, database); - } catch (Exception e) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - } - - private void runRestoreTask(String backupDbName, Sender sender, Database database) { - processing.submitCritical(() -> { - try { - boolean containsDBFileExtension = backupDbName.endsWith(".db"); - File backupDBFile = files.getFileFromPluginFolder(backupDbName + (containsDBFileExtension ? "" : ".db")); - - if (!backupDBFile.exists()) { - sender.sendMessage(locale.getString(ManageLang.FAIL_FILE_NOT_FOUND, backupDBFile.getAbsolutePath())); - return; - } - - SQLiteDB backupDB = sqliteFactory.usingFile(backupDBFile); - backupDB.init(); - - Database.State dbState = database.getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.WARN_DATABASE_NOT_OPEN, dbState.name())); - } - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - - database.executeTransaction(new BackupCopyTransaction(backupDB, database)).get(); - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java deleted file mode 100644 index c16d66990..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.api.exceptions.connection.*; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; - -/** - * This manage SubCommand is used to request settings from Bungee so that connection can be established. - * - * @author Rsl1122 - */ -@Singleton -public class ManageSetupCommand extends CommandNode { - - private final Locale locale; - private final PlanConfig config; - private final Processing processing; - private final InfoSystem infoSystem; - private final WebServer webServer; - private final ErrorHandler errorHandler; - - @Inject - public ManageSetupCommand( - Locale locale, - PlanConfig config, - Processing processing, - InfoSystem infoSystem, - WebServer webServer, - ErrorHandler errorHandler - ) { - super("setup", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - this.config = config; - this.processing = processing; - this.infoSystem = infoSystem; - this.webServer = webServer; - this.errorHandler = errorHandler; - - setArguments(""); - setShortHelp(locale.getString(CmdHelpLang.MANAGE_SETUP)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_SETUP)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - if (!webServer.isEnabled()) { - sender.sendMessage(locale.getString(CommandLang.CONNECT_WEBSERVER_NOT_ENABLED)); - return; - } - String address = args[0].toLowerCase(); - if (!address.startsWith("http") || address.endsWith("://")) { - sender.sendMessage(locale.getString(CommandLang.CONNECT_URL_MISTAKE)); - return; - } - if (address.endsWith("/")) { - address = address.substring(0, address.length() - 1); - } - - requestSetup(sender, address); - } - - private void requestSetup(Sender sender, String address) { - processing.submitNonCritical(() -> { - try { - config.set(PluginSettings.BUNGEE_COPY_CONFIG, true); - - infoSystem.requestSetUp(address); - - sender.sendMessage(locale.getString(CommandLang.CONNECT_SUCCESS)); - } catch (ForbiddenException e) { - sender.sendMessage(locale.getString(CommandLang.CONNECT_FORBIDDEN)); - } catch (BadRequestException e) { - sender.sendMessage(locale.getString(CommandLang.CONNECT_BAD_REQUEST)); - } catch (UnauthorizedServerException e) { - sender.sendMessage(locale.getString(CommandLang.CONNECT_UNAUTHORIZED)); - } catch (ConnectionFailException e) { - sender.sendMessage(locale.getString(CommandLang.CONNECT_FAIL, e.getMessage())); - } catch (InternalErrorException e) { - sender.sendMessage(locale.getString(CommandLang.CONNECT_INTERNAL_ERROR, e.getMessage())); - } catch (GatewayException e) { - sender.sendMessage(locale.getString(CommandLang.CONNECT_GATEWAY)); - } catch (WebException e) { - errorHandler.log(L.WARN, this.getClass(), e); - sender.sendMessage(locale.getString(CommandLang.CONNECT_FAIL, e.toString())); - } - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageUninstalledCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageUninstalledCommand.java deleted file mode 100644 index ce23ecf31..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageUninstalledCommand.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.manage; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.transactions.commands.SetServerAsUninstalledTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Optional; -import java.util.UUID; - -/** - * This SubCommand is used to set a server as uninstalled on Plan. - * - * @author Rsl1122 - */ -@Singleton -public class ManageUninstalledCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - private final ServerInfo serverInfo; - - @Inject - public ManageUninstalledCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - ServerInfo serverInfo, - ErrorHandler errorHandler - ) { - super("uninstalled", Permissions.MANAGE.getPermission(), CommandType.ALL_WITH_ARGS); - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.errorHandler = errorHandler; - - setShortHelp(locale.getString(CmdHelpLang.MANAGE_UNINSTALLED)); - setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_UNINSTALLED)); - setArguments("[server/id]"); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - processing.submitNonCritical(() -> { - try { - Optional serverOptional = getServer(args); - if (!serverOptional.isPresent()) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, locale.getString(ManageLang.NO_SERVER))); - return; - } - Server server = serverOptional.get(); - UUID serverUUID = server.getUuid(); - if (serverInfo.getServerUUID().equals(serverUUID)) { - sender.sendMessage(locale.getString(ManageLang.UNINSTALLING_SAME_SERVER)); - return; - } - - dbSystem.getDatabase().executeTransaction(new SetServerAsUninstalledTransaction(serverUUID)); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (DBOpException e) { - sender.sendMessage("§cError occurred: " + e.toString()); - errorHandler.log(L.ERROR, this.getClass(), e); - } - }); - } - - private Optional getServer(String[] args) { - if (args.length >= 1) { - String serverIdentifier = getGivenIdentifier(args); - return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverIdentifier)) - .filter(Server::isNotProxy); - } - return Optional.empty(); - } - - private String getGivenIdentifier(String[] args) { - StringBuilder idBuilder = new StringBuilder(args[0]); - if (args.length > 1) { - for (int i = 1; i < args.length; i++) { - idBuilder.append(" ").append(args[i]); - } - } - return idBuilder.toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java deleted file mode 100644 index 87a0f5e76..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.webuser; - -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.WebUserQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; -import java.util.Optional; - -/** - * Subcommand for checking WebUser permission level. - * - * @author Rsl1122 - */ -@Singleton -public class WebCheckCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public WebCheckCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - super("check", Permissions.MANAGE_WEB.getPerm(), CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - - setShortHelp(locale.getString(CmdHelpLang.WEB_CHECK)); - setArguments(""); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - String user = args[0]; - - processing.submitNonCritical(() -> { - try { - Database db = dbSystem.getDatabase(); - Optional found = db.query(WebUserQueries.fetchWebUser(user)); - if (!found.isPresent()) { - sender.sendMessage(locale.getString(CommandLang.FAIL_WEB_USER_NOT_EXISTS)); - return; - } - WebUser info = found.get(); - sender.sendMessage(locale.getString(CommandLang.WEB_USER_LIST, info.getName(), info.getPermLevel())); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - }); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java deleted file mode 100644 index 119ad4c8b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.webuser; - -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.WebUserQueries; -import com.djrapitops.plan.db.access.transactions.commands.RemoveWebUserTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Arrays; -import java.util.Optional; - -/** - * Subcommand for deleting a WebUser. - * - * @author Rsl1122 - */ -@Singleton -public class WebDeleteCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public WebDeleteCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - super("delete|remove", Permissions.MANAGE_WEB.getPerm(), CommandType.PLAYER_OR_ARGS); - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - - setShortHelp(locale.getString(CmdHelpLang.WEB_DELETE)); - setArguments(""); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - Verify.isTrue(args.length >= 1, - () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - - String user = args[0]; - - processing.submitNonCritical(() -> { - try { - Database db = dbSystem.getDatabase(); - Optional found = db.query(WebUserQueries.fetchWebUser(user)); - if (!found.isPresent()) { - sender.sendMessage("§c[Plan] User Doesn't exist."); - return; - } - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - db.executeTransaction(new RemoveWebUserTransaction(user)) - .get(); // Wait for completion - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - }); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java deleted file mode 100644 index 2d95007ac..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.webuser; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; - -import javax.inject.Inject; - -/** - * Subcommand for info about permission levels. - * - * @author Rsl1122 - */ -public class WebLevelCommand extends CommandNode { - - private final Locale locale; - - @Inject - public WebLevelCommand(Locale locale) { - super("level", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE); - - this.locale = locale; - - setShortHelp(locale.getString(CmdHelpLang.WEB_LEVEL)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - sender.sendMessage(locale.getArray(CommandLang.WEB_PERMISSION_LEVELS)); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java deleted file mode 100644 index 861a5fb5c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.command.commands.webuser; - -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.WebUserQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.Sender; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.List; - -/** - * Subcommand for checking WebUser list. - * - * @author Rsl1122 - */ -@Singleton -public class WebListUsersCommand extends CommandNode { - - private final Locale locale; - private final Processing processing; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public WebListUsersCommand( - Locale locale, - Processing processing, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - super("list", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE); - - this.locale = locale; - this.processing = processing; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - - setShortHelp(locale.getString(CmdHelpLang.WEB_LIST)); - } - - @Override - public void onCommand(Sender sender, String commandLabel, String[] args) { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); - return; - } - - processing.submitNonCritical(() -> { - try { - List users = dbSystem.getDatabase().query(WebUserQueries.fetchAllPlanWebUsers()); - sender.sendMessage(locale.getString(CommandLang.HEADER_WEB_USERS, users.size())); - for (WebUser user : users) { - sender.sendMessage(locale.getString(CommandLang.WEB_USER_LIST, user.getName(), user.getPermLevel())); - } - sender.sendMessage(">"); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } - }); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/WebUser.java b/Plan/common/src/main/java/com/djrapitops/plan/data/WebUser.java deleted file mode 100644 index de70c4bae..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/WebUser.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data; - -import java.util.Objects; - -/** - * Object containing webserver security user information. - * - * @author Rsl1122 - */ -public class WebUser { - - private final String user; - private final String saltedPassHash; - private final int permLevel; - - public WebUser(String user, String saltedPassHash, int permLevel) { - this.user = user; - this.saltedPassHash = saltedPassHash; - this.permLevel = permLevel; - } - - public String getName() { - return user; - } - - public String getSaltedPassHash() { - return saltedPassHash; - } - - public int getPermLevel() { - return permLevel; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - WebUser webUser = (WebUser) o; - return permLevel == webUser.permLevel && - Objects.equals(user, webUser.user) && - Objects.equals(saltedPassHash, webUser.saltedPassHash); - } - - @Override - public int hashCode() { - return Objects.hash(user, saltedPassHash, permLevel); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/BaseUser.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/BaseUser.java deleted file mode 100644 index b83985cc3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/BaseUser.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.container; - -import com.djrapitops.plugin.utilities.Verify; - -import java.util.Objects; -import java.util.UUID; - -/** - * Represents user information stored in plan_users. - *

- * Only one per player exists unlike {@link UserInfo} which is available per server. - * - * @author Rsl1122 - */ -public class BaseUser { - - private final UUID uuid; - private final String name; - private final long registered; - private final int timesKicked; - - public BaseUser(UUID uuid, String name, long registered, int timesKicked) { - Verify.nullCheck(uuid, () -> new IllegalArgumentException("'uuid' can not be null")); - Verify.nullCheck(name, () -> new IllegalArgumentException("'name' can not be null")); - - this.uuid = uuid; - this.name = name; - this.registered = registered; - this.timesKicked = timesKicked; - } - - public UUID getUuid() { - return uuid; - } - - public String getName() { - return name; - } - - public long getRegistered() { - return registered; - } - - public int getTimesKicked() { - return timesKicked; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof BaseUser)) return false; - BaseUser baseUser = (BaseUser) o; - return uuid.equals(baseUser.uuid) && name.equals(baseUser.name); - } - - @Override - public int hashCode() { - return Objects.hash(uuid, name); - } - - @Override - public String toString() { - return "BaseUser{" + - uuid + - ", '" + name + '\'' + - ", +" + registered + - ", kick:" + timesKicked + - '}'; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java deleted file mode 100644 index f5ab5b430..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.container; - -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.data.store.objects.DateMap; -import com.google.common.base.Objects; - -import java.io.Serializable; -import java.net.Inet6Address; -import java.net.InetAddress; - -/** - * Data class that contains information about IP and Geolocation. - * - * @author Rsl1122 - */ -public class GeoInfo implements DateHolder, Serializable { - - private final String ip; - private final String geolocation; - private final long date; - - public GeoInfo(InetAddress address, String geolocation, long lastUsed) { - this(formatIP(address), geolocation, lastUsed); - } - - public GeoInfo(String ip, String geolocation, long date) { - this.ip = ip; - this.geolocation = geolocation; - this.date = date; - } - - public static DateMap intoDateMap(Iterable geoInfo) { - DateMap map = new DateMap<>(); - for (GeoInfo info : geoInfo) { - map.put(info.date, info); - } - return map; - } - - static String formatIP(InetAddress address) { - String ip = address.getHostAddress(); - if ("localhost".equals(ip)) { - return ip; - } - if (address instanceof Inet6Address) { - StringBuilder b = new StringBuilder(); - int i = 0; - for (String part : ip.split(":")) { - if (i >= 3) { - break; - } - - b.append(part).append(':'); - - i++; - } - - return b.append("xx..").toString(); - } else { - StringBuilder b = new StringBuilder(); - int i = 0; - for (String part : ip.split("\\.")) { - if (i >= 2) { - break; - } - - b.append(part).append('.'); - - i++; - } - - return b.append("xx.xx").toString(); - } - } - - public String getIp() { - return ip; - } - - public String getGeolocation() { - return geolocation; - } - - @Override - public long getDate() { - return date; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GeoInfo geoInfo = (GeoInfo) o; - return Objects.equal(ip, geoInfo.ip) && - Objects.equal(geolocation, geoInfo.geolocation); - } - - @Override - public int hashCode() { - return Objects.hashCode(ip, geolocation); - } - - @Override - public String toString() { - return "GeoInfo{" + - "ip='" + ip + '\'' + - ", geolocation='" + geolocation + '\'' + - ", date=" + date + - '}'; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/Ping.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/Ping.java deleted file mode 100644 index c0f897df8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/Ping.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.container; - -import com.djrapitops.plan.data.store.objects.DateObj; - -import java.util.UUID; - -public class Ping extends DateObj { - - private final UUID serverUUID; - private final double average; - private final int min; - private final int max; - - public Ping(long date, UUID serverUUID, int min, int max, double average) { - super(date, average); - this.serverUUID = serverUUID; - this.average = average; - this.min = min; - this.max = max; - } - - public UUID getServerUUID() { - return serverUUID; - } - - public double getAverage() { - return average; - } - - public int getMin() { - return min; - } - - public int getMax() { - return max; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/PlayerDeath.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/PlayerDeath.java deleted file mode 100644 index 98b048dfc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/PlayerDeath.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.container; - -import com.djrapitops.plan.data.store.objects.DateHolder; - -import java.util.UUID; - -public class PlayerDeath implements DateHolder { - - private final UUID killer; - private final String killerName; - private final long date; - private final String weapon; - - public PlayerDeath(UUID killer, String killerName, String weapon, long date) { - this.killer = killer; - this.killerName = killerName; - this.date = date; - this.weapon = weapon; - } - - public UUID getKiller() { - return killer; - } - - public String getKillerName() { - return killerName; - } - - @Override - public long getDate() { - return date; - } - - public String getWeapon() { - return weapon; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/PlayerKill.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/PlayerKill.java deleted file mode 100644 index 8c8fa9f8d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/PlayerKill.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.container; - -import com.djrapitops.plan.data.store.objects.DateHolder; - -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; - -/** - * This class is used to store data about a player kill inside the UserInfo - * object. - * - * @author Rsl1122 - */ -public class PlayerKill implements DateHolder { - - private final UUID victim; - private final String weapon; - private final long date; - - private String victimName; - - /** - * Creates a PlayerKill object with given parameters. - * - * @param victim UUID of the victim. - * @param weapon Weapon used. - * @param date Epoch millisecond at which the kill occurred. - */ - public PlayerKill(UUID victim, String weapon, long date) { - this.victim = victim; - this.weapon = weapon; - this.date = date; - } - - public PlayerKill(UUID victim, String weapon, long date, String victimName) { - this.victim = victim; - this.date = date; - this.weapon = weapon; - this.victimName = victimName; - } - - /** - * Get the victim's UUID. - * - * @return UUID of the victim. - */ - public UUID getVictim() { - return victim; - } - - public Optional getVictimName() { - return Optional.ofNullable(victimName); - } - - @Override - public long getDate() { - return date; - } - - /** - * Get the Weapon used as string. - * - * @return For example DIAMOND_SWORD - */ - public String getWeapon() { - return weapon; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PlayerKill that = (PlayerKill) o; - return date == that.date && - Objects.equals(victim, that.victim) && - Objects.equals(weapon, that.weapon); - } - - @Override - public int hashCode() { - return Objects.hash(victim, date, weapon); - } - - @Override - public String toString() { - return "PlayerKill{" + - "victim=" + victim + ", " + - "date=" + date + ", " + - "weapon='" + weapon + "'}"; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java deleted file mode 100644 index db1ac4fed..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.container; - -import com.djrapitops.plan.data.store.containers.DynamicDataContainer; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.data.time.WorldTimes; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; - -/** - * DataContainer for information about a player's play session. - * - * @author Rsl1122 - * @see SessionKeys for Key objects. - */ -public class Session extends DynamicDataContainer implements DateHolder { - - private long sessionStart; - private WorldTimes worldTimes; - private List playerKills; - - private int mobKills; - private int deaths; - private long afkTime; - - /** - * Creates a new session. - * - * @param uuid UUID of the Player. - * @param serverUUID UUID of the server. - * @param sessionStart Epoch ms the session started. - * @param world Starting world. - * @param gm Starting GameMode. - */ - public Session(UUID uuid, UUID serverUUID, long sessionStart, String world, String gm) { - this.sessionStart = sessionStart; - worldTimes = new WorldTimes(world, gm, sessionStart); - playerKills = new ArrayList<>(); - - mobKills = 0; - deaths = 0; - afkTime = 0; - - putRawData(SessionKeys.UUID, uuid); - putRawData(SessionKeys.SERVER_UUID, serverUUID); - putSupplier(SessionKeys.START, this::getSessionStart); - putSupplier(SessionKeys.WORLD_TIMES, this::getWorldTimes); - putSupplier(SessionKeys.PLAYER_KILLS, this::getPlayerKills); - putRawData(SessionKeys.PLAYER_DEATHS, new ArrayList<>()); - putSupplier(SessionKeys.MOB_KILL_COUNT, this::getMobKills); - putSupplier(SessionKeys.DEATH_COUNT, this::getDeaths); - putSupplier(SessionKeys.AFK_TIME, this::getAfkTime); - - putSupplier(SessionKeys.PLAYER_KILL_COUNT, getUnsafe(SessionKeys.PLAYER_KILLS)::size); - putSupplier(SessionKeys.LENGTH, () -> - getValue(SessionKeys.END).orElse(System.currentTimeMillis()) - getUnsafe(SessionKeys.START)); - putSupplier(SessionKeys.ACTIVE_TIME, () -> getUnsafe(SessionKeys.LENGTH) - getUnsafe(SessionKeys.AFK_TIME)); - - putRawData(SessionKeys.LONGEST_WORLD_PLAYED, "Key is Deprecated, use WorldAliasSettings#getLongestWorldPlayed(Session) instead."); - } - - /** - * Recreates a Session found in the database. - *

- * WorldTimes and Player kills need to be set separately. - * - * @param id ID in the database (Used for fetching world times and player kills. - * @param uuid UUID of the Player. - * @param serverUUID UUID of the Server. - * @param sessionStart Epoch ms the session started. - * @param sessionEnd Epoch ms the session ended. - * @param mobKills Mobs killed during the session. - * @param deaths Death count during the session. - * @param afkTime Time spent AFK during the session. - */ - public Session(int id, UUID uuid, UUID serverUUID, long sessionStart, long sessionEnd, int mobKills, int deaths, long afkTime) { - this.sessionStart = sessionStart; - worldTimes = new WorldTimes(); - playerKills = new ArrayList<>(); - - this.mobKills = mobKills; - this.deaths = deaths; - this.afkTime = afkTime; - - putRawData(SessionKeys.DB_ID, id); - putRawData(SessionKeys.UUID, uuid); - putRawData(SessionKeys.SERVER_UUID, serverUUID); - putSupplier(SessionKeys.START, this::getSessionStart); - putRawData(SessionKeys.END, sessionEnd); - putSupplier(SessionKeys.WORLD_TIMES, this::getWorldTimes); - putSupplier(SessionKeys.PLAYER_KILLS, this::getPlayerKills); - putRawData(SessionKeys.PLAYER_DEATHS, new ArrayList<>()); - putSupplier(SessionKeys.MOB_KILL_COUNT, this::getMobKills); - putSupplier(SessionKeys.DEATH_COUNT, this::getDeaths); - putSupplier(SessionKeys.AFK_TIME, this::getAfkTime); - - putSupplier(SessionKeys.PLAYER_KILL_COUNT, () -> getUnsafe(SessionKeys.PLAYER_KILLS).size()); - putSupplier(SessionKeys.LENGTH, () -> - getValue(SessionKeys.END).orElse(System.currentTimeMillis()) - getUnsafe(SessionKeys.START)); - putSupplier(SessionKeys.ACTIVE_TIME, () -> getUnsafe(SessionKeys.LENGTH) - getUnsafe(SessionKeys.AFK_TIME)); - - putRawData(SessionKeys.LONGEST_WORLD_PLAYED, "Key is Deprecated, use WorldAliasSettings#getLongestWorldPlayed(Session) instead."); - } - - /** - * Ends the session with given end point. - *

- * Updates world times to the latest value. - * - * @param endOfSession Epoch millisecond the session ended. - */ - public void endSession(long endOfSession) { - putRawData(SessionKeys.END, endOfSession); - worldTimes.updateState(endOfSession); - } - - /** - * Updates WorldTimes state. - * - * @param world World Name the player has moved to - * @param gm GameMode the player is in. - * @param time Epoch ms of the event. - */ - public void changeState(String world, String gm, long time) { - worldTimes.updateState(world, gm, time); - } - - public void playerKilled(PlayerKill kill) { - playerKills.add(kill); - } - - public void mobKilled() { - mobKills++; - } - - public void died() { - deaths++; - } - - /** - * Get the length of the session in milliseconds. - * - * @return Long in ms. - */ - public long getLength() { - return getValue(SessionKeys.LENGTH).orElse(0L); - } - - @Override - public long getDate() { - return getUnsafe(SessionKeys.START); - } - - public void setWorldTimes(WorldTimes worldTimes) { - this.worldTimes = worldTimes; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Session session = (Session) o; - return getUnsafe(SessionKeys.START).equals(session.getUnsafe(SessionKeys.START)) && - getValue(SessionKeys.END).orElse(-1L).equals(session.getValue(SessionKeys.END).orElse(-1L)) && - mobKills == session.mobKills && - deaths == session.deaths && - Objects.equals(playerKills, session.playerKills) && - Objects.equals(worldTimes, session.worldTimes); - } - - public boolean isFetchedFromDB() { - return supports(SessionKeys.DB_ID); - } - - public void addAFKTime(long timeAFK) { - afkTime += timeAFK; - } - - public void setSessionID(int sessionID) { - putRawData(SessionKeys.DB_ID, sessionID); - } - - public List getPlayerKills() { - return playerKills; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), mobKills, deaths, afkTime); - } - - private long getSessionStart() { - return sessionStart; - } - - private WorldTimes getWorldTimes() { - return worldTimes; - } - - public void setPlayerKills(List playerKills) { - this.playerKills = playerKills; - } - - private int getMobKills() { - return mobKills; - } - - private int getDeaths() { - return deaths; - } - - private long getAfkTime() { - return afkTime; - } - - @Override - public String toString() { - return "Session{" + - "sessionStart=" + getUnsafe(SessionKeys.START) + - ", sessionEnd=" + getUnsafe(SessionKeys.END) + - ", worldTimes=" + worldTimes + - ", playerKills=" + playerKills + - ", mobKills=" + mobKills + - ", deaths=" + deaths + - ", afkTime=" + afkTime + - '}'; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/TPS.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/TPS.java deleted file mode 100644 index b61300648..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/TPS.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.container; - -import com.djrapitops.plan.data.store.objects.DateHolder; - -import java.util.Objects; - -/** - * Class containing single datapoint of TPS / Players online / CPU Usage / Used Memory / Entity Count / Chunks loaded. - * - * @author Rsl1122 - */ -public class TPS implements DateHolder { - - private final long date; - private final double ticksPerSecond; - private final int players; - private final double cpuUsage; - private final long usedMemory; - private final int entityCount; - private final int chunksLoaded; - private final long freeDiskSpace; - - /** - * Constructor. - * - * @param date time of the TPS calculation. - * @param ticksPerSecond average ticksPerSecond for the last minute. - * @param players players for the minute. - * @param cpuUsage CPU usage for the minute - * @param usedMemory used memory (megabytes) at the time of fetching - * @param entityCount amount of entities at the time of fetching - * @param chunksLoaded amount of chunks loaded at the time of fetching - * @param freeDiskSpace free megabytes in the partition the server is running in. - */ - public TPS( - long date, - double ticksPerSecond, - int players, - double cpuUsage, - long usedMemory, - int entityCount, - int chunksLoaded, - long freeDiskSpace - ) { - this.date = date; - this.ticksPerSecond = ticksPerSecond; - this.players = players; - this.cpuUsage = cpuUsage; - this.usedMemory = usedMemory; - this.entityCount = entityCount; - this.chunksLoaded = chunksLoaded; - this.freeDiskSpace = freeDiskSpace; - } - - @Override - public long getDate() { - return date; - } - - /** - * Get the average ticksPerSecond for the minute. - * - * @return 0-20 double - */ - public double getTicksPerSecond() { - return ticksPerSecond; - } - - /** - * Get the player for the time, when the data was fetched. - * - * @return Players online. - */ - public int getPlayers() { - return players; - } - - /** - * Get the average CPU Usage for the minute - * - * @return 0-100 double - */ - public double getCPUUsage() { - return cpuUsage; - } - - /** - * Get the used memory for the time, when the data was fetched. - * - * @return Used Memory in Megabyte - */ - public long getUsedMemory() { - return usedMemory; - } - - /** - * Get the amount of entities for the time, when the data was fetched - * - * @return Amount of entities - */ - public int getEntityCount() { - return entityCount; - } - - /** - * Get the amount of chunks loaded for the time, when the data was fetched - * - * @return Amount of chunks loaded - */ - public int getChunksLoaded() { - return chunksLoaded; - } - - /** - * Get free megabytes of disk space on the server disk. - * - * @return Amount of free megabytes available on disk. - */ - public long getFreeDiskSpace() { - return freeDiskSpace; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TPS tps = (TPS) o; - return date == tps.date && - Double.compare(tps.ticksPerSecond, ticksPerSecond) == 0 && - players == tps.players && - Double.compare(tps.cpuUsage, cpuUsage) == 0 && - usedMemory == tps.usedMemory && - entityCount == tps.entityCount && - chunksLoaded == tps.chunksLoaded && - freeDiskSpace == tps.freeDiskSpace; - } - - @Override - public int hashCode() { - return Objects.hash(date, ticksPerSecond, players, cpuUsage, usedMemory, entityCount, chunksLoaded, freeDiskSpace); - } - - @Override - public String toString() { - return "TPS{" + - "date=" + date + ", " + - "ticksPerSecond=" + ticksPerSecond + ", " + - "players=" + players + ", " + - "cpuUsage=" + cpuUsage + ", " + - "usedMemory=" + usedMemory + ", " + - "entityCount=" + entityCount + ", " + - "chunksLoaded=" + chunksLoaded + ", " + - "freeDiskSpace=" + freeDiskSpace + '}'; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/UserInfo.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/UserInfo.java deleted file mode 100644 index 3dca56255..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/UserInfo.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.container; - -import java.util.Objects; -import java.util.UUID; - -/** - * Represents user information stored in plan_user_info. - *

- * Unlike {@link BaseUser} one instance is stored per server for a single player. - * Proxy servers are an exception, and UserInfo is not stored for them. - * - * @author Rsl1122 - */ -public class UserInfo { - - private final UUID playerUUID; - private final UUID serverUUID; - private long registered; - private boolean banned; - private boolean opped; - - public UserInfo(UUID playerUUID, UUID serverUUID, long registered, boolean opped, boolean banned) { - this.playerUUID = playerUUID; - this.serverUUID = serverUUID; - this.registered = registered; - this.opped = opped; - this.banned = banned; - } - - public UUID getPlayerUuid() { - return playerUUID; - } - - public UUID getServerUUID() { - return serverUUID; - } - - public long getRegistered() { - return registered; - } - - public boolean isBanned() { - return banned; - } - - public boolean isOperator() { - return opped; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof UserInfo)) return false; - UserInfo userInfo = (UserInfo) o; - return registered == userInfo.registered && - banned == userInfo.banned && - opped == userInfo.opped && - playerUUID.equals(userInfo.playerUUID) && - serverUUID.equals(userInfo.serverUUID); - } - - @Override - public int hashCode() { - return Objects.hash(playerUUID, serverUUID, registered, banned, opped); - } - - @Override - public String toString() { - return "UserInfo{" + - "playerUUID=" + playerUUID + - ", serverUUID=" + serverUUID + - ", registered=" + registered + - ", banned=" + banned + - ", opped=" + opped + - '}'; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/builders/TPSBuilder.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/builders/TPSBuilder.java deleted file mode 100644 index a91dab8d4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/builders/TPSBuilder.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.container.builders; - -import com.djrapitops.plan.data.container.TPS; - -/** - * Builder for TPS to make it easier to manage. - * - * @author Rsl1122 - */ -public class TPSBuilder { - - protected long date = 0; - protected double ticksPerSecond = -1; - protected int players = -1; - protected double cpuUsage = -1; - protected long usedMemory = -1; - protected int entityCount = -1; - protected int chunksLoaded = -1; - protected long freeDiskSpace = -1; - - /** - * Hides constructor. - */ - private TPSBuilder() { - } - - public static TPSBuilder get() { - return new TPSBuilder(); - } - - public TPS toTPS() { - return new TPS(date, ticksPerSecond, players, cpuUsage, usedMemory, entityCount, chunksLoaded, freeDiskSpace); - } - - public TPSBuilder date(long date) { - this.date = date; - return this; - } - - public TPSBuilder tps(double tps) { - ticksPerSecond = tps; - return this; - } - - public TPSBuilder playersOnline(int online) { - players = online; - return this; - } - - public TPSBuilder usedCPU(double cpu) { - cpuUsage = cpu; - return this; - } - - public TPSBuilder usedMemory(long ram) { - usedMemory = ram; - return this; - } - - public TPSBuilder entities(int count) { - entityCount = count; - return this; - } - - public TPSBuilder chunksLoaded(int chunksLoaded) { - this.chunksLoaded = chunksLoaded; - return this; - } - - public TPSBuilder freeDiskSpace(long freeDiskSpace) { - this.freeDiskSpace = freeDiskSpace; - return this; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/element/AnalysisContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/element/AnalysisContainer.java deleted file mode 100644 index 00bbbbc5c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/element/AnalysisContainer.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.element; - -import java.io.Serializable; -import java.util.Map; -import java.util.TreeMap; -import java.util.UUID; - -/** - * Container used to parse data for Server page. - *

- * Similar to InspectContainer, but can contain data for each player for a bigger Player data table. - *

- * Can contain values: addValue("Total Examples", 1) parses into ("Total Examples: 1") - * Html: addHtml(key, "{@code }") parses into ("{@code }") - * Tables: addTable(key, TableContainer) parses into ("{@code ...)} parses a new column to Plugin data player table. - *

- * Has methods for adding icons to Strings: - * getWithIcon("text", "cube") parses into {@code " text"} - * getWithColoredIcon("text", "cube", "light-green") parses into {@code " text"} - * - * @author Rsl1122 - * @see TableContainer - * @see InspectContainer - * @deprecated PluginData API has been deprecated - see https://github.com/plan-player-analytics/Plan/wiki/APIv5---DataExtension-API for new API. - */ -@Deprecated -public final class AnalysisContainer extends InspectContainer { - - private Map> playerTableValues; - - public AnalysisContainer() { - playerTableValues = new TreeMap<>(); - } - - public Map> getPlayerTableValues() { - return playerTableValues; - } - - public void addPlayerTableValues(String columnName, Map values) { - playerTableValues.put(columnName, values); - } - - public boolean hasPlayerTableValues() { - return !playerTableValues.isEmpty(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/element/InspectContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/element/InspectContainer.java deleted file mode 100644 index 2414953a8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/element/InspectContainer.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.element; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -/** - * Container used to parse data for Inspect page. - *

- * Can contain values: addValue("Total Examples", 1) parses into ("Total Examples: 1") - * Html: addHtml(key, "{@code }") parses into ("{@code }") - * Tables: addTable(key, TableContainer) parses into ("{@code

... - * Has methods for adding icons to Strings: - * getWithIcon("text", "cube") parses into {@code " text"} - * getWithColoredIcon("text", "cube", "light-green") parses into {@code " text"} - * - * @author Rsl1122 - * @see TableContainer - * @deprecated PluginData API has been deprecated - see https://github.com/plan-player-analytics/Plan/wiki/APIv5---DataExtension-API for new API. - */ -@Deprecated -public class InspectContainer { - - protected List values; - protected TreeMap html; - protected TreeMap tables; - - public InspectContainer() { - values = new ArrayList<>(); - html = new TreeMap<>(); - tables = new TreeMap<>(); - } - - public final void addValue(String label, Serializable value) { - values.add(label + ": " + value.toString()); - } - - public final void addHtml(String key, String html) { - this.html.put(key, html); - } - - public final void addTable(String key, TableContainer table) { - tables.put(key, table); - } - - public final String parseHtml() { - StringBuilder parsed = new StringBuilder(); - - if (!values.isEmpty()) { - parsed.append("
"); - for (String value : values) { - parsed.append("

").append(value).append("

"); - } - parsed.append("
"); - } - - for (Map.Entry entry : this.html.entrySet()) { - parsed.append(entry.getValue()); - } - - for (Map.Entry entry : tables.entrySet()) { - parsed.append(entry.getValue().parseHtml()); - } - - return parsed.toString(); - } - - /** - * Check if InspectContainer has only values, and not HTML or Tables. - * - * @return true/false - */ - public final boolean hasOnlyValues() { - return html.isEmpty() && tables.isEmpty(); - } - - public boolean isEmpty() { - return values.isEmpty() && hasOnlyValues(); - } - - public final boolean hasValues() { - return !values.isEmpty(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/element/TableContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/element/TableContainer.java deleted file mode 100644 index 159b17e98..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/element/TableContainer.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.element; - -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plan.utilities.html.icon.Icon; -import com.djrapitops.plugin.utilities.ArrayUtil; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * Container used for parsing Html tables. - * - * @author Rsl1122 - * @deprecated PluginData API has been deprecated - see https://github.com/plan-player-analytics/Plan/wiki/APIv5---DataExtension-API for new API. - */ -@Deprecated -public class TableContainer { - - protected final String[] header; - protected final Formatter[] formatters; - private List values; - - private String jqueryDatatable; - - private String color; - - /** - * Constructor, call with super(...). - * - * @param header Required: example {@code new TableContainer("1st", "2nd"} parses into {@code
(); - } - - public TableContainer(boolean players, String... header) { - this( - ArrayUtil.merge(new String[]{Icon.called("user").build() + " Player"}, header) - ); - } - - public final void addRow(Serializable... values) { - this.values.add(values); - } - - public String parseHtml() { - return getTableHeader() + - parseHeader() + - parseBody() + - "
1st2nd
" + (jqueryDatatable != null ? "" : ""); - } - - public final String parseBody() { - if (values.isEmpty()) { - addRow("No Data"); - } - return Html.TABLE_BODY.parse(buildBody()); - - } - - private String buildBody() { - StringBuilder body = new StringBuilder(); - for (Serializable[] row : values) { - appendRow(body, row); - } - return body.toString(); - } - - private void appendRow(StringBuilder body, Serializable[] row) { - int maxIndex = row.length - 1; - body.append(""); - for (int i = 0; i < header.length; i++) { - try { - if (i > maxIndex) { - body.append("-"); - } else { - appendValue(body, row[i], formatters[i]); - } - body.append(""); - } catch (ClassCastException | ArrayIndexOutOfBoundsException e) { - throw new IllegalStateException("Invalid formatter given at index " + i + ": " + e.getMessage(), e); - } - } - body.append(""); - } - - private void appendValue(StringBuilder body, Serializable value, Formatter formatter) { - body.append("" : ">"); - if (formatter != null) { - body.append(formatter.apply(value)); - } else { - body.append(value != null ? value : '-'); - } - } - - public final void setColor(String color) { - this.color = color; - } - - public final String parseHeader() { - StringBuilder parsedHeader = new StringBuilder(""); - for (String title : header) { - parsedHeader.append("").append(title).append(""); - } - parsedHeader.append(""); - return parsedHeader.toString(); - } - - public final void setFormatter(int index, Formatter formatter) { - if (index < formatters.length) { - formatters[index] = formatter; - } - } - - /** - * Make use of jQuery Data-tables plugin. - *

- * Use this with custom tables. - *

- * If this is called, result of {@code parseHtml()} should be wrapped with {@code Html.PANEL.parse(Html.PANEL_BODY.parse(result))} - */ - public void useJqueryDataTables() { - this.jqueryDatatable = "player-plugin-table"; - } - - /** - * Make use of jQuery Data-tables plugin. - * - * @param sortType "player-table" or "player-plugin-table" - */ - public void useJqueryDataTables(String sortType) { - jqueryDatatable = sortType; - } - - private String getTableHeader() { - if (jqueryDatatable != null) { - return "

" + Html.TABLE_JQUERY.parse(jqueryDatatable); - } else { - return Html.TABLE_SCROLL.parse(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/BanData.java b/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/BanData.java deleted file mode 100644 index 772f9e3ba..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/BanData.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.plugin; - -import java.util.Collection; -import java.util.UUID; - -/** - * Interface for PluginData objects that affect Ban state of players. - * - * @author Rsl1122 - * @deprecated PluginData API has been deprecated - see https://github.com/plan-player-analytics/Plan/wiki/APIv5---DataExtension-API for new API. - */ -@Deprecated -public interface BanData { - - boolean isBanned(UUID uuid); - - /** - * Method that should return only banned players of the given UUIDs. - * - * @param uuids UUIDs to filter. - * @return UUIDs from the collection uuids that are banned. - */ - Collection filterBanned(Collection uuids); - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/ContainerSize.java b/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/ContainerSize.java deleted file mode 100644 index 09f89c386..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/ContainerSize.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.plugin; - -/** - * Enum class for PluginData to estimate the required width of the contained items. - * - * @author Rsl1122 - * @deprecated PluginData API has been deprecated - see https://github.com/plan-player-analytics/Plan/wiki/APIv5---DataExtension-API for new API. - */ -@Deprecated -public enum ContainerSize { - THIRD, - TWO_THIRDS, - WHOLE, - TAB -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/HookHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/HookHandler.java deleted file mode 100644 index 84427f893..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/HookHandler.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.plugin; - -import com.djrapitops.plan.data.element.InspectContainer; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.pluginbridge.plan.Bridge; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.*; - -/** - * Class responsible for hooking to other plugins and managing the %plugins% - * placeholder on Analysis and Inspect pages. - * - * @author Rsl1122 - */ -@Singleton -public class HookHandler implements SubSystem { - - private final List additionalDataSources; - - private final Bridge bridge; - private PluginsConfigSection configHandler; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - @Inject - public HookHandler( - Bridge bridge, - PluginsConfigSection configHandler, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.bridge = bridge; - this.configHandler = configHandler; - this.logger = logger; - this.errorHandler = errorHandler; - - additionalDataSources = new ArrayList<>(); - } - - @Override - public void enable() { - try { - bridge.hook(this); - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - logger.error("Plan Plugin Bridge not included in the plugin jar."); - } - } - - @Override - public void disable() { - // Nothing to disable - } - - /** - * Adds a new PluginData source to the list. - *

- * The plugin data will appear on Analysis and/or Inspect pages depending on - * how the extending object is set up. - *

- * Refer to documentation on GitHub for more information. - * - * @param dataSource an object extending the PluginData class. - */ - public void addPluginDataSource(PluginData dataSource) { - if (dataSource == null) { - return; - } - try { - if (!configHandler.hasSection(dataSource)) { - configHandler.createSection(dataSource); - } - if (configHandler.isEnabled(dataSource)) { - additionalDataSources.stream() - .filter(pluginData -> pluginData.getSourcePlugin().equals(dataSource.getSourcePlugin())) - .findAny() - .ifPresent(additionalDataSources::remove); - logger.debug("Registered a new datasource: " + dataSource.getSourcePlugin()); - additionalDataSources.add(dataSource); - } - } catch (Exception e) { - errorHandler.log(L.WARN, this.getClass(), e); - logger.error("Attempting to register PluginDataSource caused an exception."); - } - } - - /** - * Used to get all PluginData objects currently registered. - * - * @return List of PluginData objects. - */ - public List getAdditionalDataSources() { - return additionalDataSources; - } - - public Map getInspectContainersFor(UUID uuid) { - List plugins = getAdditionalDataSources(); - Map containers = new HashMap<>(); - for (PluginData pluginData : plugins) { - InspectContainer inspectContainer = new InspectContainer(); - try { - InspectContainer container = pluginData.getPlayerData(uuid, inspectContainer); - if (container != null && !container.isEmpty()) { - containers.put(pluginData, container); - } - } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) { - String pluginName = pluginData.getSourcePlugin(); - logger.error("PluginData caused exception: " + pluginName + - ", you can disable the integration under 'Plugins." + pluginName + ".Enabled'"); - errorHandler.log(L.WARN, pluginData.getClass(), e); - } - } - return containers; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/PluginData.java b/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/PluginData.java deleted file mode 100644 index b2cd15c91..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/PluginData.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.plugin; - -import com.djrapitops.plan.data.element.AnalysisContainer; -import com.djrapitops.plan.data.element.InspectContainer; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plan.utilities.html.icon.Color; -import com.djrapitops.plan.utilities.html.icon.Icon; -import com.google.common.base.Objects; - -import java.util.Collection; -import java.util.UUID; - -/** - * This is an abstract class that can be used to add data from a plugin to the - * "Plugins"-sections of Analysis and Inspect pages. - *

- * API-section of documentation has examples on the usage of this class and how - * to register objects extending this class. - * - * @author Rsl1122 - * @deprecated PluginData API has been deprecated - see https://github.com/plan-player-analytics/Plan/wiki/APIv5---DataExtension-API for new API. - */ -@Deprecated -public abstract class PluginData { - - private final ContainerSize size; - private final String sourcePlugin; - - private Icon pluginIcon; - - private String helpText; - - protected com.djrapitops.plan.data.store.containers.AnalysisContainer analysisData; - - public PluginData(ContainerSize size, String sourcePlugin) { - this.size = size; - this.sourcePlugin = sourcePlugin; - } - - public abstract InspectContainer getPlayerData(UUID uuid, InspectContainer fillThis) throws Exception; - - public abstract AnalysisContainer getServerData(Collection uuids, AnalysisContainer fillThis) throws Exception; - - protected final void setPluginIcon(Icon pluginIcon) { - this.pluginIcon = pluginIcon; - } - - /** - * @deprecated Use {@code setPluginIcon(Icon)} instead - */ - @Deprecated - protected final void setPluginIcon(String pluginIcon) { - this.pluginIcon = Icon.called(pluginIcon != null ? pluginIcon : "cube").build(); - } - - /** - * @deprecated Use {@code setPluginIcon(Icon)} instead - */ - @Deprecated - protected final void setIconColor(String iconColor) { - pluginIcon.setColor(Color.matchString(iconColor)); - } - - public final String getHelpText() { - return helpText; - } - - public final String parsePluginIcon() { - return (pluginIcon != null ? pluginIcon : Icon.called("cube").build()).toHtml(); - } - - public final ContainerSize getSize() { - return size; - } - - public final String getSourcePlugin() { - return sourcePlugin; - } - - protected final void setHelpText(String html) { - helpText = Html.HELP_BUBBLE.parse(sourcePlugin, html); - } - - @Override - public final boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PluginData that = (PluginData) o; - return size == that.size && - Objects.equal(sourcePlugin, that.sourcePlugin) && - Objects.equal(pluginIcon, that.pluginIcon); - } - - @Override - public final int hashCode() { - return Objects.hashCode(size, sourcePlugin, pluginIcon); - } - - /** - * @deprecated Use {@code getWithIcon(String, Icon)} instead - */ - @Deprecated - public final String getWithIcon(String text, String icon) { - return getWithIcon(text, Icon.called(icon).build()); - } - - /** - * @deprecated Use {@code getWithIcon(String, Icon)} instead - */ - @Deprecated - public final String getWithIcon(String text, String icon, String color) { - return getWithIcon(text, Icon.called(icon).of(Color.matchString(color)).build()); - } - - public final String getWithIcon(String text, Icon.Builder builder) { - return getWithIcon(text, builder.build()); - } - - public final String getWithIcon(String text, Icon icon) { - return icon.toHtml() + " " + text; - } - - public final void setAnalysisData(com.djrapitops.plan.data.store.containers.AnalysisContainer analysisData) { - this.analysisData = analysisData; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/PluginsConfigSection.java b/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/PluginsConfigSection.java deleted file mode 100644 index 9223fe375..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/plugin/PluginsConfigSection.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.plugin; - -import com.djrapitops.plan.system.settings.config.ConfigNode; -import com.djrapitops.plan.system.settings.config.PlanConfig; - -import java.io.IOException; - -/** - * Class responsible for generating and generating settings for PluginData - * objects to the config. - * - * @author Rsl1122 - */ -public class PluginsConfigSection { - - private final PlanConfig config; - - public PluginsConfigSection( - PlanConfig config - ) { - this.config = config; - } - - @Deprecated - public boolean hasSection(PluginData dataSource) { - return hasSection(dataSource.getSourcePlugin()); - } - - public boolean hasSection(String pluginName) { - ConfigNode section = getPluginsSection(); - return section.getNode(pluginName + ".Enabled").isPresent(); - } - - private ConfigNode getPluginsSection() { - return config.getNode("Plugins") - .orElse(config.addNode("Plugins")); - } - - @Deprecated - public void createSection(PluginData dataSource) throws IOException { - createSection(dataSource.getSourcePlugin()); - } - - public void createSection(String pluginName) throws IOException { - ConfigNode section = getPluginsSection(); - - section.set(pluginName + ".Enabled", true); - section.sort(); - section.save(); - } - - @Deprecated - public boolean isEnabled(PluginData dataSource) { - return isEnabled(dataSource.getSourcePlugin()); - } - - public boolean isEnabled(String pluginName) { - ConfigNode section = getPluginsSection(); - return section.getBoolean(pluginName + ".Enabled"); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java deleted file mode 100644 index 0b1e8e15c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store; - -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; - -/** - * Caching layer between Supplier and caller. - *

- * Refreshes the value if 30 seconds have passed since the last call. - * - * @author Rsl1122 - */ -public class CachingSupplier implements Supplier { - - private final Supplier original; - private T cachedValue; - private long cacheTime; - private long timeToLive; - - public CachingSupplier(Supplier original) { - this(original, TimeUnit.SECONDS.toMillis(30L)); - } - - public CachingSupplier(Supplier original, long timeToLive) { - this.original = original; - this.timeToLive = timeToLive; - - cacheTime = 0L; - } - - @Override - public T get() { - if (cachedValue == null || System.currentTimeMillis() - cacheTime > timeToLive) { - cachedValue = original.get(); - cacheTime = System.currentTimeMillis(); - } - return cachedValue; - } - - public boolean isCached() { - return cachedValue != null; - } - - public long getCacheTime() { - return cacheTime; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/Key.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/Key.java deleted file mode 100644 index 16e0838b4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/Key.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store; - -import java.util.Objects; - -/** - * Identifier used for storing and fetching data from DataContainers. - * - * @param Type of the object returned by the Value identified by this Key. - * @author Rsl1122 - */ -public class Key { - - private final Type type; - private final String keyName; - - /** - * Create a new key. - *

- * Example usage: - * {@code Key key = new Key(String.class, "identifier");} - *

- * (In Keys class) {@code public static final Key IDENTIFIER = new Key(String.class, "identifier");} - * {@code Key key = Keys.IDENTIFIER;} - * - * @param type Class with type of the Object returned by the Value identified by this Key. - * @param keyName Name (identifier) of the Key. - */ - public Key(Class type, String keyName) { - this(Type.ofClass(type), keyName); - } - - public Key(Type type, String keyName) { - this.type = type; - this.keyName = keyName; - } - - /** - * Get the type of the key. - * - * @return specified in constructor. - */ - public Type getType() { - return type; - } - - /** - * Get the name (identifier) of the Key. - * - * @return For example "nickname" - */ - public String getKeyName() { - return keyName; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Key key = (Key) o; - return Objects.equals(type, key.type) && - Objects.equals(keyName, key.keyName); - } - - @Override - public int hashCode() { - return Objects.hash(type, keyName); - } - - /** - * Cast an object to the type of the key. - * - * @param object Object to cast. - * @return The object with the type of T. - */ - public T typeCast(Object object) { - // Since Type can have a List, Class can not be obtained in order to use Class while casting. - // This could be done since Google Gson does it, but I don't know how they do it since - // the implementation is hidden. - return (T) object; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/PlaceholderKey.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/PlaceholderKey.java deleted file mode 100644 index 40c42b069..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/PlaceholderKey.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store; - -/** - * Special Key object that can be used for placeholders when replacing values in html files. - * - * @author Rsl1122 - */ -public class PlaceholderKey extends Key { - - private final String placeholder; - - public PlaceholderKey(Class type, String placeholder) { - super(type, placeholder); - this.placeholder = placeholder; - } - - public PlaceholderKey(Type type, String placeholder) { - super(type, placeholder); - this.placeholder = placeholder; - } - - public String getPlaceholder() { - return placeholder; - } - - @Override - public boolean equals(Object o) { - return super.equals(o); - } - - @Override - public int hashCode() { - return super.hashCode(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/Type.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/Type.java deleted file mode 100644 index 24289bf8f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/Type.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store; - -import java.util.Objects; - -/** - * Similar to Google's TypeToken but without requiring whole gson package. - *

- * Create new instance with {@code new Type() {}}. - * - * @author Rsl1122 - */ -public abstract class Type { - - private final String genericsSuperClass; - - public Type() { - genericsSuperClass = getGenericsClass().getGenericSuperclass().getTypeName(); - } - - public static Type ofClass(Class of) { - return new Type() {}; - } - - public static Type of(K object) { - return new Type() {}; - } - - public Class> getGenericsClass() { - return (Class>) getClass(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Type)) return false; - Type type = (Type) o; - return Objects.equals(genericsSuperClass, type.genericsSuperClass); - } - - @Override - public int hashCode() { - - return Objects.hash(genericsSuperClass); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java deleted file mode 100644 index 3a26990f9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java +++ /dev/null @@ -1,561 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.containers; - -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.Type; -import com.djrapitops.plan.data.store.keys.AnalysisKeys; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.data.store.mutators.*; -import com.djrapitops.plan.data.store.mutators.health.HealthInformation; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DisplaySettings; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.formatting.Formatters; -import com.djrapitops.plan.utilities.html.graphs.Graphs; -import com.djrapitops.plan.utilities.html.graphs.bar.BarGraph; -import com.djrapitops.plan.utilities.html.graphs.line.PingGraph; -import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; -import com.djrapitops.plan.utilities.html.graphs.stack.StackGraph; -import com.djrapitops.plan.utilities.html.pages.AnalysisPluginTabs; -import com.djrapitops.plan.utilities.html.structure.Accordions; -import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator; -import com.djrapitops.plan.utilities.html.structure.RecentLoginList; -import com.djrapitops.plan.utilities.html.structure.SessionAccordion; -import com.djrapitops.plan.utilities.html.tables.HtmlTables; -import com.djrapitops.plugin.api.TimeAmount; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -/** - * Container used for analysis. - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.store.keys.AnalysisKeys for Key objects - * @see com.djrapitops.plan.data.store.PlaceholderKey for placeholder information - */ -public class AnalysisContainer extends DynamicDataContainer { - - private final ServerContainer serverContainer; - - private final String version; - private final Locale locale; - private final PlanConfig config; - private final Theme theme; - private final ServerProperties serverProperties; - private final Formatters formatters; - private final Graphs graphs; - private final HtmlTables tables; - private final Accordions accordions; - private final AnalysisPluginsTabContentCreator pluginsTabContentCreator; - private TimeZone timeZone; - - public AnalysisContainer( - ServerContainer serverContainer, - String version, - Locale locale, - PlanConfig config, - Theme theme, - ServerProperties serverProperties, - Formatters formatters, - Graphs graphs, - HtmlTables tables, - Accordions accordions, - AnalysisPluginsTabContentCreator pluginsTabContentCreator - ) { - this.serverContainer = serverContainer; - this.version = version; - this.locale = locale; - this.config = config; - this.theme = theme; - this.serverProperties = serverProperties; - this.formatters = formatters; - this.graphs = graphs; - this.tables = tables; - this.accordions = accordions; - this.pluginsTabContentCreator = pluginsTabContentCreator; - - timeZone = config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT"); - - addAnalysisSuppliers(); - } - - public ServerContainer getServerContainer() { - return serverContainer; - } - - private void addAnalysisSuppliers() { - putCachingSupplier(AnalysisKeys.SESSIONS_MUTATOR, () -> SessionsMutator.forContainer(serverContainer)); - putCachingSupplier(AnalysisKeys.TPS_MUTATOR, () -> TPSMutator.forContainer(serverContainer)); - putCachingSupplier(AnalysisKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(serverContainer)); - - addConstants(); - addPlayerSuppliers(); - addSessionSuppliers(); - addGraphSuppliers(); - addTPSAverageSuppliers(); - addCommandSuppliers(); - addServerHealth(); - addPluginSuppliers(); - } - - private void addConstants() { - long now = System.currentTimeMillis(); - putRawData(AnalysisKeys.ANALYSIS_TIME, now); - putRawData(AnalysisKeys.ANALYSIS_TIME_DAY_AGO, now - TimeUnit.DAYS.toMillis(1L)); - putRawData(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO, now - TimeAmount.WEEK.toMillis(1L)); - putRawData(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO, now - TimeAmount.MONTH.toMillis(1L)); - putSupplier(AnalysisKeys.REFRESH_TIME_F, () -> formatters.clockLong().apply(getUnsafe(AnalysisKeys.ANALYSIS_TIME))); - putSupplier(AnalysisKeys.REFRESH_TIME_FULL_F, () -> formatters.secondLong().apply(getUnsafe(AnalysisKeys.ANALYSIS_TIME))); - - putRawData(AnalysisKeys.VERSION, version); - putSupplier(AnalysisKeys.TIME_ZONE, config::getTimeZoneOffsetHours); - putRawData(AnalysisKeys.FIRST_DAY, 1); - putRawData(AnalysisKeys.TPS_MEDIUM, config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED)); - putRawData(AnalysisKeys.TPS_HIGH, config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_HIGH)); - putRawData(AnalysisKeys.DISK_MEDIUM, config.get(DisplaySettings.GRAPH_DISK_THRESHOLD_MED)); - putRawData(AnalysisKeys.DISK_HIGH, config.get(DisplaySettings.GRAPH_DISK_THRESHOLD_HIGH)); - - addServerProperties(); - addThemeColors(); - } - - private void addServerProperties() { - putCachingSupplier(AnalysisKeys.SERVER_NAME, () -> serverContainer.getValue(ServerKeys.NAME).orElse("Plan")); - - putRawData(AnalysisKeys.PLAYERS_MAX, serverProperties.getMaxPlayers()); - putRawData(AnalysisKeys.PLAYERS_ONLINE, serverProperties.getOnlinePlayers()); - } - - private void addThemeColors() { - putRawData(AnalysisKeys.ACTIVITY_PIE_COLORS, theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE)); - putRawData(AnalysisKeys.GM_PIE_COLORS, theme.getValue(ThemeVal.GRAPH_GM_PIE)); - putRawData(AnalysisKeys.PLAYERS_GRAPH_COLOR, theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE)); - putRawData(AnalysisKeys.TPS_LOW_COLOR, theme.getValue(ThemeVal.GRAPH_TPS_LOW)); - putRawData(AnalysisKeys.TPS_MEDIUM_COLOR, theme.getValue(ThemeVal.GRAPH_TPS_MED)); - putRawData(AnalysisKeys.TPS_HIGH_COLOR, theme.getValue(ThemeVal.GRAPH_TPS_HIGH)); - putRawData(AnalysisKeys.WORLD_MAP_LOW_COLOR, theme.getValue(ThemeVal.WORLD_MAP_LOW)); - putRawData(AnalysisKeys.WORLD_MAP_HIGH_COLOR, theme.getValue(ThemeVal.WORLD_MAP_HIGH)); - putRawData(AnalysisKeys.WORLD_PIE_COLORS, theme.getValue(ThemeVal.GRAPH_WORLD_PIE)); - putRawData(AnalysisKeys.AVG_PING_COLOR, theme.getValue(ThemeVal.GRAPH_AVG_PING)); - putRawData(AnalysisKeys.MAX_PING_COLOR, theme.getValue(ThemeVal.GRAPH_MAX_PING)); - putRawData(AnalysisKeys.MIN_PING_COLOR, theme.getValue(ThemeVal.GRAPH_MIN_PING)); - } - - private void addPlayerSuppliers() { - putCachingSupplier(AnalysisKeys.PLAYER_NAMES, () -> serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>()) - .stream().collect(Collectors.toMap( - p -> p.getUnsafe(PlayerKeys.UUID), p -> p.getValue(PlayerKeys.NAME).orElse("?")) - ) - ); - putSupplier(AnalysisKeys.PLAYERS_TOTAL, () -> serverContainer.getValue(ServerKeys.PLAYER_COUNT).orElse(0)); - putSupplier(AnalysisKeys.PLAYERS_LAST_PEAK, () -> - serverContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS) - .map(dateObj -> Integer.toString(dateObj.getValue())).orElse("-") - ); - putSupplier(AnalysisKeys.PLAYERS_ALL_TIME_PEAK, () -> - serverContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS) - .map(dateObj -> Integer.toString(dateObj.getValue())).orElse("-") - ); - putSupplier(AnalysisKeys.LAST_PEAK_TIME_F, () -> - serverContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS) - .map(dateObj -> formatters.year().apply(dateObj)).orElse("-") - ); - putSupplier(AnalysisKeys.ALL_TIME_PEAK_TIME_F, () -> - serverContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS) - .map(dateObj -> formatters.year().apply(dateObj)).orElse("-") - ); - putSupplier(AnalysisKeys.OPERATORS, () -> serverContainer.getValue(ServerKeys.OPERATORS).map(List::size).orElse(0)); - putSupplier(AnalysisKeys.PLAYERS_TABLE, () -> - tables.playerTableForServerPage(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).all()).parseHtml() - ); - putSupplier(AnalysisKeys.PING_TABLE, () -> - tables.pingTable( - getUnsafe(AnalysisKeys.PLAYERS_MUTATOR) - .getPingPerCountry(serverContainer.getUnsafe(ServerKeys.SERVER_UUID)) - ).parseHtml() - ); - - newAndUniquePlayerCounts(); - } - - private void newAndUniquePlayerCounts() { - Key newDay = new Key<>(PlayersMutator.class, "NEW_DAY"); - Key newWeek = new Key<>(PlayersMutator.class, "NEW_WEEK"); - Key newMonth = new Key<>(PlayersMutator.class, "NEW_MONTH"); - Key uniqueDay = new Key<>(PlayersMutator.class, "UNIQUE_DAY"); - Key uniqueWeek = new Key<>(PlayersMutator.class, "UNIQUE_WEEK"); - Key uniqueMonth = new Key<>(PlayersMutator.class, "UNIQUE_MONTH"); - putCachingSupplier(newDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR) - .filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - putCachingSupplier(newWeek, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR) - .filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - putCachingSupplier(newMonth, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR) - .filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - putCachingSupplier(uniqueDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR) - .filterPlayedBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - putCachingSupplier(uniqueWeek, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR) - .filterPlayedBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - putCachingSupplier(uniqueMonth, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR) - .filterPlayedBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - - putSupplier(AnalysisKeys.PLAYERS_NEW_DAY, () -> getUnsafe(newDay).count()); - putSupplier(AnalysisKeys.PLAYERS_NEW_WEEK, () -> getUnsafe(newWeek).count()); - putSupplier(AnalysisKeys.PLAYERS_NEW_MONTH, () -> getUnsafe(newMonth).count()); - putSupplier(AnalysisKeys.PLAYERS_DAY, () -> getUnsafe(uniqueDay).count()); - putSupplier(AnalysisKeys.PLAYERS_WEEK, () -> getUnsafe(uniqueWeek).count()); - putSupplier(AnalysisKeys.PLAYERS_MONTH, () -> getUnsafe(uniqueMonth).count()); - putSupplier(AnalysisKeys.AVG_PLAYERS_NEW, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).averageNewPerDay(timeZone)); - putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_DAY, () -> getUnsafe(newDay).averageNewPerDay(timeZone)); - putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_WEEK, () -> getUnsafe(newWeek).averageNewPerDay(timeZone)); - putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_MONTH, () -> getUnsafe(newMonth).averageNewPerDay(timeZone)); - - putSupplier(AnalysisKeys.UNIQUE_PLAYERS_PER_DAY, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).uniqueJoinsPerDay(timeZone)); - putSupplier(AnalysisKeys.NEW_PLAYERS_PER_DAY, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).newPerDay(timeZone)); - putSupplier(AnalysisKeys.UNIQUE_PLAYERS_SERIES, () -> graphs.line().lineGraph( - MutatorFunctions.toPointsWithRemovedOffset(getUnsafe(AnalysisKeys.UNIQUE_PLAYERS_PER_DAY), timeZone)).toHighChartsSeries() - ); - putSupplier(AnalysisKeys.NEW_PLAYERS_SERIES, () -> graphs.line().lineGraph( - MutatorFunctions.toPointsWithRemovedOffset(getUnsafe(AnalysisKeys.NEW_PLAYERS_PER_DAY), timeZone)).toHighChartsSeries() - ); - - Key retentionDay = new Key<>(Integer.class, "RETENTION_DAY"); - // compareAndFindThoseLikelyToBeRetained can throw exception. - putCachingSupplier(retentionDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).compareAndFindThoseLikelyToBeRetained( - getUnsafe(newDay).all(), getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), - getUnsafe(AnalysisKeys.PLAYERS_ONLINE_RESOLVER), - config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), - config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD) - ).count() - ); - putSupplier(AnalysisKeys.PLAYERS_RETAINED_DAY, () -> { - try { - return getUnsafe(retentionDay); - } catch (IllegalStateException noPlayersAfterDateFiltering) { - return 0; - } - }); - putCachingSupplier(AnalysisKeys.PLAYERS_RETAINED_WEEK, () -> - getUnsafe(newWeek).filterRetained( - getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), - getUnsafe(AnalysisKeys.ANALYSIS_TIME) - ).count() - ); - putCachingSupplier(AnalysisKeys.PLAYERS_RETAINED_MONTH, () -> - getUnsafe(newMonth).filterRetained( - getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), - getUnsafe(AnalysisKeys.ANALYSIS_TIME) - ).count() - ); - putSupplier(AnalysisKeys.PLAYERS_RETAINED_DAY_PERC, () -> { - try { - Integer playersNewDay = getUnsafe(AnalysisKeys.PLAYERS_NEW_DAY); - return playersNewDay != 0 - ? formatters.percentage().apply(1.0 * getUnsafe(retentionDay) / playersNewDay) - : "-"; - } catch (IllegalStateException noPlayersAfterDateFiltering) { - return "Not enough data"; - } - }); - putSupplier(AnalysisKeys.PLAYERS_RETAINED_WEEK_PERC, () -> { - Integer playersNewWeek = getUnsafe(AnalysisKeys.PLAYERS_NEW_WEEK); - return playersNewWeek != 0 ? formatters.percentage().apply(1.0 * getUnsafe(AnalysisKeys.PLAYERS_RETAINED_WEEK) / playersNewWeek) : "-"; - } - ); - putSupplier(AnalysisKeys.PLAYERS_RETAINED_MONTH_PERC, () -> { - Integer playersNewMonth = getUnsafe(AnalysisKeys.PLAYERS_NEW_MONTH); - return playersNewMonth != 0 - ? formatters.percentage().apply(1.0 * getUnsafe(AnalysisKeys.PLAYERS_RETAINED_MONTH) / playersNewMonth) - : "-"; - } - ); - } - - private void addSessionSuppliers() { - Key sessionAccordion = new Key<>(SessionAccordion.class, "SESSION_ACCORDION"); - putCachingSupplier(sessionAccordion, () -> accordions.serverSessionAccordion( - getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all(), - () -> Collections.singletonMap( - serverContainer.getUnsafe(ServerKeys.SERVER_UUID), - serverContainer.getValue(ServerKeys.NAME).orElse("This server") - ), - () -> getUnsafe(AnalysisKeys.PLAYER_NAMES) - )); - putSupplier(AnalysisKeys.SESSION_ACCORDION_HTML, () -> getUnsafe(sessionAccordion).toHtml()); - putSupplier(AnalysisKeys.SESSION_ACCORDION_FUNCTIONS, () -> getUnsafe(sessionAccordion).toViewScript()); - - putSupplier(AnalysisKeys.RECENT_LOGINS, () -> new RecentLoginList( - serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>()), - formatters.secondLong()).toHtml() - ); - putSupplier(AnalysisKeys.SESSION_TABLE, () -> tables.serverSessionTable( - getUnsafe(AnalysisKeys.PLAYER_NAMES), getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all()).parseHtml() - ); - - putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, - () -> formatters.timeAmount().apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) - ); - putSupplier(AnalysisKeys.SESSION_COUNT, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).count()); - putSupplier(AnalysisKeys.PLAYTIME_TOTAL, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toPlaytime()); - putSupplier(AnalysisKeys.DEATHS, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toDeathCount()); - putSupplier(AnalysisKeys.MOB_KILL_COUNT, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toMobKillCount()); - putSupplier(AnalysisKeys.PLAYER_KILL_COUNT, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toPlayerKillCount()); - putSupplier(AnalysisKeys.PLAYTIME_F, - () -> formatters.timeAmount().apply(getUnsafe(AnalysisKeys.PLAYTIME_TOTAL)) - ); - putSupplier(AnalysisKeys.AVERAGE_PLAYTIME_F, () -> { - long players = getUnsafe(AnalysisKeys.PLAYERS_TOTAL); - return players != 0 - ? formatters.timeAmount().apply(getUnsafe(AnalysisKeys.PLAYTIME_TOTAL) / players) - : "-"; - } - ); - putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, - () -> formatters.timeAmount().apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) - ); - - Key sessionsDay = new Key<>(SessionsMutator.class, "SESSIONS_DAY"); - Key sessionsWeek = new Key<>(SessionsMutator.class, "SESSIONS_WEEK"); - Key sessionsMonth = new Key<>(SessionsMutator.class, "SESSIONS_MONTH"); - putCachingSupplier(sessionsDay, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR) - .filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - putCachingSupplier(sessionsWeek, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR) - .filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - putCachingSupplier(sessionsMonth, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR) - .filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - - putSupplier(AnalysisKeys.PUNCHCARD_SERIES, () -> graphs.special().punchCard(getUnsafe(sessionsMonth).all()).toHighChartsSeries()); - putSupplier(AnalysisKeys.AVG_PLAYERS, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageUniqueJoinsPerDay(timeZone)); - putSupplier(AnalysisKeys.AVG_PLAYERS_DAY, () -> getUnsafe(sessionsDay).toAverageUniqueJoinsPerDay(timeZone)); - putSupplier(AnalysisKeys.AVG_PLAYERS_WEEK, () -> getUnsafe(sessionsWeek).toAverageUniqueJoinsPerDay(timeZone)); - putSupplier(AnalysisKeys.AVG_PLAYERS_MONTH, () -> getUnsafe(sessionsMonth).toAverageUniqueJoinsPerDay(timeZone)); - } - - private void addGraphSuppliers() { - Key worldPie = new Key<>(WorldPie.class, "WORLD_PIE"); - putCachingSupplier(worldPie, () -> graphs.pie().worldPie( - serverContainer.getValue(ServerKeys.WORLD_TIMES).orElse(new WorldTimes()) - )); - putSupplier(AnalysisKeys.WORLD_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsSeries()); - putSupplier(AnalysisKeys.GM_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsDrilldown()); - putSupplier(AnalysisKeys.PLAYERS_ONLINE_SERIES, () -> - graphs.line().playersOnlineGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries() - ); - putSupplier(AnalysisKeys.TPS_SERIES, () -> graphs.line().tpsGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.CPU_SERIES, () -> graphs.line().cpuGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.RAM_SERIES, () -> graphs.line().ramGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.DISK_SERIES, () -> graphs.line().diskGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.ENTITY_SERIES, () -> graphs.line().entityGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.CHUNK_SERIES, () -> graphs.line().chunkGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.WORLD_MAP_SERIES, () -> - graphs.special().worldMap(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)).toHighChartsSeries() - ); - Key geolocationBarChart = new Key<>(BarGraph.class, "GEOLOCATION_BAR_GRAPH"); - putCachingSupplier(geolocationBarChart, () -> graphs.bar().geolocationBarGraph(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))); - putSupplier(AnalysisKeys.COUNTRY_CATEGORIES, () -> getUnsafe(geolocationBarChart).toHighChartsCategories()); - putSupplier(AnalysisKeys.COUNTRY_SERIES, () -> getUnsafe(geolocationBarChart).toHighChartsSeries()); - - Key pingGraph = new Key<>(PingGraph.class, "PING_GRAPH"); - putCachingSupplier(pingGraph, () -> - graphs.line().pingGraph(PingMutator.forContainer(serverContainer).mutateToByMinutePings().all()) - ); - putSupplier(AnalysisKeys.AVG_PING_SERIES, () -> getUnsafe(pingGraph).toAvgSeries()); - putSupplier(AnalysisKeys.MAX_PING_SERIES, () -> getUnsafe(pingGraph).toMaxSeries()); - putSupplier(AnalysisKeys.MIN_PING_SERIES, () -> getUnsafe(pingGraph).toMinSeries()); - - putSupplier(AnalysisKeys.CALENDAR_SERIES, () -> graphs.calendar().serverCalendar( - getUnsafe(AnalysisKeys.PLAYERS_MUTATOR), - getUnsafe(AnalysisKeys.UNIQUE_PLAYERS_PER_DAY), - getUnsafe(AnalysisKeys.NEW_PLAYERS_PER_DAY) - ).toCalendarSeries()); - - putCachingSupplier(AnalysisKeys.ACTIVITY_DATA, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(AnalysisKeys.ANALYSIS_TIME), config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD))); - Key activityStackGraph = new Key<>(StackGraph.class, "ACTIVITY_STACK_GRAPH"); - putCachingSupplier(activityStackGraph, () -> graphs.stack().activityStackGraph(getUnsafe(AnalysisKeys.ACTIVITY_DATA))); - putSupplier(AnalysisKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels()); - putSupplier(AnalysisKeys.ACTIVITY_STACK_SERIES, () -> getUnsafe(activityStackGraph).toHighChartsSeries()); - putSupplier(AnalysisKeys.ACTIVITY_PIE_SERIES, () -> graphs.pie().activityPie( - getUnsafe(AnalysisKeys.ACTIVITY_DATA).get(getUnsafe(AnalysisKeys.ANALYSIS_TIME))).toHighChartsSeries() - ); - putSupplier(AnalysisKeys.PLAYERS_REGULAR, () -> { - Map> activityNow = getUnsafe(AnalysisKeys.ACTIVITY_DATA) - .floorEntry(getUnsafe(AnalysisKeys.ANALYSIS_TIME)).getValue(); - Set veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>()); - Set activeNow = activityNow.getOrDefault("Active", new HashSet<>()); - Set regularNow = activityNow.getOrDefault("Regular", new HashSet<>()); - return veryActiveNow.size() + activeNow.size() + regularNow.size(); - }); - } - - private void addTPSAverageSuppliers() { - Key tpsMonth = new Key<>(TPSMutator.class, "TPS_MONTH"); - Key tpsWeek = new Key<>(TPSMutator.class, "TPS_WEEK"); - Key tpsDay = new Key<>(TPSMutator.class, "TPS_DAY"); - - putCachingSupplier(tpsMonth, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR) - .filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - putCachingSupplier(tpsWeek, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR) - .filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - putCachingSupplier(tpsDay, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR) - .filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) - ); - - putCachingSupplier(AnalysisKeys.PLAYERS_ONLINE_RESOLVER, () -> new PlayersOnlineResolver(getUnsafe(AnalysisKeys.TPS_MUTATOR))); - - int threshold = config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED); - - putSupplier(AnalysisKeys.TPS_SPIKE_MONTH, () -> getUnsafe(tpsMonth).lowTpsSpikeCount(threshold)); - putSupplier(AnalysisKeys.AVG_TPS_MONTH, () -> getUnsafe(tpsMonth).averageTPS()); - putSupplier(AnalysisKeys.AVG_CPU_MONTH, () -> getUnsafe(tpsMonth).averageCPU()); - putSupplier(AnalysisKeys.AVG_RAM_MONTH, () -> getUnsafe(tpsMonth).averageRAM()); - putSupplier(AnalysisKeys.AVG_ENTITY_MONTH, () -> getUnsafe(tpsMonth).averageEntities()); - putSupplier(AnalysisKeys.AVG_CHUNK_MONTH, () -> getUnsafe(tpsMonth).averageChunks()); - putSupplier(AnalysisKeys.AVG_FREE_DISK_MONTH, () -> getUnsafe(tpsMonth).averageFreeDisk()); - putSupplier(AnalysisKeys.MAX_FREE_DISK_MONTH, () -> getUnsafe(tpsMonth).maxFreeDisk()); - putSupplier(AnalysisKeys.MIN_FREE_DISK_MONTH, () -> getUnsafe(tpsMonth).minFreeDisk()); - - putSupplier(AnalysisKeys.TPS_SPIKE_WEEK, () -> getUnsafe(tpsWeek).lowTpsSpikeCount(threshold)); - putSupplier(AnalysisKeys.AVG_TPS_WEEK, () -> getUnsafe(tpsWeek).averageTPS()); - putSupplier(AnalysisKeys.AVG_CPU_WEEK, () -> getUnsafe(tpsWeek).averageCPU()); - putSupplier(AnalysisKeys.AVG_RAM_WEEK, () -> getUnsafe(tpsWeek).averageRAM()); - putSupplier(AnalysisKeys.AVG_ENTITY_WEEK, () -> getUnsafe(tpsWeek).averageEntities()); - putSupplier(AnalysisKeys.AVG_CHUNK_WEEK, () -> getUnsafe(tpsWeek).averageChunks()); - putSupplier(AnalysisKeys.AVG_FREE_DISK_WEEK, () -> getUnsafe(tpsWeek).averageFreeDisk()); - putSupplier(AnalysisKeys.MAX_FREE_DISK_WEEK, () -> getUnsafe(tpsWeek).maxFreeDisk()); - putSupplier(AnalysisKeys.MIN_FREE_DISK_WEEK, () -> getUnsafe(tpsWeek).minFreeDisk()); - - putSupplier(AnalysisKeys.TPS_SPIKE_DAY, () -> getUnsafe(tpsDay).lowTpsSpikeCount(threshold)); - putSupplier(AnalysisKeys.AVG_TPS_DAY, () -> getUnsafe(tpsDay).averageTPS()); - putSupplier(AnalysisKeys.AVG_CPU_DAY, () -> getUnsafe(tpsDay).averageCPU()); - putSupplier(AnalysisKeys.AVG_RAM_DAY, () -> getUnsafe(tpsDay).averageRAM()); - putSupplier(AnalysisKeys.AVG_ENTITY_DAY, () -> getUnsafe(tpsDay).averageEntities()); - putSupplier(AnalysisKeys.AVG_CHUNK_DAY, () -> getUnsafe(tpsDay).averageChunks()); - putSupplier(AnalysisKeys.AVG_FREE_DISK_DAY, () -> getUnsafe(tpsDay).averageFreeDisk()); - putSupplier(AnalysisKeys.MAX_FREE_DISK_DAY, () -> getUnsafe(tpsDay).maxFreeDisk()); - putSupplier(AnalysisKeys.MIN_FREE_DISK_DAY, () -> getUnsafe(tpsDay).minFreeDisk()); - } - - private void addCommandSuppliers() { - putSupplier(AnalysisKeys.COMMAND_USAGE_TABLE, () -> tables.commandUseTable(serverContainer).parseHtml()); - putSupplier(AnalysisKeys.COMMAND_COUNT_UNIQUE, () -> serverContainer.getValue(ServerKeys.COMMAND_USAGE).map(Map::size).orElse(0)); - putSupplier(AnalysisKeys.COMMAND_COUNT, () -> CommandUseMutator.forContainer(serverContainer).commandUsageCount()); - } - - private void addServerHealth() { - Key healthInformation = new Key<>(HealthInformation.class, "HEALTH_INFORMATION"); - putCachingSupplier(healthInformation, () -> new HealthInformation( - this, - locale, - config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED), - config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), - config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD), - formatters.timeAmount(), formatters.decimals(), formatters.percentage() - )); - putSupplier(AnalysisKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth()); - putSupplier(AnalysisKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml()); - } - - private void addPluginSuppliers() { - // TODO Refactor into a system that supports running the analysis on Bungee - Key navAndTabs = new Key<>(new Type() {}, "NAV_AND_TABS"); - Key pluginTabs = new Key<>(AnalysisPluginTabs.class, "PLUGIN_TABS"); - putCachingSupplier(navAndTabs, () -> pluginsTabContentCreator.createContent( - this, getValue(AnalysisKeys.PLAYERS_MUTATOR).orElse(new PlayersMutator(new ArrayList<>())) - )); - putCachingSupplier(pluginTabs, () -> new AnalysisPluginTabs(serverContainer.getValue(ServerKeys.EXTENSION_DATA).orElse(new ArrayList<>()), formatters)); - putSupplier(AnalysisKeys.PLUGINS_TAB_NAV, () -> getUnsafe(pluginTabs).getNav() + getUnsafe(navAndTabs)[0]); - putSupplier(AnalysisKeys.PLUGINS_TAB, () -> getUnsafe(pluginTabs).getTabs() + getUnsafe(navAndTabs)[1]); - } - - @Singleton - public static class Factory { - - private final String version; - private final PlanConfig config; - private final Locale locale; - private final Theme theme; - private final ServerProperties serverProperties; - private final Formatters formatters; - private final Graphs graphs; - private final HtmlTables tables; - private final Accordions accordions; - private final AnalysisPluginsTabContentCreator pluginsTabContentCreator; - - @Inject - public Factory( - @Named("currentVersion") String version, - PlanConfig config, - Locale locale, - Theme theme, - ServerProperties serverProperties, - Formatters formatters, - Graphs graphs, - HtmlTables tables, - Accordions accordions, - AnalysisPluginsTabContentCreator pluginsTabContentCreator - ) { - this.version = version; - this.config = config; - this.locale = locale; - this.theme = theme; - this.serverProperties = serverProperties; - this.formatters = formatters; - this.graphs = graphs; - this.tables = tables; - this.accordions = accordions; - this.pluginsTabContentCreator = pluginsTabContentCreator; - } - - public AnalysisContainer forServerContainer(ServerContainer serverContainer) { - return new AnalysisContainer( - serverContainer, - version, - locale, - config, - theme, - serverProperties, - formatters, - graphs, - tables, - accordions, - pluginsTabContentCreator - ); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java deleted file mode 100644 index c2f508da8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.containers; - -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.utilities.formatting.Formatter; - -import java.util.Map; -import java.util.Optional; -import java.util.function.Supplier; - -/** - * Interface for an object that can store arbitrary data referenced via {@link Key} objects. - *

- * Implementations should mainly be concerned on how the data given to it is stored. - * Retrieval has some details that should be followed. - * - * @author Rsl1122 - */ -public interface DataContainer { - - /** - * Place your data inside the container. - *

- * What the container does with the object depends on the implementation. - * - * @param key Key of type T that identifies the data and will be used later when the data needs to be fetched. - * @param obj object to store - * @param Type of the object - */ - void putRawData(Key key, T obj); - - /** - * Place a data supplier inside the container. - *

- * What the container does with the supplier depends on the implementation. - * - * @param key Key of type T that identifies the data and will be used later when the data needs to be fetched. - * @param supplier Supplier to store - * @param Type of the object - */ - void putSupplier(Key key, Supplier supplier); - - /** - * Place a caching data supplier inside the container. - *

- * If the supplier is called the value is cached according to the implementation of the container. - * What the container does with the supplier depends on the implementation. - * - * @param key Key of type T that identifies the data and will be used later when the data needs to be fetched. - * @param supplier Supplier to store - * @param Type of the object - */ - void putCachingSupplier(Key key, Supplier supplier); - - /** - * Check if a Value with the given Key has been placed into the container. - * - * @param key Key that identifies the data. - * @param Type of the object returned by the Value if it is present. - * @return true if found, false if not. - */ - boolean supports(Key key); - - /** - * Get an Optional of the Value identified by the Key. - *

- * It is recommended to check if the Optional is present as null values will be empty. - * - * @param key Key that identifies the Value - * @param Type of the object returned by Value - * @return Optional of the object if the key is registered and key matches the type of the object. Otherwise empty. - */ - Optional getValue(Key key); - - /** - * Get data identified by the Key, or throw an exception. - *

- * It is recommended to use {@link DataContainer#supports(Key)} before using this method. - * - * @param key Key that identifies the Value - * @param Type of the object returned by Value - * @return the value - * @throws IllegalArgumentException If the key is not supported. - */ - T getUnsafe(Key key); - - /** - * Get formatted Value identified by the Key. - *

- * - * @param key Key that identifies the Value - * @param formatter Formatter for the Optional returned by {@link DataContainer#getValue(Key)} - * @param Type of the object returned by Value - * @return Optional of the object if the key is registered and key matches the type of the object. Otherwise empty. - */ - default String getFormatted(Key key, Formatter> formatter) { - Optional value = getValue(key); - return formatter.apply(value); - } - - /** - * Get formatted Value identified by the Key, or throw an exception. - *

- * It is recommended to use {@link DataContainer#supports(Key)} before using this method. - * - * @param key Key that identifies the Value - * @param formatter Formatter for the value - * @param Type of the object returned by Value - * @return the value - * @throws IllegalArgumentException If the key is not supported. - */ - default String getFormattedUnsafe(Key key, Formatter formatter) { - T value = getUnsafe(key); - return formatter.apply(value); - } - - /** - * Place all values from given DataContainer into this container. - * - * @param dataContainer Container with values. - */ - void putAll(DataContainer dataContainer); - - /** - * Clear the container of all data. - */ - void clear(); - - /** - * Return a Key - Value Map of the data in the container. - *

- * This method may call blocking methods if underlying implementation uses the given Suppliers. - * - * @return Map: Key - Object - */ - Map getMap(); -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/DynamicDataContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/DynamicDataContainer.java deleted file mode 100644 index baf3cc93a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/DynamicDataContainer.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.containers; - -import com.djrapitops.plan.data.store.Key; - -import java.util.Map; -import java.util.Optional; -import java.util.function.Supplier; - -/** - * DataContainer implementation that delegates the method calls to other DataContainer implementations. - * - * @author Rsl1122 - */ -public class DynamicDataContainer implements DataContainer { - - private final SupplierDataContainer supplierDataContainer; - private final RawDataContainer rawDataContainer; - - public DynamicDataContainer() { - supplierDataContainer = new SupplierDataContainer(); - rawDataContainer = new RawDataContainer(); - } - - public DynamicDataContainer(long timeToLive) { - supplierDataContainer = new SupplierDataContainer(timeToLive); - rawDataContainer = new RawDataContainer(); - } - - @Override - public void putRawData(Key key, T obj) { - rawDataContainer.putRawData(key, obj); - } - - @Override - public void putSupplier(Key key, Supplier supplier) { - supplierDataContainer.putSupplier(key, supplier); - } - - @Override - public void putCachingSupplier(Key key, Supplier supplier) { - supplierDataContainer.putCachingSupplier(key, supplier); - } - - @Override - public boolean supports(Key key) { - return rawDataContainer.supports(key) || supplierDataContainer.supports(key); - } - - @Override - public Optional getValue(Key key) { - Optional raw = rawDataContainer.getValue(key); - if (raw.isPresent()) { - return raw; - } else { - return supplierDataContainer.getValue(key); - } - } - - @Override - public T getUnsafe(Key key) { - if (rawDataContainer.supports(key)) { - return rawDataContainer.getUnsafe(key); - } else { - return supplierDataContainer.getUnsafe(key); - } - } - - @Override - public void putAll(DataContainer dataContainer) { - if (dataContainer instanceof SupplierDataContainer) { - supplierDataContainer.putAll(dataContainer); - } else if (dataContainer instanceof RawDataContainer) { - rawDataContainer.putAll(dataContainer); - } else { - rawDataContainer.putAll(dataContainer.getMap()); - } - } - - @Override - public void clear() { - rawDataContainer.clear(); - supplierDataContainer.clear(); - } - - @Override - public Map getMap() { - Map map = supplierDataContainer.getMap(); - map.putAll(rawDataContainer.getMap()); - return map; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/NetworkContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/NetworkContainer.java deleted file mode 100644 index 8ce401177..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/NetworkContainer.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.containers; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.keys.NetworkKeys; -import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plan.data.store.mutators.TPSMutator; -import com.djrapitops.plan.data.store.mutators.health.NetworkHealthInformation; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.ServerAggregateQueries; -import com.djrapitops.plan.db.access.queries.objects.TPSQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.ProxySettings; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.formatting.Formatters; -import com.djrapitops.plan.utilities.html.graphs.Graphs; -import com.djrapitops.plan.utilities.html.graphs.bar.BarGraph; -import com.djrapitops.plan.utilities.html.graphs.stack.StackGraph; -import com.djrapitops.plan.utilities.html.structure.NetworkServerBox; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.TimeAmount; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; -import java.util.*; -import java.util.concurrent.TimeUnit; - -/** - * DataContainer for the whole network. - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.store.keys.NetworkKeys for Key objects - * @see com.djrapitops.plan.data.store.PlaceholderKey for placeholder information - */ -public class NetworkContainer extends DynamicDataContainer { - - private final ServerContainer bungeeContainer; - - private final String version; - private final PlanConfig config; - private final Locale locale; - private final Theme theme; - private final ServerProperties serverProperties; - private final Formatters formatters; - private final Graphs graphs; - private final Database database; - - public NetworkContainer( - ServerContainer bungeeContainer, - String version, - PlanConfig config, - Locale locale, - Theme theme, - DBSystem dbSystem, - ServerProperties serverProperties, - Formatters formatters, - Graphs graphs - ) { - this.bungeeContainer = bungeeContainer; - this.version = version; - this.config = config; - this.locale = locale; - this.theme = theme; - this.database = dbSystem.getDatabase(); - this.serverProperties = serverProperties; - this.formatters = formatters; - this.graphs = graphs; - - putCachingSupplier(NetworkKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(bungeeContainer)); - - addConstants(); - addServerBoxes(); - addPlayerInformation(); - addNetworkHealth(); - } - - private void addServerBoxes() { - putSupplier(NetworkKeys.NETWORK_PLAYER_ONLINE_DATA, () -> database.query(TPSQueries.fetchPlayerOnlineDataOfServers( - getValue(NetworkKeys.BUKKIT_SERVERS).orElse(new ArrayList<>())) - )); - putSupplier(NetworkKeys.SERVERS_TAB, () -> { - StringBuilder serverBoxes = new StringBuilder(); - Map> playersOnlineData = getValue(NetworkKeys.NETWORK_PLAYER_ONLINE_DATA).orElse(new HashMap<>()); - Map userCounts = database.query(ServerAggregateQueries.serverUserCounts()); - Collection servers = getValue(NetworkKeys.BUKKIT_SERVERS).orElse(new ArrayList<>()); - servers.stream() - .sorted((one, two) -> String.CASE_INSENSITIVE_ORDER.compare(one.getName(), two.getName())) - .forEach(server -> { - TPSMutator tpsMutator = new TPSMutator(playersOnlineData.getOrDefault(server.getId(), new ArrayList<>())); - int registered = userCounts.getOrDefault(server.getUuid(), 0); - NetworkServerBox serverBox = new NetworkServerBox(server, registered, tpsMutator, graphs); - serverBoxes.append(serverBox.toHtml()); - }); - if (servers.isEmpty()) { - serverBoxes.append("

" + - "
" + - "
" + - "
" + - "
" + - "
" + - "

No Servers

" + - "
" + - "

No Bukkit/Sponge servers connected to Plan.

" + - "
"); - } - return serverBoxes.toString(); - }); - } - - private void addNetworkHealth() { - Key healthInformation = new Key<>(NetworkHealthInformation.class, "HEALTH_INFORMATION"); - putCachingSupplier(healthInformation, () -> new NetworkHealthInformation( - this, - locale, - config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), - config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD), - formatters.timeAmount(), formatters.decimals(), formatters.percentage(), - config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT") - )); - putCachingSupplier(NetworkKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth()); - putCachingSupplier(NetworkKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml()); - } - - private void addConstants() { - long now = System.currentTimeMillis(); - putRawData(NetworkKeys.REFRESH_TIME, now); - putRawData(NetworkKeys.REFRESH_TIME_DAY_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeUnit.DAYS.toMillis(1L)); - putRawData(NetworkKeys.REFRESH_TIME_WEEK_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.WEEK.toMillis(1L)); - putRawData(NetworkKeys.REFRESH_TIME_MONTH_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.MONTH.toMillis(1L)); - putSupplier(NetworkKeys.REFRESH_TIME_F, () -> formatters.secondLong().apply(getUnsafe(NetworkKeys.REFRESH_TIME))); - - putRawData(NetworkKeys.VERSION, version); - putSupplier(NetworkKeys.TIME_ZONE, config::getTimeZoneOffsetHours); - - putCachingSupplier(NetworkKeys.NETWORK_NAME, () -> - Check.isBungeeAvailable() || Check.isVelocityAvailable() ? - config.get(ProxySettings.NETWORK_NAME) : - bungeeContainer.getValue(ServerKeys.NAME).orElse("Plan") - ); - putSupplier(NetworkKeys.PLAYERS_ONLINE, serverProperties::getOnlinePlayers); - putRawData(NetworkKeys.WORLD_MAP_LOW_COLOR, theme.getValue(ThemeVal.WORLD_MAP_LOW)); - putRawData(NetworkKeys.WORLD_MAP_HIGH_COLOR, theme.getValue(ThemeVal.WORLD_MAP_HIGH)); - putRawData(NetworkKeys.PLAYERS_GRAPH_COLOR, theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE)); - } - - private void addPlayerInformation() { - putSupplier(NetworkKeys.PLAYERS_TOTAL, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR).count()); - putSupplier(NetworkKeys.WORLD_MAP_SERIES, () -> - graphs.special().worldMap(database.query(ServerAggregateQueries.networkGeolocationCounts())).toHighChartsSeries() - ); - Key geolocationBarChart = new Key<>(BarGraph.class, "GEOLOCATION_BAR_GRAPH"); - putSupplier(geolocationBarChart, () -> graphs.bar().geolocationBarGraph(getUnsafe(NetworkKeys.PLAYERS_MUTATOR))); - putSupplier(NetworkKeys.COUNTRY_CATEGORIES, () -> getUnsafe(geolocationBarChart).toHighChartsCategories()); - putSupplier(NetworkKeys.COUNTRY_SERIES, () -> getUnsafe(geolocationBarChart).toHighChartsSeries()); - - putSupplier(NetworkKeys.PLAYERS_ONLINE_SERIES, () -> - graphs.line().playersOnlineGraph(TPSMutator.forContainer(bungeeContainer)).toHighChartsSeries() - ); - Key activityStackGraph = new Key<>(StackGraph.class, "ACTIVITY_STACK_GRAPH"); - putSupplier(NetworkKeys.ACTIVITY_DATA, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(NetworkKeys.REFRESH_TIME), config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD))); - putSupplier(activityStackGraph, () -> graphs.stack().activityStackGraph(getUnsafe(NetworkKeys.ACTIVITY_DATA))); - putSupplier(NetworkKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels()); - putSupplier(NetworkKeys.ACTIVITY_STACK_SERIES, () -> getUnsafe(activityStackGraph).toHighChartsSeries()); - putSupplier(NetworkKeys.ACTIVITY_PIE_SERIES, () -> graphs.pie().activityPie( - getUnsafe(NetworkKeys.ACTIVITY_DATA).get(getUnsafe(NetworkKeys.REFRESH_TIME))).toHighChartsSeries() - ); - - putSupplier(NetworkKeys.ALL_TIME_PEAK_TIME_F, () -> - bungeeContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS).map(formatters.year()).orElse("No data") - ); - putSupplier(NetworkKeys.RECENT_PEAK_TIME_F, () -> - bungeeContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS).map(formatters.year()).orElse("No data") - ); - putSupplier(NetworkKeys.PLAYERS_ALL_TIME_PEAK, () -> - bungeeContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS).map(dateObj -> "" + dateObj.getValue()).orElse("-") - ); - putSupplier(NetworkKeys.PLAYERS_RECENT_PEAK, () -> - bungeeContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS).map(dateObj -> "" + dateObj.getValue()).orElse("-") - ); - - addPlayerCounts(); - } - - private void addPlayerCounts() { - Key newDay = new Key<>(PlayersMutator.class, "NEW_DAY"); - Key newWeek = new Key<>(PlayersMutator.class, "NEW_WEEK"); - Key newMonth = new Key<>(PlayersMutator.class, "NEW_MONTH"); - Key uniqueDay = new Key<>(PlayersMutator.class, "UNIQUE_DAY"); - Key uniqueWeek = new Key<>(PlayersMutator.class, "UNIQUE_WEEK"); - Key uniqueMonth = new Key<>(PlayersMutator.class, "UNIQUE_MONTH"); - putCachingSupplier(newDay, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR) - .filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_DAY_AGO), getUnsafe(NetworkKeys.REFRESH_TIME)) - ); - putCachingSupplier(newWeek, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR) - .filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_WEEK_AGO), getUnsafe(NetworkKeys.REFRESH_TIME)) - ); - putCachingSupplier(newMonth, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR) - .filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), getUnsafe(NetworkKeys.REFRESH_TIME)) - ); - putCachingSupplier(uniqueDay, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR) - .filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_DAY_AGO), getUnsafe(NetworkKeys.REFRESH_TIME)) - ); - putCachingSupplier(uniqueWeek, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR) - .filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_WEEK_AGO), getUnsafe(NetworkKeys.REFRESH_TIME)) - ); - putCachingSupplier(uniqueMonth, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR) - .filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), getUnsafe(NetworkKeys.REFRESH_TIME)) - ); - - putSupplier(NetworkKeys.PLAYERS_NEW_DAY, () -> getUnsafe(newDay).count()); - putSupplier(NetworkKeys.PLAYERS_NEW_WEEK, () -> getUnsafe(newWeek).count()); - putSupplier(NetworkKeys.PLAYERS_NEW_MONTH, () -> getUnsafe(newMonth).count()); - putSupplier(NetworkKeys.PLAYERS_DAY, () -> getUnsafe(uniqueDay).count()); - putSupplier(NetworkKeys.PLAYERS_WEEK, () -> getUnsafe(uniqueWeek).count()); - putSupplier(NetworkKeys.PLAYERS_MONTH, () -> getUnsafe(uniqueMonth).count()); - } - - public ServerContainer getBungeeContainer() { - return bungeeContainer; - } - - @Singleton - public static class Factory { - - private final Lazy version; - private final Lazy config; - private final Lazy locale; - private final Lazy theme; - private final Lazy dbSystem; - private final Lazy serverProperties; - private final Lazy formatters; - private final Lazy graphs; - - @Inject - public Factory( - @Named("currentVersion") Lazy version, - Lazy config, - Lazy locale, - Lazy theme, - Lazy dbSystem, - Lazy serverProperties, - Lazy formatters, - Lazy graphs - ) { - this.version = version; - this.config = config; - this.locale = locale; - this.theme = theme; - this.dbSystem = dbSystem; - this.serverProperties = serverProperties; - this.formatters = formatters; - this.graphs = graphs; - } - - public NetworkContainer forBungeeContainer(ServerContainer bungeeContainer) { - return new NetworkContainer( - bungeeContainer, - version.get(), - config.get(), - locale.get(), - theme.get(), - dbSystem.get(), - serverProperties.get(), - formatters.get(), - graphs.get() - ); - } - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/PerServerContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/PerServerContainer.java deleted file mode 100644 index 77ddb615d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/PerServerContainer.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.containers; - -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.container.UserInfo; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.keys.PerServerKeys; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; - -import java.util.*; - -/** - * Container for data about a player linked to a single server. - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.store.keys.PerServerKeys For Key objects. - */ -public class PerServerContainer extends HashMap { - - public void putToContainerOfServer(UUID serverUUID, Key key, T value) { - DataContainer container = getOrDefault(serverUUID, new DynamicDataContainer()); - container.putRawData(key, value); - put(serverUUID, container); - } - - public void putUserInfo(UserInfo userInfo) { - UUID serverUUID = userInfo.getServerUUID(); - putToContainerOfServer(serverUUID, PerServerKeys.REGISTERED, userInfo.getRegistered()); - putToContainerOfServer(serverUUID, PerServerKeys.BANNED, userInfo.isBanned()); - putToContainerOfServer(serverUUID, PerServerKeys.OPERATOR, userInfo.isOperator()); - } - - public void putUserInfo(Collection userInformation) { - for (UserInfo userInfo : userInformation) { - putUserInfo(userInfo); - } - } - - public void putCalculatingSuppliers() { - for (DataContainer container : values()) { - container.putSupplier(PerServerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen()); - - container.putSupplier(PerServerKeys.WORLD_TIMES, () -> SessionsMutator.forContainer(container).toTotalWorldTimes()); - container.putSupplier(PerServerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList()); - container.putSupplier(PerServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList()); - container.putSupplier(PerServerKeys.PLAYER_KILL_COUNT, () -> container.getValue(PerServerKeys.PLAYER_KILLS).map(Collection::size).orElse(0)); - container.putSupplier(PerServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount()); - container.putSupplier(PerServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount()); - container.putSupplier(PerServerKeys.PLAYER_DEATH_COUNT, () -> SessionsMutator.forContainer(container).toPlayerDeathCount()); - container.putSupplier(PerServerKeys.MOB_DEATH_COUNT, () -> - container.getValue(PerServerKeys.DEATH_COUNT).orElse(0) - container.getValue(PerServerKeys.PLAYER_DEATH_COUNT).orElse(0) - ); - } - } - - public void putSessions(Collection sessions) { - if (sessions == null) { - return; - } - - for (Session session : sessions) { - putSession(session); - } - } - - private void putSession(Session session) { - if (session == null) { - return; - } - - UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID); - DataContainer container = getOrDefault(serverUUID, new DynamicDataContainer()); - if (!container.supports(PerServerKeys.SESSIONS)) { - container.putRawData(PerServerKeys.SESSIONS, new ArrayList<>()); - } - container.getUnsafe(PerServerKeys.SESSIONS).add(session); - put(serverUUID, container); - } - - public void putPing(List pings) { - if (pings == null) { - return; - } - - for (Ping ping : pings) { - putPing(ping); - } - } - - private void putPing(Ping ping) { - if (ping == null) { - return; - } - - UUID serverUUID = ping.getServerUUID(); - DataContainer container = getOrDefault(serverUUID, new DynamicDataContainer()); - if (!container.supports(PerServerKeys.PING)) { - container.putRawData(PerServerKeys.PING, new ArrayList<>()); - } - container.getUnsafe(PerServerKeys.PING).add(ping); - put(serverUUID, container); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/PlayerContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/PlayerContainer.java deleted file mode 100644 index d8423890c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/PlayerContainer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.containers; - -import com.djrapitops.plan.data.store.mutators.ActivityIndex; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; - -import java.util.HashMap; -import java.util.Map; - -/** - * DataContainer about a Player. - *

- * Use {@code getValue(PlayerKeys.REGISTERED).isPresent()} to determine if Plan has data about the player. - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.store.keys.PlayerKeys For Key objects. - */ -public class PlayerContainer extends DynamicDataContainer { - - private Map activityIndexCache; - - public PlayerContainer() { - activityIndexCache = new HashMap<>(); - } - - public ActivityIndex getActivityIndex(long date, long playtimeMsThreshold, int loginThreshold) { - return activityIndexCache.computeIfAbsent(date, time -> new ActivityIndex(this, time, playtimeMsThreshold, loginThreshold)); - } - - public boolean playedBetween(long after, long before) { - return SessionsMutator.forContainer(this).playedBetween(after, before); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/RawDataContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/RawDataContainer.java deleted file mode 100644 index 842f8e85b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/RawDataContainer.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.containers; - -import com.djrapitops.plan.data.store.Key; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.function.Supplier; - -/** - * DataContainer that stores everything as raw object value. - * - * @author Rsl1122 - */ -public class RawDataContainer implements DataContainer { - - private final Map map; - - /** - * Create a RawDataContainer. - */ - public RawDataContainer() { - map = new HashMap<>(); - } - - @Override - public void putRawData(Key key, T obj) { - if (obj == null) { - return; - } - map.put(key, obj); - } - - @Override - public void putSupplier(Key key, Supplier supplier) { - if (supplier == null) { - return; - } - putRawData(key, supplier.get()); - } - - @Override - public void putCachingSupplier(Key key, Supplier supplier) { - putSupplier(key, supplier); - } - - @Override - public boolean supports(Key key) { - return map.containsKey(key); - } - - @Override - public Optional getValue(Key key) { - try { - return Optional.ofNullable(key.typeCast(map.get(key))); - } catch (ClassCastException e) { - return Optional.empty(); - } - } - - @Override - public T getUnsafe(Key key) { - Object value = map.get(key); - if (value == null) { - throw new IllegalArgumentException("Unsupported Key: " + key.getKeyName()); - } - return key.typeCast(value); - } - - @Override - public void putAll(DataContainer dataContainer) { - if (dataContainer instanceof RawDataContainer) { - putAll(((RawDataContainer) dataContainer).map); - } else { - putAll(dataContainer.getMap()); - } - } - - void putAll(Map map) { - this.map.putAll(map); - } - - @Override - public void clear() { - map.clear(); - } - - @Override - public Map getMap() { - return map; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/ServerContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/ServerContainer.java deleted file mode 100644 index 7328ddf0e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/ServerContainer.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.containers; - -/** - * DataContainer for a single server. - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.store.keys.ServerKeys For Key objects. - */ -public class ServerContainer extends DynamicDataContainer { -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/SupplierDataContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/SupplierDataContainer.java deleted file mode 100644 index b84d6ab6e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/SupplierDataContainer.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.containers; - -import com.djrapitops.plan.data.store.CachingSupplier; -import com.djrapitops.plan.data.store.Key; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; - -/** - * DataContainer implementation that stores everything in {@link Supplier} objects. - * - * @author Rsl1122 - */ -public class SupplierDataContainer implements DataContainer { - - private final Map map; - private long timeToLive; - - /** - * Create a SupplierDataContainer with a default TTL of 30 seconds. - */ - public SupplierDataContainer() { - this(TimeUnit.SECONDS.toMillis(30L)); - } - - /** - * Create a SupplierDataContainer with a custom TTL. - *

- * The old value is not removed from memory until the supplier is called again. - * - * @param timeToLive TTL that determines how long a CachingSupplier value is deemed valid. - */ - public SupplierDataContainer(long timeToLive) { - this.timeToLive = timeToLive; - map = new HashMap<>(); - } - - @Override - public void putRawData(Key key, T obj) { - putSupplier(key, () -> obj); - } - - @Override - public void putSupplier(Key key, Supplier supplier) { - if (supplier == null) { - return; - } - map.put(key, supplier); - } - - @Override - public void putCachingSupplier(Key key, Supplier supplier) { - if (supplier == null) { - return; - } - map.put(key, new CachingSupplier<>(supplier, timeToLive)); - } - - private Supplier getSupplier(Key key) { - return (Supplier) map.get(key); - } - - @Override - public boolean supports(Key key) { - return map.containsKey(key); - } - - @Override - public Optional getValue(Key key) { - Supplier supplier = getSupplier(key); - if (supplier == null) { - return Optional.empty(); - } - try { - return Optional.ofNullable(supplier.get()); - } catch (ClassCastException e) { - return Optional.empty(); - } - } - - @Override - public T getUnsafe(Key key) { - Supplier supplier = map.get(key); - if (supplier == null) { - throw new IllegalArgumentException("Unsupported Key: " + key.getKeyName()); - } - return key.typeCast(supplier.get()); - } - - private void putAll(Map toPut) { - map.putAll(toPut); - } - - @Override - public void putAll(DataContainer dataContainer) { - if (dataContainer instanceof SupplierDataContainer) { - putAll(((SupplierDataContainer) dataContainer).map); - } else { - for (Map.Entry entry : dataContainer.getMap().entrySet()) { - putRawData(entry.getKey(), entry.getValue()); - } - } - } - - @Override - public void clear() { - map.clear(); - } - - @Override - public Map getMap() { - // Fetches all objects from their Suppliers. - Map objectMap = new HashMap<>(); - for (Map.Entry entry : map.entrySet()) { - objectMap.put(entry.getKey(), entry.getValue().get()); - } - return objectMap; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java deleted file mode 100644 index 5194b51bc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.keys; - -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.PlaceholderKey; -import com.djrapitops.plan.data.store.Type; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plan.data.store.mutators.PlayersOnlineResolver; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.mutators.TPSMutator; - -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.UUID; - -/** - * Key objects used for Analysis. - *

- * PlaceholderKey objects can be used for directly replacing a value on the html. - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.store.containers.AnalysisContainer for Suppliers for each Key. - */ -public class AnalysisKeys { - - // Constants (Affected only by config settings) - public static final PlaceholderKey VERSION = CommonPlaceholderKeys.VERSION; - public static final PlaceholderKey SERVER_NAME = new PlaceholderKey<>(String.class, "serverName"); - public static final PlaceholderKey TIME_ZONE = CommonPlaceholderKeys.TIME_ZONE; - public static final PlaceholderKey FIRST_DAY = new PlaceholderKey<>(Integer.class, "firstDay"); - public static final PlaceholderKey TPS_MEDIUM = new PlaceholderKey<>(Integer.class, "tpsMedium"); - public static final PlaceholderKey TPS_HIGH = new PlaceholderKey<>(Integer.class, "tpsHigh"); - public static final PlaceholderKey DISK_MEDIUM = new PlaceholderKey<>(Integer.class, "diskMedium"); - public static final PlaceholderKey DISK_HIGH = new PlaceholderKey<>(Integer.class, "diskHigh"); - public static final PlaceholderKey PLAYERS_MAX = new PlaceholderKey<>(Integer.class, "playersMax"); - public static final PlaceholderKey PLAYERS_ONLINE = CommonPlaceholderKeys.PLAYERS_ONLINE; - public static final PlaceholderKey PLAYERS_TOTAL = CommonPlaceholderKeys.PLAYERS_TOTAL; - // - public static final PlaceholderKey WORLD_PIE_COLORS = new PlaceholderKey<>(String.class, "worldPieColors"); - public static final PlaceholderKey GM_PIE_COLORS = new PlaceholderKey<>(String.class, "gmPieColors"); - public static final PlaceholderKey ACTIVITY_PIE_COLORS = new PlaceholderKey<>(String.class, "activityPieColors"); - public static final PlaceholderKey PLAYERS_GRAPH_COLOR = CommonPlaceholderKeys.PLAYERS_GRAPH_COLOR; - public static final PlaceholderKey TPS_HIGH_COLOR = new PlaceholderKey<>(String.class, "tpsHighColor"); - public static final PlaceholderKey TPS_MEDIUM_COLOR = new PlaceholderKey<>(String.class, "tpsMediumColor"); - public static final PlaceholderKey TPS_LOW_COLOR = new PlaceholderKey<>(String.class, "tpsLowColor"); - public static final PlaceholderKey AVG_PING_COLOR = new PlaceholderKey<>(String.class, "avgPingColor"); - public static final PlaceholderKey MIN_PING_COLOR = new PlaceholderKey<>(String.class, "minPingColor"); - public static final PlaceholderKey MAX_PING_COLOR = new PlaceholderKey<>(String.class, "maxPingColor"); - public static final PlaceholderKey WORLD_MAP_HIGH_COLOR = CommonPlaceholderKeys.WORLD_MAP_HIGH_COLOR; - public static final PlaceholderKey WORLD_MAP_LOW_COLOR = CommonPlaceholderKeys.WORLD_MAP_LOW_COLOR; - - // Tables & other structures - public static final PlaceholderKey PLAYERS_TABLE = new PlaceholderKey<>(String.class, "tablePlayerlist"); - public static final PlaceholderKey SESSION_ACCORDION_HTML = new PlaceholderKey<>(String.class, "accordionSessions"); - public static final PlaceholderKey SESSION_ACCORDION_FUNCTIONS = new PlaceholderKey<>(String.class, "sessionTabGraphViewFunctions"); - public static final PlaceholderKey SESSION_TABLE = new PlaceholderKey<>(String.class, "tableBodySessions"); - public static final PlaceholderKey PING_TABLE = new PlaceholderKey<>(String.class, "tablePing"); - public static final PlaceholderKey RECENT_LOGINS = new PlaceholderKey<>(String.class, "listRecentLogins"); - public static final PlaceholderKey COMMAND_USAGE_TABLE = new PlaceholderKey<>(String.class, "tableCommandUsage"); - public static final PlaceholderKey HEALTH_NOTES = CommonPlaceholderKeys.HEALTH_NOTES; - public static final PlaceholderKey PLUGINS_TAB = new PlaceholderKey<>(String.class, "tabsPlugins"); - public static final PlaceholderKey PLUGINS_TAB_NAV = new PlaceholderKey<>(String.class, "navPluginsTabs"); - // Formatted time values - public static final PlaceholderKey REFRESH_TIME_F = CommonPlaceholderKeys.REFRESH_TIME_F; - public static final PlaceholderKey REFRESH_TIME_FULL_F = CommonPlaceholderKeys.REFRESH_TIME_FULL_F; - public static final PlaceholderKey LAST_PEAK_TIME_F = CommonPlaceholderKeys.LAST_PEAK_TIME_F; - public static final PlaceholderKey ALL_TIME_PEAK_TIME_F = CommonPlaceholderKeys.ALL_TIME_PEAK_TIME_F; - public static final PlaceholderKey AVERAGE_SESSION_LENGTH_F = new PlaceholderKey<>(String.class, "sessionAverage"); - public static final PlaceholderKey AVERAGE_PLAYTIME_F = new PlaceholderKey<>(String.class, "playtimeAverage"); - public static final PlaceholderKey PLAYTIME_F = new PlaceholderKey<>(String.class, "playtimeTotal"); - // Direct values, possibly formatted - public static final PlaceholderKey PLAYERS_LAST_PEAK = CommonPlaceholderKeys.PLAYERS_LAST_PEAK; - public static final PlaceholderKey PLAYERS_ALL_TIME_PEAK = CommonPlaceholderKeys.PLAYERS_ALL_TIME_PEAK; - public static final PlaceholderKey OPERATORS = new PlaceholderKey<>(Integer.class, "ops"); - public static final PlaceholderKey PLAYERS_REGULAR = new PlaceholderKey<>(Integer.class, "playersRegular"); - public static final PlaceholderKey SESSION_COUNT = new PlaceholderKey<>(Integer.class, "sessionCount"); - public static final PlaceholderKey DEATHS = new PlaceholderKey<>(Integer.class, "deaths"); - public static final PlaceholderKey MOB_KILL_COUNT = new PlaceholderKey<>(Integer.class, "mobKillCount"); - public static final PlaceholderKey PLAYER_KILL_COUNT = new PlaceholderKey<>(Integer.class, "killCount"); - public static final PlaceholderKey HEALTH_INDEX = CommonPlaceholderKeys.HEALTH_INDEX; - public static final PlaceholderKey COMMAND_COUNT = new PlaceholderKey<>(Integer.class, "commandCount"); - public static final PlaceholderKey COMMAND_COUNT_UNIQUE = new PlaceholderKey<>(Integer.class, "commandUniqueCount"); - // - public static final PlaceholderKey PLAYERS_DAY = CommonPlaceholderKeys.PLAYERS_DAY; - public static final PlaceholderKey PLAYERS_WEEK = CommonPlaceholderKeys.PLAYERS_WEEK; - public static final PlaceholderKey PLAYERS_MONTH = CommonPlaceholderKeys.PLAYERS_MONTH; - public static final PlaceholderKey PLAYERS_NEW_DAY = CommonPlaceholderKeys.PLAYERS_NEW_DAY; - public static final PlaceholderKey PLAYERS_NEW_WEEK = CommonPlaceholderKeys.PLAYERS_NEW_WEEK; - public static final PlaceholderKey PLAYERS_NEW_MONTH = CommonPlaceholderKeys.PLAYERS_NEW_MONTH; - public static final PlaceholderKey AVG_PLAYERS = new PlaceholderKey<>(Integer.class, "playersAverage"); - public static final PlaceholderKey AVG_PLAYERS_DAY = new PlaceholderKey<>(Integer.class, "playersAverageDay"); - public static final PlaceholderKey AVG_PLAYERS_WEEK = new PlaceholderKey<>(Integer.class, "playersAverageWeek"); - public static final PlaceholderKey AVG_PLAYERS_MONTH = new PlaceholderKey<>(Integer.class, "playersAverageMonth"); - public static final PlaceholderKey AVG_PLAYERS_NEW = new PlaceholderKey<>(Integer.class, "playersNewAverage"); - public static final PlaceholderKey AVG_PLAYERS_NEW_DAY = new PlaceholderKey<>(Integer.class, "playersNewAverageDay"); - public static final PlaceholderKey AVG_PLAYERS_NEW_WEEK = new PlaceholderKey<>(Integer.class, "playersNewAverageWeek"); - public static final PlaceholderKey AVG_PLAYERS_NEW_MONTH = new PlaceholderKey<>(Integer.class, "playersNewAverageMonth"); - public static final PlaceholderKey PLAYERS_RETAINED_DAY = new PlaceholderKey<>(Integer.class, "playersStuckDay"); - public static final PlaceholderKey PLAYERS_RETAINED_DAY_PERC = new PlaceholderKey<>(String.class, "playersStuckPercDay"); - public static final PlaceholderKey PLAYERS_RETAINED_WEEK = new PlaceholderKey<>(Integer.class, "playersStuckWeek"); - public static final PlaceholderKey PLAYERS_RETAINED_WEEK_PERC = new PlaceholderKey<>(String.class, "playersStuckPercWeek"); - public static final PlaceholderKey PLAYERS_RETAINED_MONTH = new PlaceholderKey<>(Integer.class, "playersStuckMonth"); - public static final PlaceholderKey PLAYERS_RETAINED_MONTH_PERC = new PlaceholderKey<>(String.class, "playersStuckPercMonth"); - // - public static final PlaceholderKey TPS_SPIKE_MONTH = new PlaceholderKey<>(Integer.class, "tpsSpikeMonth"); - public static final PlaceholderKey TPS_SPIKE_WEEK = new PlaceholderKey<>(Integer.class, "tpsSpikeWeek"); - public static final PlaceholderKey TPS_SPIKE_DAY = new PlaceholderKey<>(Integer.class, "tpsSpikeDay"); - public static final PlaceholderKey AVG_TPS_MONTH = new PlaceholderKey<>(Double.class, "tpsAverageMonth"); - public static final PlaceholderKey AVG_TPS_WEEK = new PlaceholderKey<>(Double.class, "tpsAverageWeek"); - public static final PlaceholderKey AVG_TPS_DAY = new PlaceholderKey<>(Double.class, "tpsAverageDay"); - public static final PlaceholderKey AVG_CPU_MONTH = new PlaceholderKey<>(Double.class, "cpuAverageMonth"); - public static final PlaceholderKey AVG_CPU_WEEK = new PlaceholderKey<>(Double.class, "cpuAverageWeek"); - public static final PlaceholderKey AVG_CPU_DAY = new PlaceholderKey<>(Double.class, "cpuAverageDay"); - public static final PlaceholderKey AVG_RAM_MONTH = new PlaceholderKey<>(Double.class, "ramAverageMonth"); - public static final PlaceholderKey AVG_RAM_WEEK = new PlaceholderKey<>(Double.class, "ramAverageWeek"); - public static final PlaceholderKey AVG_RAM_DAY = new PlaceholderKey<>(Double.class, "ramAverageDay"); - public static final PlaceholderKey AVG_ENTITY_MONTH = new PlaceholderKey<>(Double.class, "entityAverageMonth"); - public static final PlaceholderKey AVG_ENTITY_WEEK = new PlaceholderKey<>(Double.class, "entityAverageWeek"); - public static final PlaceholderKey AVG_ENTITY_DAY = new PlaceholderKey<>(Double.class, "entityAverageDay"); - public static final PlaceholderKey AVG_CHUNK_MONTH = new PlaceholderKey<>(Double.class, "chunkAverageMonth"); - public static final PlaceholderKey AVG_CHUNK_WEEK = new PlaceholderKey<>(Double.class, "chunkAverageWeek"); - public static final PlaceholderKey AVG_CHUNK_DAY = new PlaceholderKey<>(Double.class, "chunkAverageDay"); - public static final PlaceholderKey AVG_FREE_DISK_MONTH = new PlaceholderKey<>(Double.class, "freeDiskAverageMonth"); - public static final PlaceholderKey AVG_FREE_DISK_WEEK = new PlaceholderKey<>(Double.class, "freeDiskAverageWeek"); - public static final PlaceholderKey AVG_FREE_DISK_DAY = new PlaceholderKey<>(Double.class, "freeDiskAverageDay"); - public static final PlaceholderKey MAX_FREE_DISK_MONTH = new PlaceholderKey<>(Long.class, "freeDiskMaximumMonth"); - public static final PlaceholderKey MAX_FREE_DISK_WEEK = new PlaceholderKey<>(Long.class, "freeDiskMaximumWeek"); - public static final PlaceholderKey MAX_FREE_DISK_DAY = new PlaceholderKey<>(Long.class, "freeDiskMaximumDay"); - public static final PlaceholderKey MIN_FREE_DISK_MONTH = new PlaceholderKey<>(Long.class, "freeDiskMinimumMonth"); - public static final PlaceholderKey MIN_FREE_DISK_WEEK = new PlaceholderKey<>(Long.class, "freeDiskMinimumWeek"); - public static final PlaceholderKey MIN_FREE_DISK_DAY = new PlaceholderKey<>(Long.class, "freeDiskMinimumDay"); - // Data for Charts - public static final PlaceholderKey WORLD_PIE_SERIES = new PlaceholderKey<>(String.class, "worldSeries"); - public static final PlaceholderKey GM_PIE_SERIES = new PlaceholderKey<>(String.class, "gmSeries"); - public static final PlaceholderKey PLAYERS_ONLINE_SERIES = CommonPlaceholderKeys.PLAYERS_ONLINE_SERIES; - public static final PlaceholderKey TPS_SERIES = new PlaceholderKey<>(String.class, "tpsSeries"); - public static final PlaceholderKey CPU_SERIES = new PlaceholderKey<>(String.class, "cpuSeries"); - public static final PlaceholderKey RAM_SERIES = new PlaceholderKey<>(String.class, "ramSeries"); - public static final PlaceholderKey ENTITY_SERIES = new PlaceholderKey<>(String.class, "entitySeries"); - public static final PlaceholderKey CHUNK_SERIES = new PlaceholderKey<>(String.class, "chunkSeries"); - public static final PlaceholderKey DISK_SERIES = new PlaceholderKey<>(String.class, "diskSeries"); - public static final PlaceholderKey PUNCHCARD_SERIES = new PlaceholderKey<>(String.class, "punchCardSeries"); - public static final PlaceholderKey WORLD_MAP_SERIES = CommonPlaceholderKeys.WORLD_MAP_SERIES; - public static final PlaceholderKey ACTIVITY_STACK_SERIES = CommonPlaceholderKeys.ACTIVITY_STACK_SERIES; - public static final PlaceholderKey ACTIVITY_STACK_CATEGORIES = CommonPlaceholderKeys.ACTIVITY_STACK_CATEGORIES; - public static final PlaceholderKey ACTIVITY_PIE_SERIES = CommonPlaceholderKeys.ACTIVITY_PIE_SERIES; - public static final PlaceholderKey CALENDAR_SERIES = new PlaceholderKey<>(String.class, "calendarSeries"); - public static final PlaceholderKey UNIQUE_PLAYERS_SERIES = new PlaceholderKey<>(String.class, "uniquePlayersSeries"); - public static final PlaceholderKey NEW_PLAYERS_SERIES = new PlaceholderKey<>(String.class, "newPlayersSeries"); - public static final PlaceholderKey AVG_PING_SERIES = new PlaceholderKey<>(String.class, "avgPingSeries"); - public static final PlaceholderKey MAX_PING_SERIES = new PlaceholderKey<>(String.class, "maxPingSeries"); - public static final PlaceholderKey MIN_PING_SERIES = new PlaceholderKey<>(String.class, "minPingSeries"); - public static final PlaceholderKey COUNTRY_CATEGORIES = CommonPlaceholderKeys.COUNTRY_CATEGORIES; - public static final PlaceholderKey COUNTRY_SERIES = CommonPlaceholderKeys.COUNTRY_SERIES; - // Variables used only during analysis - public static final Key SESSIONS_MUTATOR = CommonKeys.SESSIONS_MUTATOR; - public static final Key TPS_MUTATOR = CommonKeys.TPS_MUTATOR; - public static final Key PLAYERS_MUTATOR = CommonKeys.PLAYERS_MUTATOR; - public static final Key PLAYERS_ONLINE_RESOLVER = new Key<>(PlayersOnlineResolver.class, "PLAYERS_ONLINE_RESOLVER"); - public static final Key PLAYTIME_TOTAL = new Key<>(Long.class, "PLAYTIME_TOTAL"); - public static final Key ANALYSIS_TIME = new Key<>(Long.class, "ANALYSIS_TIME"); - public static final Key ANALYSIS_TIME_DAY_AGO = new Key<>(Long.class, "ANALYSIS_TIME_DAY_AGO"); - public static final Key ANALYSIS_TIME_WEEK_AGO = new Key<>(Long.class, "ANALYSIS_TIME_WEEK_AGO"); - public static final Key ANALYSIS_TIME_MONTH_AGO = new Key<>(Long.class, "ANALYSIS_TIME_MONTH_AGO"); - public static final Key> PLAYER_NAMES = new Key<>(new Type>() { - }, "PLAYER_NAMES"); - public static final Key>>> ACTIVITY_DATA = CommonKeys.ACTIVITY_DATA; - public static final Key> UNIQUE_PLAYERS_PER_DAY = new Key<>(new Type>() { - }, "UNIQUE_PLAYERS_PER_DAY"); - public static final Key> NEW_PLAYERS_PER_DAY = new Key<>(new Type>() { - }, "NEW_PLAYERS_PER_DAY"); - - private AnalysisKeys() { - /* Static variable class */ - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/CommonKeys.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/CommonKeys.java deleted file mode 100644 index faf53c9be..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/CommonKeys.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.keys; - -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.data.container.PlayerDeath; -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.PlaceholderKey; -import com.djrapitops.plan.data.store.Type; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.mutators.TPSMutator; -import com.djrapitops.plan.data.time.WorldTimes; - -import java.util.*; - -/** - * Class holding Key objects that are commonly used across multiple DataContainers. - * - * @author Rsl1122 - */ -public class CommonKeys { - - private CommonKeys() { - /* Static variable class */ - } - - public static final Key UUID = new Key<>(UUID.class, "uuid"); - public static final Key SERVER_UUID = new Key<>(UUID.class, "server_uuid"); - public static final Key NAME = new Key<>(String.class, "name"); - public static final PlaceholderKey REGISTERED = new PlaceholderKey<>(Long.class, "registered"); - public static final Key> PING = new Key<>(new Type>() {}, "ping"); - - public static final Key> SESSIONS = new Key<>(new Type>() {}, "sessions"); - public static final Key WORLD_TIMES = new Key<>(WorldTimes.class, "world_times"); - public static final PlaceholderKey LAST_SEEN = new PlaceholderKey<>(Long.class, "lastSeen"); - - public static final Key> PLAYER_DEATHS = new Key<>(new Type>() {}, "player_deaths"); - public static final Key> PLAYER_KILLS = new Key<>(new Type>() {}, "player_kills"); - public static final Key PLAYER_KILL_COUNT = new Key<>(Integer.class, "player_kill_count"); - public static final Key PLAYER_DEATH_COUNT = new Key<>(Integer.class, "player_death_count"); - public static final Key MOB_KILL_COUNT = new Key<>(Integer.class, "mob_kill_count"); - public static final Key MOB_DEATH_COUNT = new Key<>(Integer.class, "mob_death_count"); - public static final Key DEATH_COUNT = new Key<>(Integer.class, "death_count"); - - public static final Key BANNED = new Key<>(Boolean.class, "banned"); - public static final Key OPERATOR = new Key<>(Boolean.class, "operator"); - - public static final Key SESSIONS_MUTATOR = new Key<>(SessionsMutator.class, "SESSIONS_MUTATOR"); - public static final Key TPS_MUTATOR = new Key<>(TPSMutator.class, "TPS_MUTATOR"); - public static final Key PLAYERS_MUTATOR = new Key<>(PlayersMutator.class, "PLAYERS_MUTATOR"); - - public static final Key>>> ACTIVITY_DATA = new Key<>(new Type>>>() {}, "ACTIVITY_DATA"); - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/CommonPlaceholderKeys.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/CommonPlaceholderKeys.java deleted file mode 100644 index cb2197833..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/CommonPlaceholderKeys.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.keys; - -import com.djrapitops.plan.data.store.PlaceholderKey; - -/** - * Similar to {@link CommonKeys}, but for {@link com.djrapitops.plan.data.store.PlaceholderKey}s. - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.store.PlaceholderKey for placeholder information - */ -class CommonPlaceholderKeys { - - static final PlaceholderKey VERSION = new PlaceholderKey<>(String.class, "version"); - static final PlaceholderKey TIME_ZONE = new PlaceholderKey<>(Integer.class, "timeZone"); - static final PlaceholderKey PLAYERS_GRAPH_COLOR = new PlaceholderKey<>(String.class, "playersGraphColor"); - static final PlaceholderKey PLAYERS_ONLINE_SERIES = new PlaceholderKey<>(String.class, "playersOnlineSeries"); - static final PlaceholderKey WORLD_MAP_HIGH_COLOR = new PlaceholderKey<>(String.class, "worldMapColHigh"); - static final PlaceholderKey WORLD_MAP_LOW_COLOR = new PlaceholderKey<>(String.class, "worldMapColLow"); - static final PlaceholderKey PLAYERS_ONLINE = new PlaceholderKey<>(Integer.class, "playersOnline"); - static final PlaceholderKey PLAYERS_TOTAL = new PlaceholderKey<>(Integer.class, "playersTotal"); - static final PlaceholderKey WORLD_MAP_SERIES = new PlaceholderKey<>(String.class, "geoMapSeries"); - static final PlaceholderKey ACTIVITY_STACK_SERIES = new PlaceholderKey<>(String.class, "activityStackSeries"); - static final PlaceholderKey ACTIVITY_STACK_CATEGORIES = new PlaceholderKey<>(String.class, "activityStackCategories"); - static final PlaceholderKey ACTIVITY_PIE_SERIES = new PlaceholderKey<>(String.class, "activityPieSeries"); - static final PlaceholderKey COUNTRY_CATEGORIES = new PlaceholderKey<>(String.class, "countryCategories"); - static final PlaceholderKey COUNTRY_SERIES = new PlaceholderKey<>(String.class, "countrySeries"); - - static final PlaceholderKey HEALTH_NOTES = new PlaceholderKey<>(String.class, "healthNotes"); - static final PlaceholderKey HEALTH_INDEX = new PlaceholderKey<>(Double.class, "healthIndex"); - - static final PlaceholderKey PLAYERS_DAY = new PlaceholderKey<>(Integer.class, "playersDay"); - static final PlaceholderKey PLAYERS_WEEK = new PlaceholderKey<>(Integer.class, "playersWeek"); - static final PlaceholderKey PLAYERS_MONTH = new PlaceholderKey<>(Integer.class, "playersMonth"); - static final PlaceholderKey PLAYERS_NEW_DAY = new PlaceholderKey<>(Integer.class, "playersNewDay"); - static final PlaceholderKey PLAYERS_NEW_WEEK = new PlaceholderKey<>(Integer.class, "playersNewWeek"); - static final PlaceholderKey PLAYERS_NEW_MONTH = new PlaceholderKey<>(Integer.class, "playersNewMonth"); - - static final PlaceholderKey REFRESH_TIME_F = new PlaceholderKey<>(String.class, "refresh"); - static final PlaceholderKey REFRESH_TIME_FULL_F = new PlaceholderKey<>(String.class, "refreshFull"); - static final PlaceholderKey LAST_PEAK_TIME_F = new PlaceholderKey<>(String.class, "lastPeakTime"); - static final PlaceholderKey ALL_TIME_PEAK_TIME_F = new PlaceholderKey<>(String.class, "bestPeakTime"); - static final PlaceholderKey PLAYERS_LAST_PEAK = new PlaceholderKey<>(String.class, "playersLastPeak"); - static final PlaceholderKey PLAYERS_ALL_TIME_PEAK = new PlaceholderKey<>(String.class, "playersBestPeak"); - - private CommonPlaceholderKeys() { - /* static variable class */ - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/NetworkKeys.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/NetworkKeys.java deleted file mode 100644 index 50421cddd..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/NetworkKeys.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.keys; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.PlaceholderKey; -import com.djrapitops.plan.data.store.Type; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plan.system.info.server.Server; - -import java.util.*; - -/** - * Key objects for {@link com.djrapitops.plan.data.store.containers.NetworkContainer}. - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.store.containers.NetworkContainer for DataContainer. - */ -public class NetworkKeys { - - public static final PlaceholderKey VERSION = CommonPlaceholderKeys.VERSION; - public static final PlaceholderKey NETWORK_NAME = new PlaceholderKey<>(String.class, "networkName"); - public static final PlaceholderKey TIME_ZONE = CommonPlaceholderKeys.TIME_ZONE; - public static final PlaceholderKey PLAYERS_ONLINE = CommonPlaceholderKeys.PLAYERS_ONLINE; - public static final PlaceholderKey PLAYERS_TOTAL = CommonPlaceholderKeys.PLAYERS_TOTAL; - public static final PlaceholderKey PLAYERS_GRAPH_COLOR = CommonPlaceholderKeys.PLAYERS_GRAPH_COLOR; - public static final PlaceholderKey WORLD_MAP_HIGH_COLOR = CommonPlaceholderKeys.WORLD_MAP_HIGH_COLOR; - public static final PlaceholderKey WORLD_MAP_LOW_COLOR = CommonPlaceholderKeys.WORLD_MAP_LOW_COLOR; - - public static final PlaceholderKey REFRESH_TIME_F = CommonPlaceholderKeys.REFRESH_TIME_F; - public static final PlaceholderKey RECENT_PEAK_TIME_F = CommonPlaceholderKeys.LAST_PEAK_TIME_F; - public static final PlaceholderKey ALL_TIME_PEAK_TIME_F = CommonPlaceholderKeys.ALL_TIME_PEAK_TIME_F; - public static final PlaceholderKey PLAYERS_RECENT_PEAK = CommonPlaceholderKeys.PLAYERS_LAST_PEAK; - public static final PlaceholderKey PLAYERS_ALL_TIME_PEAK = CommonPlaceholderKeys.PLAYERS_ALL_TIME_PEAK; - public static final PlaceholderKey PLAYERS_DAY = CommonPlaceholderKeys.PLAYERS_DAY; - public static final PlaceholderKey PLAYERS_WEEK = CommonPlaceholderKeys.PLAYERS_WEEK; - public static final PlaceholderKey PLAYERS_MONTH = CommonPlaceholderKeys.PLAYERS_MONTH; - public static final PlaceholderKey PLAYERS_NEW_DAY = CommonPlaceholderKeys.PLAYERS_NEW_DAY; - public static final PlaceholderKey PLAYERS_NEW_WEEK = CommonPlaceholderKeys.PLAYERS_NEW_WEEK; - public static final PlaceholderKey PLAYERS_NEW_MONTH = CommonPlaceholderKeys.PLAYERS_NEW_MONTH; - - public static final PlaceholderKey SERVERS_TAB = new PlaceholderKey<>(String.class, "tabContentServers"); - public static final PlaceholderKey WORLD_MAP_SERIES = CommonPlaceholderKeys.WORLD_MAP_SERIES; - public static final PlaceholderKey PLAYERS_ONLINE_SERIES = CommonPlaceholderKeys.PLAYERS_ONLINE_SERIES; - public static final PlaceholderKey ACTIVITY_STACK_SERIES = CommonPlaceholderKeys.ACTIVITY_STACK_SERIES; - public static final PlaceholderKey ACTIVITY_STACK_CATEGORIES = CommonPlaceholderKeys.ACTIVITY_STACK_CATEGORIES; - public static final PlaceholderKey ACTIVITY_PIE_SERIES = CommonPlaceholderKeys.ACTIVITY_PIE_SERIES; - public static final PlaceholderKey COUNTRY_CATEGORIES = CommonPlaceholderKeys.COUNTRY_CATEGORIES; - public static final PlaceholderKey COUNTRY_SERIES = CommonPlaceholderKeys.COUNTRY_SERIES; - public static final PlaceholderKey HEALTH_INDEX = CommonPlaceholderKeys.HEALTH_INDEX; - public static final PlaceholderKey HEALTH_NOTES = CommonPlaceholderKeys.HEALTH_NOTES; - - public static final Key REFRESH_TIME = new Key<>(Long.class, "REFRESH_TIME"); - public static final Key REFRESH_TIME_DAY_AGO = new Key<>(Long.class, "REFRESH_TIME_DAY_AGO"); - public static final Key REFRESH_TIME_WEEK_AGO = new Key<>(Long.class, "REFRESH_TIME_WEEK_AGO"); - public static final Key REFRESH_TIME_MONTH_AGO = new Key<>(Long.class, "REFRESH_TIME_MONTH_AGO"); - public static final Key PLAYERS_MUTATOR = CommonKeys.PLAYERS_MUTATOR; - - public static final Key> BUKKIT_SERVERS = new Key<>(new Type>() {}, "BUKKIT_SERVERS"); - public static final Key>>> ACTIVITY_DATA = CommonKeys.ACTIVITY_DATA; - public static final Key>> NETWORK_PLAYER_ONLINE_DATA = new Key<>(new Type>>() {}, "NETWORK_PLAYER_ONLINE_DATA"); - @Deprecated - public static final Key> SERVER_REGISTER_DATA = new Key<>(new Type>() {}, "SERVER_REGISTER_DATA"); - - private NetworkKeys() { - /* static variable class */ - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/PerServerKeys.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/PerServerKeys.java deleted file mode 100644 index e907a7e5b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/PerServerKeys.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.keys; - -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.data.container.PlayerDeath; -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.time.WorldTimes; - -import java.util.List; - -/** - * Key objects for PerServerContainer container. - * - * @author Rsl1122 - * @see com.djrapitops.plan.db.access.queries.containers.PerServerContainerQuery For Suppliers for each key - * @see PerServerContainer For the DataContainer. - */ -public class PerServerKeys { - - private PerServerKeys() { - /* Static variable class */ - } - - public static final Key REGISTERED = CommonKeys.REGISTERED; - public static final Key> PING = CommonKeys.PING; - - public static final Key> SESSIONS = CommonKeys.SESSIONS; - public static final Key WORLD_TIMES = CommonKeys.WORLD_TIMES; - - @Deprecated - public static final Key> PLAYER_KILLS = CommonKeys.PLAYER_KILLS; - @Deprecated - public static final Key> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS; - public static final Key PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT; - public static final Key PLAYER_DEATH_COUNT = CommonKeys.PLAYER_DEATH_COUNT; - public static final Key MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT; - public static final Key MOB_DEATH_COUNT = CommonKeys.MOB_DEATH_COUNT; - public static final Key DEATH_COUNT = CommonKeys.DEATH_COUNT; - public static final Key LAST_SEEN = CommonKeys.LAST_SEEN; - - public static final Key BANNED = CommonKeys.BANNED; - public static final Key OPERATOR = CommonKeys.OPERATOR; - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/PlayerKeys.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/PlayerKeys.java deleted file mode 100644 index 6cd87ac9e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/PlayerKeys.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.keys; - -import com.djrapitops.plan.data.container.*; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.PlaceholderKey; -import com.djrapitops.plan.data.store.Type; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.data.time.WorldTimes; - -import java.util.List; -import java.util.UUID; - -/** - * Class that holds Key objects for PlayerContainer. - * - * @author Rsl1122 - * @see com.djrapitops.plan.system.database.databases.sql.operation.SQLFetchOps For Suppliers for each key - * @see com.djrapitops.plan.data.store.containers.PlayerContainer For DataContainer. - */ -public class PlayerKeys { - - private PlayerKeys() { - /* Static variable class */ - } - - public static final Key UUID = CommonKeys.UUID; - public static final Key NAME = CommonKeys.NAME; - public static final Key> NICKNAMES = new Key<>(new Type>() {}, "nicknames"); - - public static final PlaceholderKey REGISTERED = CommonKeys.REGISTERED; - - public static final Key KICK_COUNT = new Key<>(Integer.class, "kick_count"); - public static final Key> GEO_INFO = new Key<>(new Type>() {}, "geo_info"); - public static final Key> PING = CommonKeys.PING; - - public static final Key ACTIVE_SESSION = new Key<>(Session.class, "active_session"); - public static final Key> SESSIONS = CommonKeys.SESSIONS; - public static final Key WORLD_TIMES = CommonKeys.WORLD_TIMES; - - public static final Key> PLAYER_KILLS = CommonKeys.PLAYER_KILLS; - public static final Key> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS; - public static final Key PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT; - public static final Key MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT; - public static final Key DEATH_COUNT = CommonKeys.DEATH_COUNT; - public static final Key PER_SERVER = new Key<>(PerServerContainer.class, "per_server_data"); - public static final PlaceholderKey LAST_SEEN = CommonKeys.LAST_SEEN; - - public static final Key BANNED = CommonKeys.BANNED; - public static final Key OPERATOR = CommonKeys.OPERATOR; - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/ServerKeys.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/ServerKeys.java deleted file mode 100644 index 40009c56f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/ServerKeys.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.keys; - -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.Type; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.objects.DateObj; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * Keys for the ServerContainer. - * - * @author Rsl1122 - * @see com.djrapitops.plan.system.database.databases.sql.operation.SQLFetchOps For Suppliers for each key - * @see com.djrapitops.plan.data.store.containers.ServerContainer For DataContainer. - */ -public class ServerKeys { - - private ServerKeys() { - /* Static variable class */ - } - - public static final Key SERVER_UUID = CommonKeys.SERVER_UUID; - public static final Key NAME = CommonKeys.NAME; - - public static final Key> PLAYERS = new Key<>(new Type>() {}, "players"); - public static final Key> OPERATORS = new Key<>(new Type>() {}, "operators"); - public static final Key PLAYER_COUNT = new Key<>(Integer.class, "player_count"); - - public static final Key> SESSIONS = CommonKeys.SESSIONS; - public static final Key> PING = CommonKeys.PING; - public static final Key WORLD_TIMES = CommonKeys.WORLD_TIMES; - - public static final Key> PLAYER_KILLS = CommonKeys.PLAYER_KILLS; - public static final Key PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT; - public static final Key MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT; - public static final Key DEATH_COUNT = CommonKeys.DEATH_COUNT; - - public static final Key> TPS = new Key<>(new Type>() {}, "tps"); - public static final Key> ALL_TIME_PEAK_PLAYERS = new Key<>(new Type>() {}, "all_time_peak_players"); - public static final Key> RECENT_PEAK_PLAYERS = new Key<>(new Type>() {}, "recent_peak_players"); - public static final Key> COMMAND_USAGE = new Key<>(new Type>() {}, "command_usage"); - public static final Key> EXTENSION_DATA = new Key<>(new Type>() {}, "extension_data"); -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java deleted file mode 100644 index 9315770dd..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.keys; - -import com.djrapitops.plan.data.container.PlayerDeath; -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.time.WorldTimes; - -import java.util.List; -import java.util.UUID; - -/** - * Class holding Key objects for Session (DataContainer). - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.container.Session for DataContainer. - */ -public class SessionKeys { - - public static final Key DB_ID = new Key<>(Integer.class, "db_id"); - public static final Key UUID = CommonKeys.UUID; - public static final Key SERVER_UUID = CommonKeys.SERVER_UUID; - - public static final Key START = new Key<>(Long.class, "start"); - public static final Key END = new Key<>(Long.class, "end"); - public static final Key LENGTH = new Key<>(Long.class, "length"); - public static final Key AFK_TIME = new Key<>(Long.class, "afk_time"); - public static final Key ACTIVE_TIME = new Key<>(Long.class, "active_time"); - public static final Key WORLD_TIMES = CommonKeys.WORLD_TIMES; - public static final Key> PLAYER_KILLS = CommonKeys.PLAYER_KILLS; - public static final Key PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT; - public static final Key MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT; - public static final Key DEATH_COUNT = CommonKeys.DEATH_COUNT; - @Deprecated - public static final Key> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS; - - @Deprecated - public static final Key LONGEST_WORLD_PLAYED = new Key<>(String.class, "longest_world_played"); - - private SessionKeys() { - /* Static variable class */ - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/ActivityIndex.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/ActivityIndex.java deleted file mode 100644 index b372d6e1a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/ActivityIndex.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plugin.api.TimeAmount; - -import java.util.List; -import java.util.Optional; - -public class ActivityIndex { - - private final double value; - - private final long playtimeMsThreshold; - private final int loginThreshold; - - public ActivityIndex( - DataContainer container, long date, - long playtimeMsThreshold, int loginThreshold - ) { - this.playtimeMsThreshold = playtimeMsThreshold; - this.loginThreshold = loginThreshold; - - value = calculate(container, date); - } - - public static String[] getGroups() { - return new String[]{"Very Active", "Active", "Regular", "Irregular", "Inactive"}; - } - - private double calculate(DataContainer container, long date) { - long week = TimeAmount.WEEK.toMillis(1L); - long weekAgo = date - week; - long twoWeeksAgo = date - 2L * week; - long threeWeeksAgo = date - 3L * week; - - long activePlayThreshold = playtimeMsThreshold; - int activeLoginThreshold = loginThreshold; - - Optional> sessionsValue = container.getValue(PlayerKeys.SESSIONS); - if (!sessionsValue.isPresent()) { - return 0.0; - } - SessionsMutator sessionsMutator = new SessionsMutator(sessionsValue.get()); - if (sessionsMutator.all().isEmpty()) { - return 0.0; - } - - SessionsMutator weekOne = sessionsMutator.filterSessionsBetween(weekAgo, date); - SessionsMutator weekTwo = sessionsMutator.filterSessionsBetween(twoWeeksAgo, weekAgo); - SessionsMutator weekThree = sessionsMutator.filterSessionsBetween(threeWeeksAgo, twoWeeksAgo); - - // Playtime per week multipliers, max out to avoid too high values. - double max = 4.0; - - long playtimeWeek = weekOne.toActivePlaytime(); - double weekPlay = (playtimeWeek * 1.0 / activePlayThreshold); - if (weekPlay > max) { - weekPlay = max; - } - long playtimeWeek2 = weekTwo.toActivePlaytime(); - double week2Play = (playtimeWeek2 * 1.0 / activePlayThreshold); - if (week2Play > max) { - week2Play = max; - } - long playtimeWeek3 = weekThree.toActivePlaytime(); - double week3Play = (playtimeWeek3 * 1.0 / activePlayThreshold); - if (week3Play > max) { - week3Play = max; - } - - double playtimeMultiplier = 1.0; - if (playtimeWeek + playtimeWeek2 + playtimeWeek3 > activePlayThreshold * 3.0) { - playtimeMultiplier = 1.25; - } - - // Reduce the harshness for new players and players who have had a vacation - if (weekPlay > 1 && week3Play > 1 && week2Play == 0.0) { - week2Play = 0.5; - } - if (weekPlay > 1 && week2Play == 0.0) { - week2Play = 0.6; - } - if (weekPlay > 1 && week3Play == 0.0) { - week3Play = 0.75; - } - - double playAvg = (weekPlay + week2Play + week3Play) / 3.0; - - double weekLogin = weekOne.count() >= activeLoginThreshold ? 1.0 : 0.5; - double week2Login = weekTwo.count() >= activeLoginThreshold ? 1.0 : 0.5; - double week3Login = weekThree.count() >= activeLoginThreshold ? 1.0 : 0.5; - - double loginMultiplier = 1.0; - double loginTotal = weekLogin + week2Login + week3Login; - double loginAvg = loginTotal / 3.0; - - if (loginTotal <= 2.0) { - // Reduce index for players that have not logged in the threshold amount for 2 weeks - loginMultiplier = 0.75; - } - - return playAvg * loginAvg * loginMultiplier * playtimeMultiplier; - } - - public double getValue() { - return value; - } - - public String getFormattedValue(Formatter formatter) { - return formatter.apply(value); - } - - public String getGroup() { - if (value >= 3.5) { - return "Very Active"; - } else if (value >= 1.75) { - return "Active"; - } else if (value >= 1.0) { - return "Regular"; - } else if (value >= 0.5) { - return "Irregular"; - } else { - return "Inactive"; - } - } - - public String getColor() { - if (value >= 3.5) { - return "green"; - } else if (value >= 1.75) { - return "green"; - } else if (value >= 1.0) { - return "lime"; - } else if (value >= 0.5) { - return "amber"; - } else { - return "blue-gray"; - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/CommandUseMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/CommandUseMutator.java deleted file mode 100644 index 11dca3d32..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/CommandUseMutator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.keys.ServerKeys; - -import java.util.HashMap; -import java.util.Map; - -/** - * Mutator for Command Usage Map objects. - *

- * Can be used to easily get different values about the map. - * - * @author Rsl1122 - */ -public class CommandUseMutator { - - private Map commandUsage; - - public CommandUseMutator(Map commandUsage) { - this.commandUsage = commandUsage; - } - - public static CommandUseMutator forContainer(DataContainer container) { - return new CommandUseMutator(container.getValue(ServerKeys.COMMAND_USAGE).orElse(new HashMap<>())); - } - - public int commandUsageCount() { - int total = 0; - for (Integer value : commandUsage.values()) { - total += value; - } - return total; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/DateHoldersMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/DateHoldersMutator.java deleted file mode 100644 index d6e98a8af..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/DateHoldersMutator.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.store.objects.DateHolder; - -import java.util.*; -import java.util.concurrent.TimeUnit; - -public class DateHoldersMutator { - - private final List dateHolders; - - public DateHoldersMutator(List dateHolders) { - this.dateHolders = dateHolders; - } - - public SortedMap> groupByStartOfMinute() { - TreeMap> map = new TreeMap<>(); - - if (dateHolders.isEmpty()) { - return map; - } - - long sectionLenght = TimeUnit.MINUTES.toMillis(1L); - for (T holder : dateHolders) { - long date = holder.getDate(); - long startOfSection = date - (date % sectionLenght); - - List list = map.getOrDefault(startOfSection, new ArrayList<>()); - list.add(holder); - map.put(startOfSection, list); - } - return map; - } - - public SortedMap> groupByStartOfDay(TimeZone timeZone) { - long twentyFourHours = TimeUnit.DAYS.toMillis(1L); - TreeMap> map = new TreeMap<>(); - - if (dateHolders.isEmpty()) { - return map; - } - - for (T holder : dateHolders) { - long date = holder.getDate(); - long dateWithOffset = date + timeZone.getOffset(date); - long startOfSection = dateWithOffset - (dateWithOffset % twentyFourHours); - - List list = map.getOrDefault(startOfSection, new ArrayList<>()); - list.add(holder); - map.put(startOfSection, list); - } - - // Empty map firstKey attempt causes NPE if not checked. - if (!map.isEmpty()) { - // Add missing in-between dates - long start = map.firstKey(); - long now = System.currentTimeMillis(); - long end = now - (now % twentyFourHours); - for (long date = start; date < end; date += twentyFourHours) { - map.putIfAbsent(date, new ArrayList<>()); - } - } - return map; - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/GeoInfoMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/GeoInfoMutator.java deleted file mode 100644 index 45e8f10e3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/GeoInfoMutator.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.utilities.comparators.GeoInfoComparator; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -/** - * Mutator for lists of GeoInfo objects. - * - * @author Rsl1122 - * @see GeoInfo for the object. - */ -public class GeoInfoMutator { - - private final List geoInfo; - - public static GeoInfoMutator forContainer(DataContainer container) { - return new GeoInfoMutator(container.getValue(PlayerKeys.GEO_INFO).orElse(new ArrayList<>())); - } - - public GeoInfoMutator(List geoInfo) { - this.geoInfo = geoInfo; - } - - public GeoInfoMutator forCollection(Collection collection) { - return new GeoInfoMutator(new ArrayList<>(collection)); - } - - public Optional mostRecent() { - if (geoInfo.isEmpty()) { - return Optional.empty(); - } - return geoInfo.stream().min(new GeoInfoComparator()); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/MutatorFunctions.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/MutatorFunctions.java deleted file mode 100644 index 21b802369..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/MutatorFunctions.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.utilities.html.graphs.line.Point; - -import java.util.List; -import java.util.Map; -import java.util.NavigableMap; -import java.util.TimeZone; -import java.util.stream.Collectors; - -public class MutatorFunctions { - - public static List toPoints(NavigableMap map) { - return map.entrySet().stream() - .map(entry -> new Point(entry.getKey(), entry.getValue())) - .collect(Collectors.toList()); - } - - public static List toPointsWithRemovedOffset(NavigableMap map, TimeZone timeZone) { - return map.entrySet().stream() - .map(entry -> new Point(entry.getKey() - timeZone.getOffset(entry.getKey()), entry.getValue())) - .collect(Collectors.toList()); - } - - public static int average(Map map) { - return (int) map.values().stream() - .mapToInt(i -> i) - .average().orElse(0); - } - - private MutatorFunctions() { - // Static method class. - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/NetworkPerServerMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/NetworkPerServerMutator.java deleted file mode 100644 index be04820a2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/NetworkPerServerMutator.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.CommonKeys; -import com.djrapitops.plan.data.store.keys.PlayerKeys; - -import java.util.*; - -public class NetworkPerServerMutator { - - private final Map> perServerContainers; - - public NetworkPerServerMutator(PlayersMutator playersMutator) { - this.perServerContainers = perServerContainers(playersMutator); - } - - public static NetworkPerServerMutator forContainer(DataContainer container) { - return new NetworkPerServerMutator( - container.getValue(CommonKeys.PLAYERS_MUTATOR) - .orElse(PlayersMutator.forContainer(container)) - ); - } - - public Map> getPerServerContainers() { - return perServerContainers; - } - - private Map> perServerContainers(PlayersMutator playersMutator) { - Map> dataContainerMap = new HashMap<>(); - - for (PlayerContainer playerContainer : playersMutator.all()) { - UUID uuid = playerContainer.getUnsafe(PlayerKeys.UUID); - PerServerContainer perServerContainer = playerContainer.getValue(PlayerKeys.PER_SERVER).orElse(new PerServerContainer()); - for (Map.Entry entry : perServerContainer.entrySet()) { - UUID serverUUID = entry.getKey(); - DataContainer container = entry.getValue(); - container.putRawData(PlayerKeys.UUID, uuid); - List dataContainers = dataContainerMap.getOrDefault(serverUUID, new ArrayList<>()); - dataContainers.add(container); - dataContainerMap.put(serverUUID, dataContainers); - } - } - - return dataContainerMap; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PerServerMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PerServerMutator.java deleted file mode 100644 index 2062ac002..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PerServerMutator.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.store.keys.PerServerKeys; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.time.WorldTimes; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * Mutator for PerServerContainer object. - * - * @author Rsl1122 - */ -public class PerServerMutator { - - private final PerServerContainer data; - - public PerServerMutator(PerServerContainer data) { - this.data = data; - } - - public static PerServerMutator forContainer(DataContainer container) { - return new PerServerMutator(container.getValue(PlayerKeys.PER_SERVER).orElse(new PerServerContainer())); - } - - public List flatMapSessions() { - return data.values().stream() - .filter(container -> container.supports(PerServerKeys.SESSIONS)) - .map(container -> container.getValue(PerServerKeys.SESSIONS).orElse(Collections.emptyList())) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } - - public WorldTimes flatMapWorldTimes() { - WorldTimes total = new WorldTimes(); - - for (DataContainer container : data.values()) { - if (container.supports(PerServerKeys.WORLD_TIMES)) { - WorldTimes worldTimes = container.getUnsafe(PerServerKeys.WORLD_TIMES); - total.add(worldTimes); - } - } - - return total; - } - - public Map worldTimesPerServer() { - Map timesMap = new HashMap<>(); - for (Map.Entry entry : data.entrySet()) { - DataContainer container = entry.getValue(); - timesMap.put(entry.getKey(), container.getValue(PerServerKeys.WORLD_TIMES).orElse(new WorldTimes())); - } - return timesMap; - } - - public UUID favoriteServer() { - long max = 0; - UUID maxServer = null; - - for (Map.Entry entry : data.entrySet()) { - long total = SessionsMutator.forContainer(entry.getValue()).toPlaytime(); - if (total > max) { - max = total; - maxServer = entry.getKey(); - } - } - - return maxServer; - } - - public Map> sessionsPerServer() { - Map> sessionMap = new HashMap<>(); - for (Map.Entry entry : data.entrySet()) { - sessionMap.put(entry.getKey(), entry.getValue().getValue(PerServerKeys.SESSIONS).orElse(new ArrayList<>())); - } - return sessionMap; - } - - public boolean isBanned() { - for (DataContainer container : data.values()) { - if (container.getValue(PlayerKeys.BANNED).orElse(false)) { - return true; - } - } - return false; - } - - public boolean isOperator() { - for (DataContainer container : data.values()) { - if (container.getValue(PlayerKeys.OPERATOR).orElse(false)) { - return true; - } - } - return false; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PingMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PingMutator.java deleted file mode 100644 index 4cb5f62cb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PingMutator.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.keys.CommonKeys; - -import java.util.ArrayList; -import java.util.List; -import java.util.SortedMap; -import java.util.UUID; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -public class PingMutator { - - private final List pings; - - public PingMutator(List pings) { - this.pings = pings; - } - - public static PingMutator forContainer(DataContainer container) { - return new PingMutator(container.getValue(CommonKeys.PING).orElse(new ArrayList<>())); - } - - public PingMutator filterBy(Predicate predicate) { - return new PingMutator(pings.stream().filter(predicate).collect(Collectors.toList())); - } - - public PingMutator filterByServer(UUID serverUUID) { - return filterBy(ping -> serverUUID.equals(ping.getServerUUID())); - } - - public PingMutator mutateToByMinutePings() { - DateHoldersMutator dateMutator = new DateHoldersMutator<>(pings); - SortedMap> byStartOfMinute = dateMutator.groupByStartOfMinute(); - - return new PingMutator(byStartOfMinute.entrySet().stream() - .map(entry -> { - PingMutator mutator = new PingMutator(entry.getValue()); - - return new Ping(entry.getKey(), null, - mutator.min(), mutator.max(), mutator.average()); - }).collect(Collectors.toList())); - } - - public List all() { - return pings; - } - - public int max() { - int max = -1; - for (Ping ping : pings) { - Integer value = ping.getMax(); - if (value <= 0 || 4000 < value) { - continue; - } - if (value > max) { - max = value; - } - } - - return max; - } - - public int min() { - int min = -1; - for (Ping ping : pings) { - Integer value = ping.getMin(); - if (value <= 0 || 4000 < value) { - continue; - } - if (value < min || min == -1) { - min = value; - } - } - - return min; - } - - public double average() { - return pings.stream().mapToDouble(Ping::getAverage) - .filter(value -> value > 0 && value <= 4000) - .average().orElse(-1); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java deleted file mode 100644 index 1b1d60b36..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.objects.DateObj; -import com.djrapitops.plugin.api.TimeAmount; - -import java.util.*; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -/** - * Mutator for a bunch of {@link com.djrapitops.plan.data.store.containers.PlayerContainer}s. - * - * @author Rsl1122 - */ -public class PlayersMutator { - - private List players; - - public PlayersMutator(List players) { - this.players = players; - } - - public static PlayersMutator copyOf(PlayersMutator mutator) { - return new PlayersMutator(new ArrayList<>(mutator.players)); - } - - public static PlayersMutator forContainer(DataContainer container) { - return new PlayersMutator(container.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>())); - } - - public > PlayersMutator filterBy(T by) { - return new PlayersMutator(players.stream().filter(by).collect(Collectors.toList())); - } - - public PlayersMutator filterPlayedBetween(long after, long before) { - return filterBy( - player -> player.getValue(PlayerKeys.SESSIONS) - .map(sessions -> sessions.stream().anyMatch(session -> { - long start = session.getValue(SessionKeys.START).orElse(-1L); - long end = session.getValue(SessionKeys.END).orElse(-1L); - return (after <= start && start <= before) || (after <= end && end <= before); - })).orElse(false) - ); - } - - public PlayersMutator filterRegisteredBetween(long after, long before) { - return filterBy( - player -> player.getValue(PlayerKeys.REGISTERED) - .map(date -> after <= date && date <= before).orElse(false) - ); - } - - public PlayersMutator filterRetained(long after, long before) { - return filterBy( - player -> { - long backLimit = Math.max(after, player.getValue(PlayerKeys.REGISTERED).orElse(0L)); - long half = backLimit + ((before - backLimit) / 2L); - SessionsMutator sessionsMutator = SessionsMutator.forContainer(player); - return sessionsMutator.playedBetween(backLimit, half) && - sessionsMutator.playedBetween(half, before); - } - ); - } - - public PlayersMutator filterActive(long date, long msThreshold, int loginThreshold, double limit) { - return filterBy(player -> player.getActivityIndex(date, msThreshold, loginThreshold).getValue() >= limit); - } - - public PlayersMutator filterPlayedOnServer(UUID serverUUID) { - return filterBy(player -> !SessionsMutator.forContainer(player) - .filterPlayedOnServer(serverUUID) - .all().isEmpty() - ); - } - - public List all() { - return players; - } - - public List registerDates() { - List registerDates = new ArrayList<>(); - for (PlayerContainer player : players) { - registerDates.add(player.getValue(PlayerKeys.REGISTERED).orElse(-1L)); - } - return registerDates; - } - - public List getGeolocations() { - List geolocations = new ArrayList<>(); - - for (PlayerContainer player : players) { - Optional mostRecent = GeoInfoMutator.forContainer(player).mostRecent(); - geolocations.add(mostRecent.map(GeoInfo::getGeolocation).orElse("Unknown")); - } - - return geolocations; - } - - public Map> getPingPerCountry(UUID serverUUID) { - Map> pingPerCountry = new HashMap<>(); - for (PlayerContainer player : players) { - Optional mostRecent = GeoInfoMutator.forContainer(player).mostRecent(); - if (!mostRecent.isPresent()) { - continue; - } - List pings = player.getValue(PlayerKeys.PING).orElse(new ArrayList<>()); - String country = mostRecent.get().getGeolocation(); - List countryPings = pingPerCountry.getOrDefault(country, new ArrayList<>()); - pings.stream() - .filter(ping -> ping.getServerUUID().equals(serverUUID)) - .forEach(countryPings::add); - pingPerCountry.put(country, countryPings); - } - - return pingPerCountry; - } - - public TreeMap>> toActivityDataMap(long date, long msThreshold, int loginThreshold) { - TreeMap>> activityData = new TreeMap<>(); - for (long time = date; time >= date - TimeAmount.MONTH.toMillis(2L); time -= TimeAmount.WEEK.toMillis(1L)) { - Map> map = activityData.getOrDefault(time, new HashMap<>()); - if (!players.isEmpty()) { - for (PlayerContainer player : players) { - if (player.getValue(PlayerKeys.REGISTERED).orElse(0L) > time) { - continue; - } - ActivityIndex activityIndex = player.getActivityIndex(time, msThreshold, loginThreshold); - String activityGroup = activityIndex.getGroup(); - - Set uuids = map.getOrDefault(activityGroup, new HashSet<>()); - uuids.add(player.getUnsafe(PlayerKeys.UUID)); - map.put(activityGroup, uuids); - } - } - activityData.put(time, map); - } - return activityData; - } - - public int count() { - return players.size(); - } - - public int averageNewPerDay(TimeZone timeZone) { - return MutatorFunctions.average(newPerDay(timeZone)); - } - - public TreeMap newPerDay(TimeZone timeZone) { - List registerDates = registerDates().stream() - .map(value -> new DateObj<>(value, value)) - .collect(Collectors.toList()); - // Adds timezone offset - SortedMap> byDay = new DateHoldersMutator<>(registerDates).groupByStartOfDay(timeZone); - TreeMap byDayCounts = new TreeMap<>(); - - for (Map.Entry> entry : byDay.entrySet()) { - byDayCounts.put( - entry.getKey(), - entry.getValue().size() - ); - } - - return byDayCounts; - } - - /** - * Compares players in the mutator to other players in terms of player retention. - * - * @param compareTo Players to compare to. - * @param dateLimit Epoch ms back limit, if the player registered after this their value is not used. - * @return Mutator containing the players that are considered to be retained. - * @throws IllegalStateException If all players are rejected due to dateLimit. - */ - public PlayersMutator compareAndFindThoseLikelyToBeRetained( - Iterable compareTo, - long dateLimit, - PlayersOnlineResolver onlineResolver, - long activityMsThreshold, - int activityLoginThreshold - ) { - Collection retainedAfterMonth = new ArrayList<>(); - Collection notRetainedAfterMonth = new ArrayList<>(); - - for (PlayerContainer player : players) { - long registered = player.getValue(PlayerKeys.REGISTERED).orElse(System.currentTimeMillis()); - - // Discard uncertain data - if (registered > dateLimit) { - continue; - } - - long monthAfterRegister = registered + TimeAmount.MONTH.toMillis(1L); - long half = registered + (TimeAmount.MONTH.toMillis(1L) / 2L); - if (player.playedBetween(registered, half) && player.playedBetween(half, monthAfterRegister)) { - retainedAfterMonth.add(player); - } else { - notRetainedAfterMonth.add(player); - } - } - - if (retainedAfterMonth.isEmpty() || notRetainedAfterMonth.isEmpty()) { - throw new IllegalStateException("No players to compare to after rejecting with dateLimit"); - } - - List retained = retainedAfterMonth.stream() - .map(player -> new RetentionData(player, onlineResolver, activityMsThreshold, activityLoginThreshold)) - .collect(Collectors.toList()); - List notRetained = notRetainedAfterMonth.stream() - .map(player -> new RetentionData(player, onlineResolver, activityMsThreshold, activityLoginThreshold)) - .collect(Collectors.toList()); - - RetentionData avgRetained = RetentionData.average(retained); - RetentionData avgNotRetained = RetentionData.average(notRetained); - - List toBeRetained = new ArrayList<>(); - for (PlayerContainer player : compareTo) { - RetentionData retentionData = new RetentionData(player, onlineResolver, activityMsThreshold, activityLoginThreshold); - if (retentionData.distance(avgRetained) < retentionData.distance(avgNotRetained)) { - toBeRetained.add(player); - } - } - return new PlayersMutator(toBeRetained); - } - - public List getSessions() { - return players.stream() - .map(player -> player.getValue(PlayerKeys.SESSIONS).orElse(new ArrayList<>())) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } - - public List uuids() { - return players.stream() - .map(player -> player.getValue(PlayerKeys.UUID).orElse(null)) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - } - - public List operators() { - return players.stream() - .filter(player -> player.getValue(PlayerKeys.OPERATOR).orElse(false)).collect(Collectors.toList()); - } - - public List pings() { - return players.stream() - .map(player -> player.getValue(PlayerKeys.PING).orElse(new ArrayList<>())) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersOnlineResolver.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersOnlineResolver.java deleted file mode 100644 index 6ef9d22cf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersOnlineResolver.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.utilities.html.graphs.line.Point; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.TreeMap; - -/** - * Resolves dates into players online numbers with a help of a NavigableMap. - *

- * Time Complexity of O(n / 2) with the use of TreeMap. - * - * @author Rsl1122 - */ -public class PlayersOnlineResolver extends TreeMap { - - public PlayersOnlineResolver(TPSMutator mutator) { - List points = mutator.playersOnlinePoints(); - for (Point point : points) { - double date = point.getX(); - double value = point.getY(); - put((long) date, (int) value); - } - } - - public Optional getOnlineOn(long date) { - Map.Entry entry = floorEntry(date); - if (entry == null) { - return Optional.empty(); - } - return Optional.of(entry.getValue()); - } - - public boolean isServerOnline(long date, long timeLimit) { - Long lastEntry = floorKey(date); - return date - lastEntry < timeLimit; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PvpInfoMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PvpInfoMutator.java deleted file mode 100644 index 0932167cb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PvpInfoMutator.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.containers.DataContainer; - -import java.util.List; - -public class PvpInfoMutator { - - private final SessionsMutator sessionsMutator; - - private PvpInfoMutator(SessionsMutator sessionsMutator) { - this.sessionsMutator = sessionsMutator; - } - - public PvpInfoMutator(List sessions) { - this(new SessionsMutator(sessions)); - } - - public static PvpInfoMutator forContainer(DataContainer container) { - return new PvpInfoMutator(SessionsMutator.forContainer(container)); - } - - public static PvpInfoMutator forMutator(SessionsMutator sessionsMutator) { - return new PvpInfoMutator(sessionsMutator); - } - - public double killDeathRatio() { - int deathCount = sessionsMutator.toPlayerDeathCount(); - return sessionsMutator.toPlayerKillCount() * 1.0 / (deathCount != 0 ? deathCount : 1); - } - - public int mobCausedDeaths() { - return sessionsMutator.toDeathCount() - sessionsMutator.toPlayerDeathCount(); - } - - public double mobKillDeathRatio() { - int deathCount = mobCausedDeaths(); - return sessionsMutator.toMobKillCount() * 1.0 / (deathCount != 0 ? deathCount : 1); - } - - public int mobKills() { - return sessionsMutator.toMobKillCount(); - } - - public int playerKills() { - return sessionsMutator.toPlayerKillCount(); - } - - public int deaths() { - return sessionsMutator.toDeathCount(); - } - - public int playerCausedDeaths() { - return sessionsMutator.toPlayerDeathCount(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/RetentionData.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/RetentionData.java deleted file mode 100644 index f3b46c812..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/RetentionData.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.google.common.base.Objects; - -import java.util.Collection; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -/** - * Utility class for player retention calculations. - *

- * Previously known as StickyData. - * - * @author Rsl1122 - */ -public class RetentionData { - private final double activityIndex; - private double onlineOnJoin; - - public static RetentionData average(Collection stuck) { - int size = stuck.size(); - - double totalIndex = 0.0; - double totalPlayersOnline = 0.0; - - for (RetentionData retentionData : stuck) { - totalIndex += retentionData.getActivityIndex(); - totalPlayersOnline += retentionData.getOnlineOnJoin(); - } - - double averageIndex = totalIndex / (double) size; - double averagePlayersOnline = totalPlayersOnline / (double) size; - - return new RetentionData(averageIndex, averagePlayersOnline); - } - - public RetentionData(double activityIndex, double onlineOnJoin) { - this.activityIndex = activityIndex; - this.onlineOnJoin = onlineOnJoin; - } - - public RetentionData( - PlayerContainer player, - PlayersOnlineResolver onlineOnJoin, - long activityMsThreshold, - int activityLoginThreshold - ) { - Optional registeredValue = player.getValue(PlayerKeys.REGISTERED); - activityIndex = registeredValue - .map(registered -> new ActivityIndex( - player, - registered + TimeUnit.DAYS.toMillis(1L), - activityMsThreshold, - activityLoginThreshold - ).getValue()) - .orElse(0.0); - this.onlineOnJoin = registeredValue - .map(registered -> onlineOnJoin.getOnlineOn(registered).orElse(-1)) - .orElse(0); - } - - public double distance(RetentionData data) { - double num = 0; - num += Math.abs(data.activityIndex - activityIndex) * 2.0; - num += data.onlineOnJoin != -1 && onlineOnJoin != -1 - ? Math.abs(data.onlineOnJoin - onlineOnJoin) / 10.0 - : 0; - - return num; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - RetentionData that = (RetentionData) o; - return Double.compare(that.activityIndex, activityIndex) == 0 && - Objects.equal(onlineOnJoin, that.onlineOnJoin); - } - - @Override - public int hashCode() { - return Objects.hashCode(activityIndex, onlineOnJoin); - } - - public double getOnlineOnJoin() { - return onlineOnJoin; - } - - public double getActivityIndex() { - return activityIndex; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java deleted file mode 100644 index de1e11be3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.container.PlayerDeath; -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.keys.CommonKeys; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.utilities.analysis.Median; - -import java.util.*; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -/** - * Mutator for a list of Sessions. - *

- * Can be used to get properties of a large number of sessions easily. - * - * @author Rsl1122 - */ -public class SessionsMutator { - - private List sessions; - - public static SessionsMutator forContainer(DataContainer container) { - return new SessionsMutator(container.getValue(CommonKeys.SESSIONS).orElse(new ArrayList<>())); - } - - public SessionsMutator(List sessions) { - this.sessions = sessions; - } - - public List all() { - return sessions; - } - - public SessionsMutator filterBy(Predicate predicate) { - return new SessionsMutator(sessions.stream() - .filter(predicate) - .collect(Collectors.toList())); - } - - public SessionsMutator filterSessionsBetween(long after, long before) { - return filterBy(getBetweenPredicate(after, before)); - } - - public SessionsMutator filterPlayedOnServer(UUID serverUUID) { - return filterBy(session -> - session.getValue(SessionKeys.SERVER_UUID) - .map(uuid -> uuid.equals(serverUUID)) - .orElse(false) - ); - } - - public DateHoldersMutator toDateHoldersMutator() { - return new DateHoldersMutator<>(sessions); - } - - public WorldTimes toTotalWorldTimes() { - WorldTimes total = new WorldTimes(); - - for (Session session : sessions) { - session.getValue(SessionKeys.WORLD_TIMES).ifPresent(total::add); - } - - return total; - } - - public List toPlayerKillList() { - return sessions.stream() - .map(session -> session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>())) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } - - public List toPlayerDeathList() { - return sessions.stream() - .map(session -> session.getValue(SessionKeys.PLAYER_DEATHS).orElse(new ArrayList<>())) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } - - public int toMobKillCount() { - return sessions.stream() - .mapToInt(session -> session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0)) - .sum(); - } - - public int toDeathCount() { - return sessions.stream() - .mapToInt(session -> session.getValue(SessionKeys.DEATH_COUNT).orElse(0)) - .sum(); - } - - public long toPlaytime() { - return sessions.stream() - .mapToLong(Session::getLength) - .sum(); - } - - public long toAfkTime() { - return sessions.stream() - .mapToLong(session -> session.getValue(SessionKeys.AFK_TIME).orElse(0L)) - .sum(); - } - - public long toActivePlaytime() { - return sessions.stream() - .mapToLong(session -> session.getValue(SessionKeys.ACTIVE_TIME).orElse(0L)) - .sum(); - } - - public long toLastSeen() { - return sessions.stream() - .mapToLong(session -> Math.max(session.getUnsafe( - SessionKeys.START), - session.getValue(SessionKeys.END).orElse(System.currentTimeMillis())) - ).max().orElse(-1); - } - - public long toLongestSessionLength() { - OptionalLong longestSession = sessions.stream().mapToLong(Session::getLength).max(); - if (longestSession.isPresent()) { - return longestSession.getAsLong(); - } - return -1; - } - - public long toAverageSessionLength() { - OptionalDouble average = sessions.stream().map(Session::getLength) - .mapToLong(i -> i) - .average(); - if (average.isPresent()) { - return (long) average.getAsDouble(); - } - return 0L; - } - - public long toMedianSessionLength() { - List sessionLengths = sessions.stream().map(Session::getLength).collect(Collectors.toList()); - return (long) Median.forList(sessionLengths).calculate(); - } - - public int toAverageUniqueJoinsPerDay(TimeZone timeZone) { - return MutatorFunctions.average(uniqueJoinsPerDay(timeZone)); - } - - public TreeMap uniqueJoinsPerDay(TimeZone timeZone) { - // Adds Timezone offset - SortedMap> byStartOfDay = toDateHoldersMutator().groupByStartOfDay(timeZone); - - TreeMap uniqueJoins = new TreeMap<>(); - for (Map.Entry> entry : byStartOfDay.entrySet()) { - uniqueJoins.put( - entry.getKey(), - new SessionsMutator(entry.getValue()).toUniquePlayers() - ); - } - - return uniqueJoins; - } - - public int toUniquePlayers() { - return (int) sessions.stream() - .map(session -> session.getUnsafe(SessionKeys.UUID)) - .distinct() - .count(); - } - - public int count() { - return sessions.size(); - } - - public int toPlayerKillCount() { - return toPlayerKillList().size(); - } - - public boolean playedBetween(long after, long before) { - return sessions.stream().anyMatch(getBetweenPredicate(after, before)); - } - - private Predicate getBetweenPredicate(long after, long before) { - return session -> { - Long start = session.getUnsafe(SessionKeys.START); - Long end = session.getValue(SessionKeys.END).orElse(System.currentTimeMillis()); - return (after <= start && start <= before) || (after <= end && end <= before); - }; - } - - public static Map> sortByPlayers(List sessions) { - Map> sorted = new HashMap<>(); - for (Session session : sessions) { - UUID playerUUID = session.getUnsafe(SessionKeys.UUID); - List playerSessions = sorted.getOrDefault(playerUUID, new ArrayList<>()); - playerSessions.add(session); - sorted.put(playerUUID, playerSessions); - } - return sorted; - } - - public static Map> sortByServers(List sessions) { - Map> sorted = new HashMap<>(); - for (Session session : sessions) { - UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID); - List serverSessions = sorted.getOrDefault(serverUUID, new ArrayList<>()); - serverSessions.add(session); - sorted.put(serverUUID, serverSessions); - } - return sorted; - } - - public int toPlayerDeathCount() { - return toPlayerDeathList().size(); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java deleted file mode 100644 index 7ac0f7994..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.utilities.comparators.TPSComparator; -import com.djrapitops.plan.utilities.html.graphs.line.Point; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -/** - * Mutator for a list of TPS data. - *

- * Can be used to get properties of a large number of TPS entries easily. - * - * @author Rsl1122 - */ -public class TPSMutator { - - private List tpsData; - - public TPSMutator(List tpsData) { - this.tpsData = tpsData; - } - - public static TPSMutator forContainer(DataContainer container) { - return new TPSMutator(container.getValue(ServerKeys.TPS).orElse(new ArrayList<>())); - } - - public static TPSMutator copyOf(TPSMutator mutator) { - return new TPSMutator(new ArrayList<>(mutator.tpsData)); - } - - public TPSMutator filterBy(Predicate filter) { - return new TPSMutator(tpsData.stream() - .filter(filter) - .collect(Collectors.toList())); - } - - public TPSMutator filterDataBetween(long after, long before) { - return filterBy(tps -> tps.getDate() >= after && tps.getDate() <= before); - } - - public List all() { - return tpsData; - } - - public List playersOnlinePoints() { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getPlayers())) - .collect(Collectors.toList()); - } - - public List tpsPoints() { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getTicksPerSecond())) - .collect(Collectors.toList()); - } - - public List cpuPoints() { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getCPUUsage())) - .filter(point -> point.getY() != -1) - .collect(Collectors.toList()); - } - - public List ramUsagePoints() { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getUsedMemory())) - .collect(Collectors.toList()); - } - - public List entityPoints() { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getEntityCount())) - .collect(Collectors.toList()); - } - - public List chunkPoints() { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getChunksLoaded())) - .collect(Collectors.toList()); - } - - public List freeDiskPoints() { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getFreeDiskSpace())) - .filter(point -> point.getY() != -1) - .collect(Collectors.toList()); - } - - public long serverDownTime() { - long lastDate = -1; - long downTime = 0; - tpsData.sort(new TPSComparator()); - for (TPS tps : tpsData) { - long date = tps.getDate(); - if (lastDate == -1) { - lastDate = date; - continue; - } - - long diff = date - lastDate; - if (diff > TimeUnit.MINUTES.toMillis(3L)) { - downTime += diff; - } - lastDate = date; - } - - return downTime; - } - - public long serverIdleTime() { - long lastDate = -1; - int lastPlayers = 0; - long idleTime = 0; - tpsData.sort(new TPSComparator()); - for (TPS tps : tpsData) { - long date = tps.getDate(); - int players = tps.getPlayers(); - if (lastDate == -1) { - lastDate = date; - lastPlayers = players; - continue; - } - - long diff = date - lastDate; - if (lastPlayers == 0 && players == 0) { - idleTime += diff; - } - - lastDate = date; - lastPlayers = players; - } - - return idleTime; - } - - public double percentageTPSAboveThreshold(int threshold) { - if (tpsData.isEmpty()) { - return 1; - } - - long count = 0; - for (TPS tps : tpsData) { - if (tps.getTicksPerSecond() >= threshold) { - count++; - } - } - - return count * 1.0 / tpsData.size(); - } - - public int lowTpsSpikeCount(int threshold) { - boolean wasLow = false; - int spikeCount = 0; - - for (TPS tpsObj : tpsData) { - double tps = tpsObj.getTicksPerSecond(); - if (tps < threshold) { - if (!wasLow) { - spikeCount++; - wasLow = true; - } - } else { - wasLow = false; - } - } - - return spikeCount; - } - - public double averageTPS() { - return tpsData.stream() - .mapToDouble(TPS::getTicksPerSecond) - .filter(num -> num >= 0) - .average().orElse(-1); - } - - public double averageCPU() { - return tpsData.stream() - .mapToDouble(TPS::getCPUUsage) - .filter(num -> num >= 0) - .average().orElse(-1); - } - - public double averageRAM() { - return tpsData.stream() - .mapToDouble(TPS::getUsedMemory) - .filter(num -> num >= 0) - .average().orElse(-1); - } - - public double averageEntities() { - return tpsData.stream() - .mapToDouble(TPS::getEntityCount) - .filter(num -> num >= 0) - .average().orElse(-1); - } - - public double averageChunks() { - return tpsData.stream() - .mapToDouble(TPS::getChunksLoaded) - .filter(num -> num >= 0) - .average().orElse(-1); - } - - public double averageFreeDisk() { - return tpsData.stream() - .mapToDouble(TPS::getFreeDiskSpace) - .filter(num -> num >= 0) - .average().orElse(-1); - } - - public long maxFreeDisk() { - return tpsData.stream() - .mapToLong(TPS::getFreeDiskSpace) - .filter(num -> num >= 0) - .max().orElse(-1); - } - - public long minFreeDisk() { - return tpsData.stream() - .mapToLong(TPS::getFreeDiskSpace) - .filter(num -> num >= 0) - .min().orElse(-1); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/AbstractHealthInfo.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/AbstractHealthInfo.java deleted file mode 100644 index ce42de3ed..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/AbstractHealthInfo.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators.health; - -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.HealthInfoLang; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.icon.Icons; - -import java.util.*; -import java.util.concurrent.TimeUnit; - -public abstract class AbstractHealthInfo { - - protected static final String SUB_NOTE = "
     "; - - protected final List notes; - protected final long now; - protected final long monthAgo; - - protected double serverHealth; - - protected final Locale locale; - protected final long activeMsThreshold; - protected final int activeLoginThreshold; - protected final Formatter timeAmountFormatter; - protected final Formatter decimalFormatter; - protected final Formatter percentageFormatter; - - public AbstractHealthInfo( - long now, long monthAgo, - Locale locale, - long activeMsThreshold, - int activeLoginThreshold, - Formatter timeAmountFormatter, - Formatter decimalFormatter, - Formatter percentageFormatter - ) { - this.now = now; - this.monthAgo = monthAgo; - this.locale = locale; - this.activeMsThreshold = activeMsThreshold; - this.activeLoginThreshold = activeLoginThreshold; - this.timeAmountFormatter = timeAmountFormatter; - this.decimalFormatter = decimalFormatter; - this.percentageFormatter = percentageFormatter; - serverHealth = 100.0; - - this.notes = new ArrayList<>(); - } - - protected abstract void calculate(); - - public double getServerHealth() { - return serverHealth; - } - - public String toHtml() { - StringBuilder healthNoteBuilder = new StringBuilder(); - for (String healthNote : notes) { - healthNoteBuilder.append(healthNote); - } - return healthNoteBuilder.toString(); - } - - protected void activityChangeNote(TreeMap>> activityData) { - Map> activityNow = activityData.getOrDefault(now, new HashMap<>()); - Set veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>()); - Set activeNow = activityNow.getOrDefault("Active", new HashSet<>()); - Set regularNow = activityNow.getOrDefault("Regular", new HashSet<>()); - - Map> activityFourWAgo = activityData.getOrDefault(monthAgo, new HashMap<>()); - Set veryActiveFWAG = activityFourWAgo.getOrDefault("Very Active", new HashSet<>()); - Set activeFWAG = activityFourWAgo.getOrDefault("Active", new HashSet<>()); - Set regularFWAG = activityFourWAgo.getOrDefault("Regular", new HashSet<>()); - - Set regularRemainCompareSet = new HashSet<>(regularFWAG); - regularRemainCompareSet.addAll(activeFWAG); - regularRemainCompareSet.addAll(veryActiveFWAG); - - int activeFWAGNum = regularRemainCompareSet.size(); - regularRemainCompareSet.removeAll(regularNow); - regularRemainCompareSet.removeAll(activeNow); - regularRemainCompareSet.removeAll(veryActiveNow); - int notRegularAnymore = regularRemainCompareSet.size(); - int remain = activeFWAGNum - notRegularAnymore; - double percRemain = activeFWAGNum != 0 ? remain * 1.0 / activeFWAGNum : 1.0; - - int newActive = getNewActive(veryActiveNow, activeNow, regularNow, veryActiveFWAG, activeFWAG, regularFWAG); - - int change = newActive - notRegularAnymore; - - StringBuilder remainNote = new StringBuilder(); - if (activeFWAGNum != 0) { - remainNote.append(SUB_NOTE); - if (percRemain > 0.5) { - remainNote.append(Icons.GREEN_THUMB); - } else if (percRemain > 0.2) { - remainNote.append(Icons.YELLOW_FLAG); - } else { - remainNote.append(Icons.RED_WARN); - serverHealth -= 2.5; - } - - remainNote.append(locale.getString(HealthInfoLang.REGULAR_ACTIVITY_REMAIN, - percentageFormatter.apply(percRemain), - remain, activeFWAGNum - )); - } - - String sentenceStart = locale.getString(HealthInfoLang.REGULAR_CHANGE); - if (change > 0) { - addNote(Icons.GREEN_THUMB + sentenceStart + locale.getString(HealthInfoLang.REGULAR_CHANGE_INCREASE, change) + remainNote); - } else if (change == 0) { - addNote(Icons.GREEN_THUMB + sentenceStart + locale.getString(HealthInfoLang.REGULAR_CHANGE_ZERO, change) + remainNote); - } else if (change > -20) { - addNote(Icons.YELLOW_FLAG + sentenceStart + locale.getString(HealthInfoLang.REGULAR_CHANGE_DECREASE, change) + remainNote); - serverHealth -= 5; - } else { - addNote(Icons.RED_WARN + sentenceStart + locale.getString(HealthInfoLang.REGULAR_CHANGE_DECREASE, change) + remainNote); - serverHealth -= 10; - } - } - - protected void activePlayerPlaytimeChange(PlayersMutator playersMutator) { - PlayersMutator currentlyActive = playersMutator.filterActive(now, activeMsThreshold, activeLoginThreshold, 1.75); - long twoWeeksAgo = now - ((now - monthAgo) / 2L); - - long totalFourToTwoWeeks = 0; - long totalLastTwoWeeks = 0; - for (PlayerContainer activePlayer : currentlyActive.all()) { - totalFourToTwoWeeks += SessionsMutator.forContainer(activePlayer) - .filterSessionsBetween(monthAgo, twoWeeksAgo).toActivePlaytime(); - totalLastTwoWeeks += SessionsMutator.forContainer(activePlayer) - .filterSessionsBetween(twoWeeksAgo, now).toActivePlaytime(); - } - int activeCount = currentlyActive.count(); - if (activeCount != 0) { - long avgFourToTwoWeeks = totalFourToTwoWeeks / (long) activeCount; - long avgLastTwoWeeks = totalLastTwoWeeks / (long) activeCount; - String avgLastTwoWeeksString = timeAmountFormatter.apply(avgLastTwoWeeks); - String avgFourToTwoWeeksString = timeAmountFormatter.apply(avgFourToTwoWeeks); - - // Played more or equal amount than 2 weeks ago - if (avgLastTwoWeeks >= avgFourToTwoWeeks) { - addNote(Icons.GREEN_THUMB + locale.getString(HealthInfoLang.ACTIVE_PLAY_COMPARISON_INCREASE, - avgLastTwoWeeksString, avgFourToTwoWeeksString)); - // Played more than 2 hours less, than 2 weeks ago - } else if (avgFourToTwoWeeks - avgLastTwoWeeks > TimeUnit.HOURS.toMillis(2L)) { - addNote(Icons.RED_WARN + locale.getString(HealthInfoLang.ACTIVE_PLAY_COMPARISON_DECREASE, - avgLastTwoWeeksString, avgFourToTwoWeeksString)); - serverHealth -= 5; - // Played less than two weeks ago - } else { - addNote(Icons.YELLOW_FLAG + locale.getString(HealthInfoLang.ACTIVE_PLAY_COMPARISON_DECREASE, - avgLastTwoWeeksString, avgFourToTwoWeeksString)); - } - } - } - - private int getNewActive(Set veryActiveNow, Set activeNow, Set regularNow, Set veryActiveFWAG, Set activeFWAG, Set regularFWAG) { - Set regularNewCompareSet = new HashSet<>(regularNow); - regularNewCompareSet.addAll(activeNow); - regularNewCompareSet.addAll(veryActiveNow); - regularNewCompareSet.removeAll(regularFWAG); - regularNewCompareSet.removeAll(activeFWAG); - regularNewCompareSet.removeAll(veryActiveFWAG); - return regularNewCompareSet.size(); - } - - protected void addNote(String note) { - notes.add("

" + note + "

"); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/HealthInformation.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/HealthInformation.java deleted file mode 100644 index ea79c05a4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/HealthInformation.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators.health; - -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.containers.AnalysisContainer; -import com.djrapitops.plan.data.store.keys.AnalysisKeys; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plan.data.store.mutators.PlayersOnlineResolver; -import com.djrapitops.plan.data.store.mutators.TPSMutator; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.HealthInfoLang; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.icon.Icons; -import com.djrapitops.plugin.api.TimeAmount; - -import java.util.ArrayList; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -/** - * Server Health analysis mutator. - * - * @author Rsl1122 - */ -public class HealthInformation extends AbstractHealthInfo { - - private final AnalysisContainer analysisContainer; - - private final int lowTPSThreshold; - - public HealthInformation( - AnalysisContainer analysisContainer, - Locale locale, - int lowTPSThreshold, - long activeMsThreshold, - int activeLoginThreshold, - Formatter timeAmountFormatter, - Formatter decimalFormatter, - Formatter percentageFormatter - ) { - super( - analysisContainer.getUnsafe(AnalysisKeys.ANALYSIS_TIME), - analysisContainer.getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), - locale, - activeMsThreshold, activeLoginThreshold, - timeAmountFormatter, decimalFormatter, percentageFormatter - ); - this.analysisContainer = analysisContainer; - this.lowTPSThreshold = lowTPSThreshold; - calculate(); - } - - @Override - public String toHtml() { - StringBuilder healthNoteBuilder = new StringBuilder(); - for (String healthNote : notes) { - healthNoteBuilder.append(healthNote); - } - return healthNoteBuilder.toString(); - } - - @Override - protected void calculate() { - activityChangeNote(analysisContainer.getUnsafe(AnalysisKeys.ACTIVITY_DATA)); - newPlayerNote(); - activePlayerPlaytimeChange(analysisContainer.getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)); - lowPerformance(); - } - - private void newPlayerNote() { - Key newMonth = new Key<>(PlayersMutator.class, "NEW_MONTH"); - PlayersMutator newPlayersMonth = analysisContainer.getValue(newMonth).orElse(new PlayersMutator(new ArrayList<>())); - PlayersOnlineResolver onlineResolver = analysisContainer.getUnsafe(AnalysisKeys.PLAYERS_ONLINE_RESOLVER); - - double avgOnlineOnRegister = newPlayersMonth.registerDates().stream() - .map(onlineResolver::getOnlineOn) - .filter(Optional::isPresent) - .mapToInt(Optional::get) - .average().orElse(0); - if (avgOnlineOnRegister >= 1) { - addNote(Icons.GREEN_THUMB + locale.getString(HealthInfoLang.NEW_PLAYER_JOIN_PLAYERS_GOOD, - decimalFormatter.apply(avgOnlineOnRegister))); - } else { - addNote(Icons.YELLOW_FLAG + locale.getString(HealthInfoLang.NEW_PLAYER_JOIN_PLAYERS_BAD, - decimalFormatter.apply(avgOnlineOnRegister))); - serverHealth -= 5; - } - - long playersNewMonth = analysisContainer.getValue(AnalysisKeys.PLAYERS_NEW_MONTH).orElse(0); - long playersRetainedMonth = analysisContainer.getValue(AnalysisKeys.PLAYERS_RETAINED_MONTH).orElse(0); - - if (playersNewMonth != 0) { - double retainPercentage = playersRetainedMonth * 1.0 / playersNewMonth; - String stickinessSentence = locale.getString(HealthInfoLang.NEW_PLAYER_STICKINESS, - percentageFormatter.apply(retainPercentage), playersRetainedMonth, playersNewMonth); - if (retainPercentage >= 0.25) { - addNote(Icons.GREEN_THUMB + stickinessSentence); - } else { - addNote(Icons.YELLOW_FLAG + stickinessSentence); - } - } - } - - private void lowPerformance() { - Key tpsMonth = new Key<>(TPSMutator.class, "TPS_MONTH"); - TPSMutator tpsMutator = analysisContainer.getUnsafe(tpsMonth); - long serverDownTime = tpsMutator.serverDownTime(); - - double aboveThreshold = tpsMutator.percentageTPSAboveThreshold(lowTPSThreshold); - long tpsSpikeMonth = analysisContainer.getValue(AnalysisKeys.TPS_SPIKE_MONTH).orElse(0); - - StringBuilder avgLowThresholdString = new StringBuilder(SUB_NOTE); - if (aboveThreshold >= 0.96) { - avgLowThresholdString.append(Icons.GREEN_THUMB); - } else if (aboveThreshold >= 0.9) { - avgLowThresholdString.append(Icons.YELLOW_FLAG); - serverHealth *= 0.9; - } else { - avgLowThresholdString.append(Icons.RED_WARN); - serverHealth *= 0.6; - } - avgLowThresholdString.append(locale.getString(HealthInfoLang.TPS_ABOVE_LOW_THERSHOLD, percentageFormatter.apply(aboveThreshold))); - - String tpsDipSentence = locale.getString(HealthInfoLang.TPS_LOW_DIPS, lowTPSThreshold, tpsSpikeMonth); - if (tpsSpikeMonth <= 5) { - addNote(Icons.GREEN_THUMB + tpsDipSentence + avgLowThresholdString); - } else if (tpsSpikeMonth <= 25) { - addNote(Icons.YELLOW_FLAG + tpsDipSentence + avgLowThresholdString); - serverHealth *= 0.95; - } else { - addNote(Icons.RED_WARN + tpsDipSentence + avgLowThresholdString); - serverHealth *= 0.8; - } - - String downtimeSentence = locale.getString(HealthInfoLang.DOWNTIME, timeAmountFormatter.apply(serverDownTime)); - if (serverDownTime <= TimeUnit.DAYS.toMillis(1L)) { - addNote(Icons.GREEN_THUMB + downtimeSentence); - } else { - long weekMs = TimeAmount.WEEK.toMillis(1L); - if (serverDownTime <= weekMs) { - addNote(Icons.YELLOW_FLAG + downtimeSentence); - serverHealth *= (weekMs - serverDownTime) * 1.0 / weekMs; - } else { - addNote(Icons.RED_WARN + downtimeSentence); - long monthMs = TimeAmount.MONTH.toMillis(1L); - serverHealth *= (monthMs - serverDownTime) * 1.0 / monthMs; - } - } - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/NetworkHealthInformation.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/NetworkHealthInformation.java deleted file mode 100644 index db50e1b8c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/health/NetworkHealthInformation.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.mutators.health; - -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.data.store.containers.SupplierDataContainer; -import com.djrapitops.plan.data.store.keys.AnalysisKeys; -import com.djrapitops.plan.data.store.keys.NetworkKeys; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.HealthInfoLang; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.icon.Icon; -import com.djrapitops.plan.utilities.html.icon.Icons; - -import java.util.*; - -public class NetworkHealthInformation extends AbstractHealthInfo { - - private final NetworkContainer container; - private final TimeZone timeZone; - - public NetworkHealthInformation( - NetworkContainer container, - Locale locale, - long activeMsThreshold, - int activeLoginThreshold, - Formatter timeAmountFormatter, - Formatter decimalFormatter, - Formatter percentageFormatter, - TimeZone timeZone - ) { - super( - container.getUnsafe(NetworkKeys.REFRESH_TIME), - container.getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), - locale, - activeMsThreshold, activeLoginThreshold, - timeAmountFormatter, decimalFormatter, percentageFormatter - ); - this.container = container; - this.timeZone = timeZone; - calculate(); - } - - @Override - protected void calculate() { - perServerComparisonNotes(container.getUnsafe(NetworkKeys.PLAYERS_MUTATOR)); - - activityChangeNote(container.getUnsafe(NetworkKeys.ACTIVITY_DATA)); - activePlayerPlaytimeChange(container.getUnsafe(NetworkKeys.PLAYERS_MUTATOR)); - } - - private void perServerComparisonNotes(PlayersMutator playersMutator) { - Collection servers = container.getValue(NetworkKeys.BUKKIT_SERVERS) - .orElse(Collections.emptyList()); - - if (servers.isEmpty()) { - addNote(Icons.HELP_RING + locale.getString(HealthInfoLang.NO_SERVERS_INACCURACY)); - return; - } - int serverCount = servers.size(); - if (serverCount == 1) { - addNote(Icons.HELP_RING + locale.getString(HealthInfoLang.SINGLE_SERVER_INACCURACY)); - return; - } - - Key serverKey = new Key<>(Server.class, "SERVER"); - - List perServerContainers = getPerServerContainers(playersMutator, servers, serverKey); - - uniquePlayersNote(serverCount, serverKey, perServerContainers); - newPlayersNote(serverCount, serverKey, perServerContainers); - playersNote(serverKey, perServerContainers); - } - - private void uniquePlayersNote(int serverCount, Key serverKey, List perServerContainers) { - Icon icon; - String uniquePlayersNote = locale.getString(HealthInfoLang.PLAYER_VISIT_PER_SERVER); - double average = perServerContainers.stream() - .mapToInt(c -> c.getUnsafe(AnalysisKeys.AVG_PLAYERS_MONTH)) - .average().orElse(0.0); - if (average < 1) { - icon = Icons.RED_WARN; - serverHealth -= 10.0; - } else if (average < serverCount) { - icon = Icons.YELLOW_FLAG; - serverHealth -= 5.0; - } else { - icon = Icons.GREEN_THUMB; - } - StringBuilder subNotes = new StringBuilder(); - perServerContainers.stream() - .sorted(Comparator.comparingInt(c -> 0 - c.getUnsafe(AnalysisKeys.AVG_PLAYERS_MONTH))) - .map(c -> { - int playersPerMonth = c.getUnsafe(AnalysisKeys.AVG_PLAYERS_MONTH); - Server server = c.getUnsafe(serverKey); - return SUB_NOTE + (playersPerMonth >= average && playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " + - server.getName() + ": " + playersPerMonth; - }).forEach(subNotes::append); - addNote(icon + " " + decimalFormatter.apply(average) + uniquePlayersNote + subNotes.toString()); - } - - private void newPlayersNote(int serverCount, Key serverKey, List perServerContainers) { - Icon icon; - String newPlayersNote = locale.getString(HealthInfoLang.PLAYER_REGISTER_PER_SERVER); - double average = perServerContainers.stream() - .mapToInt(c -> c.getUnsafe(AnalysisKeys.AVG_PLAYERS_NEW_MONTH)) - .average().orElse(0.0); - if (average < 1) { - icon = Icons.RED_WARN; - serverHealth -= 10.0; - } else if (average < serverCount) { - icon = Icons.YELLOW_FLAG; - serverHealth -= 5.0; - } else { - icon = Icons.GREEN_THUMB; - } - StringBuilder subNotes = new StringBuilder(); - perServerContainers.stream() - .sorted(Comparator.comparingInt(c -> 0 - c.getUnsafe(AnalysisKeys.AVG_PLAYERS_NEW_MONTH))) - .map(c -> { - int playersPerMonth = c.getUnsafe(AnalysisKeys.AVG_PLAYERS_NEW_MONTH); - Server server = c.getUnsafe(serverKey); - return SUB_NOTE + (playersPerMonth >= average && playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " + - server.getName() + ": " + playersPerMonth; - }).forEach(subNotes::append); - addNote(icon + " " + decimalFormatter.apply(average) + newPlayersNote + subNotes.toString()); - } - - private List getPerServerContainers(PlayersMutator playersMutator, Collection servers, Key serverKey) { - List perServerContainers = new ArrayList<>(); - - for (Server server : servers) { - UUID serverUUID = server.getUuid(); - DataContainer serverContainer = new SupplierDataContainer(); - serverContainer.putRawData(serverKey, server); - - PlayersMutator serverPlayers = playersMutator.filterPlayedOnServer(serverUUID); - PlayersMutator serverRegistered = serverPlayers.filterRegisteredBetween(monthAgo, now); - int averageNewPerDay = serverRegistered.averageNewPerDay(timeZone); - serverContainer.putRawData(AnalysisKeys.AVG_PLAYERS_NEW_MONTH, averageNewPerDay); - SessionsMutator serverSessions = new SessionsMutator(serverPlayers.getSessions()) - .filterSessionsBetween(monthAgo, now) - .filterPlayedOnServer(serverUUID); - int averageUniquePerDay = serverSessions.toAverageUniqueJoinsPerDay(timeZone); - int uniquePlayers = serverSessions.toUniquePlayers(); - serverContainer.putRawData(AnalysisKeys.AVG_PLAYERS_MONTH, averageUniquePerDay); - serverContainer.putRawData(AnalysisKeys.PLAYERS_MONTH, uniquePlayers); - - perServerContainers.add(serverContainer); - } - return perServerContainers; - } - - private void playersNote(Key serverKey, List perServerContainers) { - Icon icon = Icons.HELP_RING; - String uniquePlayersNote = "${playersMonth}" + locale.getString(HealthInfoLang.PLAYER_PLAY_ON_NETWORK); - StringBuilder subNotes = new StringBuilder(); - perServerContainers.stream() - .sorted(Comparator.comparingInt(c -> 0 - c.getUnsafe(AnalysisKeys.PLAYERS_MONTH))) - .map(c -> { - int playersPerMonth = c.getUnsafe(AnalysisKeys.PLAYERS_MONTH); - Server server = c.getUnsafe(serverKey); - return SUB_NOTE + (playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " + - server.getName() + ": " + playersPerMonth; - }).forEach(subNotes::append); - addNote(icon.toHtml() + " " + uniquePlayersNote + subNotes.toString()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateHolder.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateHolder.java deleted file mode 100644 index 892d607ed..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateHolder.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.objects; - -/** - * Interface for objects that have a epoch ms date. - * - * @author Rsl1122 - */ -public interface DateHolder { - - /** - * Get the date the object holds. - * - * @return Epoch ms - milliseconds passed since January 1st 1970. - */ - long getDate(); - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateMap.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateMap.java deleted file mode 100644 index 9df1907df..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateMap.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.objects; - -import java.util.TreeMap; - -/** - * Basic TreeMap that uses Epoch MS as keys. - * - * @author Rsl1122 - */ -public class DateMap extends TreeMap { - - public DateMap() { - super(Long::compareTo); - } - - public boolean hasValuesBetween(long after, long before) { - return countBetween(after, before) > 0; - } - - public int countBetween(long after, long before) { - return subMap(after, before).size(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateObj.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateObj.java deleted file mode 100644 index 600e1d192..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateObj.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.objects; - -/** - * Object that has a value tied to a date. - * - * @author Rsl1122 - */ -public class DateObj implements DateHolder { - - private final long date; - private final T value; - - public DateObj(long date, T value) { - this.date = date; - this.value = value; - } - - @Override - public long getDate() { - return date; - } - - public T getValue() { - return value; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateSet.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateSet.java deleted file mode 100644 index cbad25a77..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/DateSet.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.objects; - -import java.util.TreeSet; - -/** - * Basic TreeSet with Epoch ms as values. - * - * @author Rsl1122 - */ -public class DateSet extends TreeSet { - - public boolean hasValuesBetween(long after, long before) { - return countBetween(after, before) > 0; - } - - public int countBetween(long after, long before) { - return subSet(after, before).size(); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/Nickname.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/Nickname.java deleted file mode 100644 index d69a7d008..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/objects/Nickname.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.store.objects; - -import java.util.Objects; -import java.util.UUID; - -/** - * Object storing nickname information. - * - * @author Rsl1122 - */ -public class Nickname implements DateHolder { - - private final String name; - private final long date; - private final UUID serverUUID; - - public Nickname(String name, long date, UUID serverUUID) { - this.name = name; - this.date = date; - this.serverUUID = serverUUID; - } - - public String getName() { - return name.length() <= 75 ? name : name.substring(0, 74); - } - - @Override - public long getDate() { - return date; - } - - public UUID getServerUUID() { - return serverUUID; - } - - @Override - public String toString() { - return "Nickname{" + - "name='" + name + '\'' + - ", date=" + date + - ", serverUUID=" + serverUUID + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Nickname)) return false; - Nickname nickname = (Nickname) o; - return Objects.equals(name, nickname.name) && - Objects.equals(serverUUID, nickname.serverUUID); - } - - @Override - public int hashCode() { - - return Objects.hash(name, date, serverUUID); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/time/GMTimes.java b/Plan/common/src/main/java/com/djrapitops/plan/data/time/GMTimes.java deleted file mode 100644 index 6d5f4c082..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/time/GMTimes.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.time; - -import com.djrapitops.plugin.utilities.Verify; - -import java.util.Map; - -/** - * TimeKeeper class that tracks the time spent in each GameMode based on Playtime. - * - * @author Rsl1122 - */ -public class GMTimes extends TimeKeeper { - - private static final String SURVIVAL = "SURVIVAL"; - private static final String CREATIVE = "CREATIVE"; - private static final String ADVENTURE = "ADVENTURE"; - private static final String SPECTATOR = "SPECTATOR"; - - public GMTimes(Map times, String lastState, long lastStateChange) { - super(times, lastState, lastStateChange); - } - - public GMTimes(String lastState, long lastStateChange) { - super(lastState, lastStateChange); - } - - public GMTimes(String lastState) { - super(lastState); - } - - public GMTimes(Map times) { - super(times); - } - - public GMTimes() { - super(); - } - - public static String[] getGMKeyArray() { - return new String[]{SURVIVAL, CREATIVE, ADVENTURE, SPECTATOR}; - } - - /** - * Sets times for all 4 gamemodes. - *

- * Give 1 - 4 parameters. - * times starts from Survival, ends in Spectator. - *

- * Given too few parameters (Under 4, rest are set as 0L) - * Extra parameters are ignored (Over 4) - * - * @param times 1-4 time parameters. - * @throws IllegalArgumentException If any parameter is null. - */ - public void setAllGMTimes(long... times) { - Verify.nullCheck(times); - String[] gms = getGMKeyArray(); - int size = times.length; - for (int i = 0; i < 4; i++) { - if (i >= size) { - setTime(gms[i], 0L); - } else { - setTime(gms[i], times[i]); - } - } - } - - public void resetTimes(long time) { - resetState(SURVIVAL, time); - resetState(CREATIVE); - resetState(ADVENTURE); - resetState(SPECTATOR); - } - - @Override - public String getState() { - String state = super.getState(); - return state != null ? state : SURVIVAL; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java b/Plan/common/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java deleted file mode 100644 index ed474f708..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.time; - -import com.djrapitops.plugin.utilities.Verify; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Abstract class for keeping track of time spent in each state. - * - * @author Rsl1122 - */ -public abstract class TimeKeeper { - - protected Map times; - protected String state; - protected long lastStateChange; - - public TimeKeeper(Map times, String lastState, long lastStateChange) { - this.times = times; - this.state = lastState; - this.lastStateChange = lastStateChange; - } - - public TimeKeeper(String lastState, long lastStateChange) { - this(new HashMap<>(), lastState, lastStateChange); - } - - public TimeKeeper(String lastState) { - this(new HashMap<>(), lastState, 0L); - } - - public TimeKeeper(Map times) { - this(times, null, 0); - } - - public TimeKeeper() { - this(new HashMap<>()); - } - - /** - * Sets a specific time for a state. - * - * @param state State to set - * @param time Time in ms the state has been active for - * @throws IllegalArgumentException If given state is null - */ - public void setTime(String state, long time) { - times.put(Verify.nullCheck(state), time); - } - - public void renameState(String state, String renameTo) { - Verify.nullCheck(state, renameTo); - Long time = times.get(state); - if (time != null) { - times.put(renameTo, time); - times.remove(state); - if (state.equals(this.state)) { - this.state = renameTo; - } - } - } - - /** - * Adds time to the last state while updating the status of other parameters. - * - * @param newState New State seen in. - * @param ms Epoch ms the change occurred. - * @throws IllegalArgumentException If newState is null. - */ - public void changeState(String newState, long ms) { - Verify.nullCheck(newState); - if (state == null) { - state = newState; - } - Long currentTime = times.getOrDefault(state, 0L); - long diff = ms - lastStateChange; - times.put(state, currentTime + Math.abs(diff)); - state = newState; - lastStateChange = ms; - } - - protected void resetState(String state) { - times.remove(Verify.nullCheck(state)); - } - - protected void resetState(String state, long time) { - if (time > 0) { - times.put(Verify.nullCheck(state), time); - lastStateChange = time; - this.state = state; - } else { - resetState(state); - } - } - - public long getTime(String state) { - return times.getOrDefault(state, 0L); - } - - public void addTime(String state, long time) { - times.put(state, times.getOrDefault(state, 0L) + time); - } - - public long getTotal() { - return times.values().stream().mapToLong(i -> i).sum(); - } - - public Map getTimes() { - return times; - } - - public void setTimes(Map times) { - this.times = times; - } - - public String getState() { - return state; - } - - public void setState(String state) { - this.state = state; - } - - public long getLastStateChange() { - return lastStateChange; - } - - public void setLastStateChange(long lastStateChange) { - this.lastStateChange = lastStateChange; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TimeKeeper that = (TimeKeeper) o; - return lastStateChange == that.lastStateChange && - Objects.equals(times, that.times) && - Objects.equals(state, that.state); - } - - @Override - public int hashCode() { - return Objects.hash(times, state, lastStateChange); - } - - @Override - public String toString() { - return "TimeKeeper{" + "times=" + times + - ", state='" + state + "', lastStateChange=" + lastStateChange + '}'; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java b/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java deleted file mode 100644 index 147772014..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.data.time; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -/** - * Class that tracks the time spent in each World based on GMTimes. - * - * @author Rsl1122 - */ -public class WorldTimes { - - private final Map times; - private String currentWorld; - private String currentGamemode; - - /** - * Creates a new Empty WorldTimes object. - * - * @param startingWorld World to start the calculations at. - * @param startingGM GameMode to start the calculations at. - * @param time Epoch ms the time calculation should start - */ - public WorldTimes(String startingWorld, String startingGM, long time) { - times = new HashMap<>(); - currentWorld = startingWorld; - currentGamemode = startingGM; - addWorld(startingWorld, startingGM, time); - } - - /** - * Re-Creates an existing WorldTimes object for viewing. - * - * @param times Map of each World's GMTimes object. - */ - public WorldTimes(Map times) { - this.times = times; - } - - public WorldTimes() { - this(new HashMap<>()); - } - - private void addWorld(String worldName, String gameMode, long changeTime) { - if (worldName == null || gameMode == null) return; - times.put(worldName, new GMTimes(gameMode, changeTime)); - } - - /** - * Updates the state at the end of the session. - * Does not change world or GameMode. - * - * @param changeTime epoch ms session ended. - */ - public void updateState(long changeTime) { - updateState(currentWorld, currentGamemode, changeTime); - } - - /** - * Updates the time status to match the new state. - * - * @param worldName World name of the world swapped to. - * @param gameMode GameMode name of the gm swapped to. - * @param changeTime Epoch ms the change occurred. - */ - public void updateState(String worldName, String gameMode, long changeTime) { - if (worldName == null || gameMode == null) return; - - GMTimes currentGMTimes = times.get(currentWorld); - if (currentWorld.equals(worldName)) { - currentGMTimes.changeState(gameMode, changeTime); - } else { - GMTimes newGMTimes = times.get(worldName); - if (newGMTimes == null) { - addWorld(worldName, gameMode, currentGMTimes.getLastStateChange()); - } - currentGMTimes.changeState(currentGamemode, changeTime); - } - - for (GMTimes gmTimes : times.values()) { - gmTimes.setLastStateChange(changeTime); - } - - currentWorld = worldName; - currentGamemode = gameMode; - } - - /** - * Used to get a total playtime of a world. - * - * @param world World name being checked. - * @return total milliseconds spent in a world. - */ - public long getWorldPlaytime(String world) { - GMTimes gmTimes = times.get(world); - return gmTimes != null ? gmTimes.getTotal() : 0; - } - - public long getTotal() { - return times.values().stream() - .mapToLong(GMTimes::getTotal) - .sum(); - } - - /** - * Used for Quick access to time of each GameMode. - *

- * Should not be used for changing state, - * because if player has not played in the world, - * an empty GMTimes is given, with 0 as playtime - * - * @param world World name being checked. - * @return GMTimes object with play times of each GameMode. - */ - public GMTimes getGMTimes(String world) { - return times.getOrDefault(world, new GMTimes()); - } - - public Map getWorldTimes() { - return times; - } - - public void setGMTimesForWorld(String world, GMTimes gmTimes) { - times.put(world, gmTimes); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - WorldTimes that = (WorldTimes) o; - return Objects.equals(times, that.times) && - Objects.equals(currentWorld, that.currentWorld) && - Objects.equals(currentGamemode, that.currentGamemode); - } - - @Override - public int hashCode() { - return Objects.hash(times, currentWorld, currentGamemode); - } - - @Override - public String toString() { - StringBuilder b = new StringBuilder("WorldTimes (Current: " + currentWorld + "){\n"); - - for (Map.Entry entry : times.entrySet()) { - GMTimes value = entry.getValue(); - b.append("World '").append(entry.getKey()).append("':\n") - .append(" Total: ").append(value.getTotal()).append("\n") - .append(" ").append(value.toString()).append("\n"); - } - - b.append("}"); - return b.toString(); - } - - public Optional getCurrentWorld() { - return Optional.ofNullable(currentWorld); - } - - public void add(WorldTimes toAdd) { - for (Map.Entry entry : toAdd.getWorldTimes().entrySet()) { - String worldName = entry.getKey(); - GMTimes gmTimes = entry.getValue(); - - GMTimes currentGMTimes = getGMTimes(worldName); - for (String gm : GMTimes.getGMKeyArray()) { - currentGMTimes.addTime(gm, gmTimes.getTime(gm)); - } - this.times.put(worldName, currentGMTimes); - } - } - - public boolean contains(String worldName) { - return times.containsKey(worldName); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/AbstractDatabase.java b/Plan/common/src/main/java/com/djrapitops/plan/db/AbstractDatabase.java deleted file mode 100644 index 1bbd6086f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/AbstractDatabase.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db; - -/** - * Abstract class representing a Database. - *

- * All Operations methods should be only called from an asynchronous thread. - * - * @author Rsl1122 - */ -public abstract class AbstractDatabase implements Database { - - protected DBAccessLock accessLock; - private State state; - - public AbstractDatabase() { - state = State.CLOSED; - accessLock = new DBAccessLock(this); - } - - @Override - public State getState() { - return state; - } - - public void setState(State state) { - this.state = state; - accessLock.operabilityChanged(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/DBAccessLock.java b/Plan/common/src/main/java/com/djrapitops/plan/db/DBAccessLock.java deleted file mode 100644 index 2471e954b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/DBAccessLock.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.access.transactions.init.OperationCriticalTransaction; - -/** - * Database Lock that prevents queries and transactions from taking place before database schema is ready. - *

- * - OperationCriticalTransactions pass through the Access lock without blocking to allow the initial transactions. - * - Queries inside Transactions skip access log to allow OperationCriticalTransactions perform queries. - * - * @author Rsl1122 - */ -public class DBAccessLock { - - private final Database database; - - private final Object lockObject; - - public DBAccessLock(Database database) { - this.database = database; - this.lockObject = new Object(); - } - - public void checkAccess() { - checkAccess(false); - } - - public void checkAccess(Transaction transaction) { - checkAccess(transaction instanceof OperationCriticalTransaction); - } - - private void checkAccess(boolean isOperationCriticalTransaction) { - if (isOperationCriticalTransaction) { - return; - } - try { - while (database.getState() != Database.State.OPEN) { - synchronized (lockObject) { - lockObject.wait(); - if (database.getState() == Database.State.CLOSED) { - throw new DBOpException("Database failed to open, Query has failed. (This exception is necessary to not keep query threads waiting)"); - } - } - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - public void operabilityChanged() { - synchronized (lockObject) { - lockObject.notifyAll(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/DBType.java b/Plan/common/src/main/java/com/djrapitops/plan/db/DBType.java deleted file mode 100644 index ba3ec6558..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/DBType.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db; - -import java.util.Optional; - -/** - * An enum which stores the name, the config name and if the Database supports MySQL Queries - * - * @author Fuzzlemann - */ -public enum DBType { - - MYSQL("MySQL", true), - SQLITE("SQLite", false), - H2("H2", true); - - private final String name; - private final String configName; - private final boolean supportingMySQLQueries; - - DBType(String name, boolean supportingMySQLQueries) { - this.name = name; - this.configName = name.toLowerCase().trim(); - this.supportingMySQLQueries = supportingMySQLQueries; - } - - /** - * Gets the name of the {@code DBType} - * - * @return the name - */ - public String getName() { - return name; - } - - /** - * Gets the config name of the {@code DBType} - * - * @return the config name - */ - public String getConfigName() { - return configName; - } - - /** - * Used to check if the {@code DBType} supports most MySQL MySQLSchemaQueries.

- * When specific Statements are not compatible, the {@code DBType} should be checked. - * - * @return if the database supports MySQL MySQLSchemaQueries - */ - public boolean supportsMySQLQueries() { - return supportingMySQLQueries; - } - - /** - * Gets an {@code Optional} which matches {@code name}.

- * This method is case-insensitive.

- * The {@code Optional} is empty when no {@code DBType} is found. - * - * @param name the name of the {@code DBType} - * @return an {@code Optional} - */ - public static Optional getForName(String name) { - for (DBType dbType : DBType.values()) { - if (dbType.getName().equalsIgnoreCase(name)) { - return Optional.of(dbType); - } - } - return Optional.empty(); - } - - /** - * Checks if the name of a {@code DBType} corresponds to {@code name}.

- * This method is case-insensitive. - * - * @param name the name of the {@code DBType} - * @return if the {@code DBType} exists - * @see DBType#getForName(String) - */ - public static boolean exists(String name) { - for (DBType dbType : DBType.values()) { - if (dbType.getName().equalsIgnoreCase(name)) { - return true; - } - } - - return false; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/Database.java b/Plan/common/src/main/java/com/djrapitops/plan/db/Database.java deleted file mode 100644 index b0fb36f7e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/Database.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db; - -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.transactions.Transaction; - -import java.util.concurrent.Future; - -/** - * Interface for interacting with a Plan SQL database. - * - * @author Rsl1122 - */ -public interface Database { - - /** - * Initializes the Database. - *

- * Queries can be performed after this request has completed all required transactions for the database operations. - * - * @throws DBInitException if Database fails to initiate. - */ - void init(); - - void close(); - - /** - * Execute an SQL Query statement to get a result. - *

- * This method should only be called from an asynchronous thread. - * - * @param query QueryStatement to execute. - * @param Type of the object to be returned. - * @return Result of the query. - */ - T query(Query query); - - /** - * Execute an SQL Transaction. - * - * @param transaction Transaction to execute. - * @return Future that is finished when the transaction has been executed. - */ - Future executeTransaction(Transaction transaction); - - /** - * Used to get the {@code DBType} of the Database - * - * @return the {@code DBType} - * @see DBType - */ - DBType getType(); - - State getState(); - - enum State { - CLOSED, - PATCHING, - OPEN - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/H2DB.java b/Plan/common/src/main/java/com/djrapitops/plan/db/H2DB.java deleted file mode 100644 index b5f08b0e9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/H2DB.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db; - -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.db.tasks.KeepAliveTask; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DatabaseSettings; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plan.utilities.java.ThrowableUtils; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.PluginTask; -import com.djrapitops.plugin.task.RunnableFactory; -import dagger.Lazy; -import org.h2.jdbcx.JdbcDataSource; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Objects; - -/** - * Implementation of the H2 database - * - * @author Fuzzlemann - */ -public class H2DB extends SQLDB { - - private final File databaseFile; - private final String dbName; - private Connection connection; - private PluginTask connectionPingTask; - - private H2DB( - File databaseFile, - Locale locale, - PlanConfig config, - Lazy serverInfo, - NetworkContainer.Factory networkContainerFactory, - RunnableFactory runnableFactory, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(() -> serverInfo.get().getServerUUID(), locale, config, networkContainerFactory, runnableFactory, logger, errorHandler); - dbName = databaseFile.getName(); - this.databaseFile = databaseFile; - } - - @Override - public void setupDataSource() { - try { - connection = getNewConnection(databaseFile); - } catch (SQLException e) { - throw new DBInitException(e.getMessage(), e); - } - - startConnectionPingTask(); - } - - public Connection getNewConnection(File dbFile) throws SQLException { - String dbFilePath = dbFile.getAbsolutePath(); - - Connection newConnection = getConnectionFor(dbFilePath); - logger.debug("H2 " + dbName + ": Opened a new Connection"); - newConnection.setAutoCommit(false); - return newConnection; - } - - private Connection getConnectionFor(String dbFilePath) throws SQLException { - String username = config.get(DatabaseSettings.MYSQL_USER); - String password = config.get(DatabaseSettings.MYSQL_PASS); - - JdbcDataSource jdbcDataSource = new JdbcDataSource(); - jdbcDataSource.setURL("jdbc:h2:file:" + dbFilePath + ";mode=MySQL;DATABASE_TO_UPPER=false"); - jdbcDataSource.setUser(username); - jdbcDataSource.setPassword(password); - - return jdbcDataSource.getConnection(); - } - - private void startConnectionPingTask() { - stopConnectionPingTask(); - try { - // Maintains Connection. - connectionPingTask = runnableFactory.create("DBConnectionPingTask " + getType().getName(), - new KeepAliveTask(connection, () -> getNewConnection(databaseFile), logger, errorHandler) - ).runTaskTimerAsynchronously(60L * 20L, 60L * 20L); - } catch (Exception ignored) { - // Task failed to register because plugin is being disabled - } - } - - private void stopConnectionPingTask() { - if (connectionPingTask != null) { - try { - connectionPingTask.cancel(); - } catch (Exception ignored) { - // Sometimes task systems fail to cancel a task, - // usually this is called on disable, so no need for users to report this. - } - } - } - - @Override - public DBType getType() { - return DBType.H2; - } - - @Override - public Connection getConnection() throws SQLException { - if (connection == null) { - connection = getNewConnection(databaseFile); - } - - return connection; - } - - @Override - public void close() { - super.close(); - stopConnectionPingTask(); - - if (connection != null) { - logger.debug("H2 Connection close prompted by: " + ThrowableUtils.findCallerAfterClass(Thread.currentThread().getStackTrace(), H2DB.class)); - logger.debug("H2 " + dbName + ": Closed Connection"); - MiscUtils.close(connection); - } - } - - @Override - public void returnToPool(Connection connection) { - // Connection pool not in use, no action required. - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - H2DB h2DB = (H2DB) o; - return Objects.equals(dbName, h2DB.dbName); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), dbName); - } - - @Singleton - public static class Factory { - - private final Locale locale; - private final PlanConfig config; - private final Lazy serverInfo; - private final NetworkContainer.Factory networkContainerFactory; - private final RunnableFactory runnableFactory; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - private PlanFiles files; - - @Inject - public Factory( - Locale locale, - PlanConfig config, - PlanFiles files, - Lazy serverInfo, - NetworkContainer.Factory networkContainerFactory, - RunnableFactory runnableFactory, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.locale = locale; - this.config = config; - this.files = files; - this.serverInfo = serverInfo; - this.networkContainerFactory = networkContainerFactory; - this.runnableFactory = runnableFactory; - this.logger = logger; - this.errorHandler = errorHandler; - } - - public H2DB usingDefaultFile() { - return usingFileCalled("h2database"); - } - - public H2DB usingFileCalled(String fileName) { - return usingFile(files.getFileFromPluginFolder(fileName)); - } - - public H2DB usingFile(File databaseFile) { - return new H2DB(databaseFile, - locale, config, serverInfo, - networkContainerFactory, - runnableFactory, logger, errorHandler - ); - } - - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/MySQLDB.java b/Plan/common/src/main/java/com/djrapitops/plan/db/MySQLDB.java deleted file mode 100644 index 6d6d17474..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/MySQLDB.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db; - -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DatabaseSettings; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.benchmarking.Timings; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.RunnableFactory; -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import com.zaxxer.hikari.pool.HikariPool; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -/** - * @author Rsl1122 - */ -@Singleton -public class MySQLDB extends SQLDB { - - private static int increment = 1; - - protected DataSource dataSource; - - @Inject - public MySQLDB( - Locale locale, - PlanConfig config, - Lazy serverInfo, - NetworkContainer.Factory networkContainerFactory, - RunnableFactory runnableFactory, - PluginLogger pluginLogger, - Timings timings, - ErrorHandler errorHandler - ) { - super(() -> serverInfo.get().getServerUUID(), locale, config, networkContainerFactory, runnableFactory, pluginLogger, errorHandler); - } - - private static synchronized void increment() { - increment++; - } - - @Override - public DBType getType() { - return DBType.MYSQL; - } - - private void loadMySQLDriver() { - try { - Class.forName("com.mysql.cj.jdbc.Driver"); - } catch (ClassNotFoundException e) { - errorHandler.log(L.CRITICAL, this.getClass(), e); - } - } - - /** - * Setups the {@link HikariDataSource} - */ - @Override - public void setupDataSource() { - try { - if (Check.isVelocityAvailable()) loadMySQLDriver(); - - HikariConfig hikariConfig = new HikariConfig(); - - String host = config.get(DatabaseSettings.MYSQL_HOST); - String port = config.get(DatabaseSettings.MYSQL_PORT); - String database = config.get(DatabaseSettings.MYSQL_DATABASE); - String launchOptions = config.get(DatabaseSettings.MYSQL_LAUNCH_OPTIONS); - // REGEX: match "?", match "word=word&" *-times, match "word=word" - if (launchOptions.isEmpty() || !launchOptions.matches("\\?((\\w*=\\w*)&)*(\\w*=\\w*)")) { - launchOptions = "?rewriteBatchedStatements=true&useSSL=false"; - logger.error(locale.getString(PluginLang.DB_MYSQL_LAUNCH_OPTIONS_FAIL, launchOptions)); - } - hikariConfig.setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + database + launchOptions); - - String username = config.get(DatabaseSettings.MYSQL_USER); - String password = config.get(DatabaseSettings.MYSQL_PASS); - - hikariConfig.setUsername(username); - hikariConfig.setPassword(password); - - hikariConfig.setPoolName("Plan Connection Pool-" + increment); - increment(); - - hikariConfig.setAutoCommit(true); - hikariConfig.setMaximumPoolSize(8); - hikariConfig.setMaxLifetime(TimeUnit.MINUTES.toMillis(25L)); - hikariConfig.setLeakDetectionThreshold(TimeUnit.MINUTES.toMillis(10L)); - - this.dataSource = new HikariDataSource(hikariConfig); - } catch (HikariPool.PoolInitializationException e) { - throw new DBInitException("Failed to set-up HikariCP Datasource: " + e.getMessage(), e); - } - } - - @Override - public synchronized Connection getConnection() throws SQLException { - Connection connection = dataSource.getConnection(); - if (!connection.isValid(5)) { - connection.close(); - if (dataSource instanceof HikariDataSource) { - ((HikariDataSource) dataSource).close(); - } - try { - setupDataSource(); - // get new connection after restarting pool - connection = dataSource.getConnection(); - } catch (DBInitException e) { - throw new DBOpException("Failed to restart DataSource after a connection was invalid: " + e.getMessage(), e); - } - } - if (connection.getAutoCommit()) connection.setAutoCommit(false); - return connection; - } - - @Override - public void close() { - super.close(); - - if (dataSource instanceof HikariDataSource) { - ((HikariDataSource) dataSource).close(); - } - } - - @Override - public void returnToPool(Connection connection) { - try { - if (connection != null) { - connection.close(); - } - } catch (SQLException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - MySQLDB mySQLDB = (MySQLDB) o; - return Objects.equals(dataSource, mySQLDB.dataSource); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), dataSource); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/SQLDB.java b/Plan/common/src/main/java/com/djrapitops/plan/db/SQLDB.java deleted file mode 100644 index f5cde6cf9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/SQLDB.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db; - -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.api.exceptions.database.FatalDBException; -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.access.transactions.init.CreateIndexTransaction; -import com.djrapitops.plan.db.access.transactions.init.CreateTablesTransaction; -import com.djrapitops.plan.db.access.transactions.init.OperationCriticalTransaction; -import com.djrapitops.plan.db.patches.*; -import com.djrapitops.plan.system.DebugChannels; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.utilities.java.ThrowableUtils; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; -import com.google.common.util.concurrent.ThreadFactoryBuilder; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import java.util.concurrent.*; -import java.util.function.BiFunction; -import java.util.function.Supplier; - -/** - * Class containing main logic for different data related save and load functionality. - * - * @author Rsl1122 - */ -public abstract class SQLDB extends AbstractDatabase { - - private final Supplier serverUUIDSupplier; - - protected final Locale locale; - protected final PlanConfig config; - protected final NetworkContainer.Factory networkContainerFactory; - protected final RunnableFactory runnableFactory; - protected final PluginLogger logger; - protected final ErrorHandler errorHandler; - - private Supplier transactionExecutorServiceProvider; - private ExecutorService transactionExecutor; - - private final boolean devMode; - - public SQLDB( - Supplier serverUUIDSupplier, - Locale locale, - PlanConfig config, - NetworkContainer.Factory networkContainerFactory, RunnableFactory runnableFactory, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.serverUUIDSupplier = serverUUIDSupplier; - this.locale = locale; - this.config = config; - this.networkContainerFactory = networkContainerFactory; - this.runnableFactory = runnableFactory; - this.logger = logger; - this.errorHandler = errorHandler; - - devMode = config.get(PluginSettings.DEV_MODE); - - this.transactionExecutorServiceProvider = () -> Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Plan " + getClass().getSimpleName() + "-transaction-thread-%d").build()); - } - - @Override - public void init() { - List unfinishedTransactions = closeTransactionExecutor(transactionExecutor); - this.transactionExecutor = transactionExecutorServiceProvider.get(); - - setState(State.PATCHING); - - setupDataSource(); - setupDatabase(); - - for (Runnable unfinishedTransaction : unfinishedTransactions) { - transactionExecutor.submit(unfinishedTransaction); - } - - // If an OperationCriticalTransaction fails open is set to false. - // See executeTransaction method below. - if (getState() == State.CLOSED) { - throw new DBInitException("Failed to set-up Database"); - } - } - - private List closeTransactionExecutor(ExecutorService transactionExecutor) { - if (transactionExecutor == null || transactionExecutor.isShutdown() || transactionExecutor.isTerminated()) { - return Collections.emptyList(); - } - transactionExecutor.shutdown(); - try { - Long waitMs = config.getOrDefault(TimeSettings.DB_TRANSACTION_FINISH_WAIT_DELAY, TimeUnit.SECONDS.toMillis(20L)); - if (waitMs > TimeUnit.MINUTES.toMillis(5L)) { - logger.warn(TimeSettings.DB_TRANSACTION_FINISH_WAIT_DELAY.getPath() + " was set to over 5 minutes, using 5 min instead."); - waitMs = TimeUnit.MINUTES.toMillis(5L); - } - if (!transactionExecutor.awaitTermination(waitMs, TimeUnit.MILLISECONDS)) { - List unfinished = transactionExecutor.shutdownNow(); - int unfinishedCount = unfinished.size(); - if (unfinishedCount > 0) { - logger.warn(unfinishedCount + " unfinished database transactions were not executed."); - } - return unfinished; - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - return Collections.emptyList(); - } - - Patch[] patches() { - return new Patch[]{ - new Version10Patch(), - new GeoInfoLastUsedPatch(), - new SessionAFKTimePatch(), - new KillsServerIDPatch(), - new WorldTimesSeverIDPatch(), - new WorldsServerIDPatch(), - new NicknameLastSeenPatch(), - new VersionTableRemovalPatch(), - new DiskUsagePatch(), - new WorldsOptimizationPatch(), - new WorldTimesOptimizationPatch(), - new KillsOptimizationPatch(), - new SessionsOptimizationPatch(), - new PingOptimizationPatch(), - new NicknamesOptimizationPatch(), - new UserInfoOptimizationPatch(), - new GeoInfoOptimizationPatch(), - new TransferTableRemovalPatch(), - new IPAnonPatch(), - new BadAFKThresholdValuePatch(), - new DeleteIPHashesPatch(), - new ExtensionShowInPlayersTablePatch() - }; - } - - /** - * Ensures connection functions correctly and all tables exist. - *

- * Updates to latest schema. - */ - private void setupDatabase() { - executeTransaction(new CreateTablesTransaction()); - for (Patch patch : patches()) { - executeTransaction(patch); - } - executeTransaction(new OperationCriticalTransaction() { - @Override - protected void performOperations() { - if (getState() == State.PATCHING) setState(State.OPEN); - } - }); - registerIndexCreationTask(); - } - - private void registerIndexCreationTask() { - try { - runnableFactory.create("Database Index Creation", new AbsRunnable() { - @Override - public void run() { - executeTransaction(new CreateIndexTransaction()); - } - }).runTaskLaterAsynchronously(TimeAmount.toTicks(1, TimeUnit.MINUTES)); - } catch (Exception ignore) { - // Task failed to register because plugin is being disabled - } - } - - /** - * Set up the source for connections. - * - * @throws DBInitException If the DataSource fails to be initialized. - */ - public abstract void setupDataSource(); - - @Override - public void close() { - setState(State.CLOSED); - closeTransactionExecutor(transactionExecutor); - } - - public abstract Connection getConnection() throws SQLException; - - public abstract void returnToPool(Connection connection); - - @Override - public T query(Query query) { - accessLock.checkAccess(); - return query.executeQuery(this); - } - - @Override - public Future executeTransaction(Transaction transaction) { - if (getState() == State.CLOSED) { - throw new DBOpException("Transaction tried to execute although database is closed."); - } - - Exception origin = new Exception(); - - return CompletableFuture.supplyAsync(() -> { - accessLock.checkAccess(transaction); - if (devMode) { - logger.getDebugLogger().logOn(DebugChannels.SQL, "Executing: " + transaction.getClass().getSimpleName()); - } - transaction.executeTransaction(this); - return CompletableFuture.completedFuture(null); - }, getTransactionExecutor()).handle(errorHandler(origin)); - } - - private BiFunction, Throwable, CompletableFuture> errorHandler(Exception origin) { - return (obj, throwable) -> { - if (throwable == null) { - return CompletableFuture.completedFuture(null); - } - if (throwable instanceof FatalDBException) { - setState(State.CLOSED); - } - ThrowableUtils.appendEntryPointToCause(throwable, origin); - - errorHandler.log(L.ERROR, getClass(), throwable); - return CompletableFuture.completedFuture(null); - }; - } - - private ExecutorService getTransactionExecutor() { - if (transactionExecutor == null) { - transactionExecutor = transactionExecutorServiceProvider.get(); - } - return transactionExecutor; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SQLDB sqldb = (SQLDB) o; - return getType() == sqldb.getType(); - } - - @Override - public int hashCode() { - return Objects.hash(getType().getName()); - } - - public Supplier getServerUUIDSupplier() { - return serverUUIDSupplier; - } - - public NetworkContainer.Factory getNetworkContainerFactory() { - return networkContainerFactory; - } - - public void setTransactionExecutorServiceProvider(Supplier transactionExecutorServiceProvider) { - this.transactionExecutorServiceProvider = transactionExecutorServiceProvider; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/SQLiteDB.java b/Plan/common/src/main/java/com/djrapitops/plan/db/SQLiteDB.java deleted file mode 100644 index 2c4f7d4f5..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/SQLiteDB.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db; - -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.db.tasks.KeepAliveTask; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plan.utilities.java.ThrowableUtils; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.PluginTask; -import com.djrapitops.plugin.task.RunnableFactory; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Objects; - -/** - * @author Rsl1122 - */ -public class SQLiteDB extends SQLDB { - - private final File databaseFile; - private final String dbName; - private Connection connection; - private PluginTask connectionPingTask; - - private SQLiteDB( - File databaseFile, - Locale locale, - PlanConfig config, - Lazy serverInfo, - NetworkContainer.Factory networkContainerFactory, - RunnableFactory runnableFactory, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(() -> serverInfo.get().getServerUUID(), locale, config, networkContainerFactory, runnableFactory, logger, errorHandler); - dbName = databaseFile.getName(); - this.databaseFile = databaseFile; - } - - @Override - public void setupDataSource() { - try { - if (connection != null) connection.close(); - - connection = getNewConnection(databaseFile); - } catch (SQLException e) { - throw new DBInitException(e.getMessage(), e); - } - startConnectionPingTask(); - } - - public Connection getNewConnection(File dbFile) throws SQLException { - try { - Class.forName("org.sqlite.JDBC"); - } catch (ClassNotFoundException e) { - errorHandler.log(L.CRITICAL, this.getClass(), e); - return null; // Should never happen. - } - - String dbFilePath = dbFile.getAbsolutePath(); - - Connection newConnection = getConnectionFor(dbFilePath); - logger.debug("SQLite " + dbName + ": Opened a new Connection"); - newConnection.setAutoCommit(false); - return newConnection; - } - - private Connection getConnectionFor(String dbFilePath) throws SQLException { - try { - return DriverManager.getConnection("jdbc:sqlite:" + dbFilePath + "?journal_mode=WAL"); - } catch (SQLException ignored) { - logger.info(locale.getString(PluginLang.DB_NOTIFY_SQLITE_WAL)); - return DriverManager.getConnection("jdbc:sqlite:" + dbFilePath); - } - } - - private void startConnectionPingTask() { - stopConnectionPingTask(); - try { - // Maintains Connection. - connectionPingTask = runnableFactory.create("DBConnectionPingTask " + getType().getName(), - new KeepAliveTask(connection, () -> getNewConnection(databaseFile), logger, errorHandler) - ).runTaskTimerAsynchronously(60L * 20L, 60L * 20L); - } catch (Exception ignored) { - // Task failed to register because plugin is being disabled - } - } - - private void stopConnectionPingTask() { - if (connectionPingTask != null) { - try { - connectionPingTask.cancel(); - } catch (Exception ignored) { - // Sometimes task systems fail to cancel a task, - // usually this is called on disable, so no need for users to report this. - } - } - } - - @Override - public DBType getType() { - return DBType.SQLITE; - } - - @Override - public Connection getConnection() throws SQLException { - if (connection == null) { - connection = getNewConnection(databaseFile); - } - return connection; - } - - @Override - public void close() { - logger.debug("SQLite Connection close prompted by: " + ThrowableUtils.findCallerAfterClass(Thread.currentThread().getStackTrace(), SQLiteDB.class)); - - super.close(); - stopConnectionPingTask(); - - if (connection != null) { - logger.debug("SQLite " + dbName + ": Closed Connection"); - MiscUtils.close(connection); - } - } - - @Override - public void returnToPool(Connection connection) { - // Connection pool not in use, no action required. - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - SQLiteDB sqLiteDB = (SQLiteDB) o; - return Objects.equals(dbName, sqLiteDB.dbName); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), dbName); - } - - @Singleton - public static class Factory { - - private final Locale locale; - private final PlanConfig config; - private final Lazy serverInfo; - private final NetworkContainer.Factory networkContainerFactory; - private final RunnableFactory runnableFactory; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - private PlanFiles files; - - @Inject - public Factory( - Locale locale, - PlanConfig config, - PlanFiles files, - Lazy serverInfo, - NetworkContainer.Factory networkContainerFactory, - RunnableFactory runnableFactory, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.locale = locale; - this.config = config; - this.files = files; - this.serverInfo = serverInfo; - this.networkContainerFactory = networkContainerFactory; - this.runnableFactory = runnableFactory; - this.logger = logger; - this.errorHandler = errorHandler; - } - - public SQLiteDB usingDefaultFile() { - return usingFileCalled("database"); - } - - public SQLiteDB usingFileCalled(String fileName) { - return usingFile(files.getFileFromPluginFolder(fileName + ".db")); - } - - public SQLiteDB usingFile(File databaseFile) { - return new SQLiteDB(databaseFile, - locale, config, serverInfo, - networkContainerFactory, - runnableFactory, logger, errorHandler - ); - } - - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/ExecBatchStatement.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/ExecBatchStatement.java deleted file mode 100644 index 7fee837d1..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/ExecBatchStatement.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -/** - * SQL executing batch statement that closes appropriate elements. - * - * @author Rsl1122 - */ -public abstract class ExecBatchStatement extends ExecStatement { - - public ExecBatchStatement(String sql) { - super(sql); - } - - @Override - protected boolean callExecute(PreparedStatement statement) throws SQLException { - return statement.executeBatch().length > 0; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/ExecStatement.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/ExecStatement.java deleted file mode 100644 index 0bb5fbf41..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/ExecStatement.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; - -/** - * SQL executing statement that closes appropriate elements. - * - * @author Rsl1122 - */ -public abstract class ExecStatement implements Executable { - - private final String sql; - - public ExecStatement(String sql) { - this.sql = sql; - } - - @Override - public boolean execute(Connection connection) { - try { - try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { - return execute(preparedStatement); - } - } catch (SQLException e) { - throw DBOpException.forCause(sql, e); - } - } - - public boolean execute(PreparedStatement statement) throws SQLException { - try { - prepare(statement); - return callExecute(statement); - } finally { - statement.close(); - } - } - - protected boolean callExecute(PreparedStatement statement) throws SQLException { - if (sql.startsWith("UPDATE") || sql.startsWith("INSERT") || sql.startsWith("DELETE") || sql.startsWith("REPLACE")) { - return statement.executeUpdate() > 0; - } else { - statement.execute(); - return false; - } - } - - public abstract void prepare(PreparedStatement statement) throws SQLException; - - public String getSql() { - return sql; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/Executable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/Executable.java deleted file mode 100644 index e56530612..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/Executable.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access; - -import java.sql.Connection; - -/** - * Interface for everything that updates rows in the database. - * - * @author Rsl1122 - */ -public interface Executable { - - boolean execute(Connection connection); - - static Executable empty() { - return i -> true; - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/HasMoreThanZeroQueryStatement.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/HasMoreThanZeroQueryStatement.java deleted file mode 100644 index 7115ba6dd..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/HasMoreThanZeroQueryStatement.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access; - -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * SQL query of a COUNT statement that closes proper elements. - * - * @author Rsl1122 - */ -public abstract class HasMoreThanZeroQueryStatement extends QueryStatement { - - private String countColumnName = "c"; - - public HasMoreThanZeroQueryStatement(String sql) { - super(sql); - } - - public HasMoreThanZeroQueryStatement(String sql, String countColumnName) { - super(sql); - this.countColumnName = countColumnName; - } - - @Override - public Boolean processResults(ResultSet set) throws SQLException { - return set.next() && set.getInt(countColumnName) > 0; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/Query.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/Query.java deleted file mode 100644 index 321c9166a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/Query.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access; - -import com.djrapitops.plan.db.SQLDB; - -/** - * Interface for everything that returns results from the database. - * - * @param Type of the result. - * @author Rsl1122 - */ -public interface Query { - - T executeQuery(SQLDB db); - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAPIExecutable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAPIExecutable.java deleted file mode 100644 index 1e86f3d89..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAPIExecutable.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.query.QueryService; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; - -public class QueryAPIExecutable implements Executable { - - private final String sql; - private final QueryService.ThrowingConsumer statement; - - public QueryAPIExecutable( - String sql, - QueryService.ThrowingConsumer statement - ) { - this.sql = sql; - this.statement = statement; - } - - @Override - public boolean execute(Connection connection) { - try { - try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { - statement.accept(preparedStatement); - return true; - } - } catch (SQLException e) { - throw DBOpException.forCause(sql, e); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAPIQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAPIQuery.java deleted file mode 100644 index bb882a672..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAPIQuery.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.query.QueryService; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; - -public class QueryAPIQuery implements Query { - - private final QueryService.ThrowingFunction performQuery; - private String sql; - - public QueryAPIQuery( - String sql, - QueryService.ThrowingFunction performQuery - ) { - this.sql = sql; - this.performQuery = performQuery; - } - - @Override - public T executeQuery(SQLDB db) { - Connection connection = null; - try { - connection = db.getConnection(); - try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { - return performQuery.apply(preparedStatement); - } - } catch (SQLException e) { - throw DBOpException.forCause(sql, e); - } finally { - db.returnToPool(connection); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAllStatement.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAllStatement.java deleted file mode 100644 index 9c2e935de..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryAllStatement.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * SQL query that doesn't require preparing that closes proper elements. - * - * @author Rsl1122 - */ -public abstract class QueryAllStatement extends QueryStatement { - public QueryAllStatement(String sql) { - super(sql); - } - - public QueryAllStatement(String sql, int fetchSize) { - super(sql, fetchSize); - } - - @Override - public void prepare(PreparedStatement statement) throws SQLException { - /* None Required */ - } - - @Override - public abstract T processResults(ResultSet set) throws SQLException; -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryStatement.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryStatement.java deleted file mode 100644 index 24082935e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/QueryStatement.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.SQLDB; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * SQL query that closes proper elements. - * - * @author Rsl1122 - */ -public abstract class QueryStatement implements Query { - - private final String sql; - private final int fetchSize; - - public QueryStatement(String sql) { - this(sql, 10); - } - - public QueryStatement(String sql, int fetchSize) { - this.sql = sql; - this.fetchSize = fetchSize; - } - - @Override - public T executeQuery(SQLDB db) { - Connection connection = null; - try { - connection = db.getConnection(); - try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { - return executeQuery(preparedStatement); - } - } catch (SQLException e) { - throw DBOpException.forCause(sql, e); - } finally { - db.returnToPool(connection); - } - } - - public T executeQuery(PreparedStatement statement) throws SQLException { - try { - statement.setFetchSize(fetchSize); - prepare(statement); - try (ResultSet set = statement.executeQuery()) { - return processResults(set); - } - } finally { - statement.close(); - } - } - - public abstract void prepare(PreparedStatement statement) throws SQLException; - - public abstract T processResults(ResultSet set) throws SQLException; - - public String getSql() { - return sql; - } - - @Override - public String toString() { - return "Query (" + sql + ')'; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/DataStoreQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/DataStoreQueries.java deleted file mode 100644 index dfbf6c388..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/DataStoreQueries.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries; - -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.data.time.GMTimes; -import com.djrapitops.plan.db.access.ExecBatchStatement; -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plugin.utilities.Verify; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -/** - * Static method class for single item store queries. - * - * @author Rsl1122 - */ -public class DataStoreQueries { - - private DataStoreQueries() { - /* static method class */ - } - - /** - * Store the used command in the database. - * - * @param serverUUID UUID of the Plan server. - * @param commandName Name of the command that was used. - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeUsedCommandInformation(UUID serverUUID, String commandName) { - return connection -> { - if (!updateCommandUsage(serverUUID, commandName).execute(connection)) { - insertNewCommandUsage(serverUUID, commandName).execute(connection); - } - return false; - }; - } - - private static Executable updateCommandUsage(UUID serverUUID, String commandName) { - return new ExecStatement(CommandUseTable.UPDATE_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - statement.setString(2, commandName); - } - }; - } - - private static Executable insertNewCommandUsage(UUID serverUUID, String commandName) { - return new ExecStatement(CommandUseTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, commandName); - statement.setInt(2, 1); - statement.setString(3, serverUUID.toString()); - } - }; - } - - /** - * Store a finished session in the database. - * - * @param session Session, of which {@link Session#endSession(long)} has been called. - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - * @throws IllegalArgumentException If {@link Session#endSession(long)} has not yet been called. - */ - public static Executable storeSession(Session session) { - Verify.isTrue(session.supports(SessionKeys.END), () -> new IllegalArgumentException("Attempted to save a session that has not ended.")); - return connection -> { - storeSessionInformation(session).execute(connection); - storeSessionKills(session).execute(connection); - return storeSessionWorldTimes(session).execute(connection); - }; - } - - private static Executable storeSessionInformation(Session session) { - return new ExecStatement(SessionsTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, session.getUnsafe(SessionKeys.UUID).toString()); - statement.setLong(2, session.getUnsafe(SessionKeys.START)); - statement.setLong(3, session.getUnsafe(SessionKeys.END)); - statement.setInt(4, session.getValue(SessionKeys.DEATH_COUNT).orElse(0)); - statement.setInt(5, session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0)); - statement.setLong(6, session.getValue(SessionKeys.AFK_TIME).orElse(0L)); - statement.setString(7, session.getUnsafe(SessionKeys.SERVER_UUID).toString()); - } - }; - } - - private static Executable storeSessionKills(Session session) { - return new ExecBatchStatement(KillsTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - KillsTable.addSessionKillsToBatch(statement, session); - } - }; - } - - public static Executable insertWorldName(UUID serverUUID, String worldName) { - return new ExecStatement(WorldTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, worldName); - statement.setString(2, serverUUID.toString()); - } - }; - } - - private static Executable storeSessionWorldTimes(Session session) { - if (session.getValue(SessionKeys.WORLD_TIMES).map(times -> times.getWorldTimes().isEmpty()).orElse(true)) { - return Executable.empty(); - } - return new ExecBatchStatement(WorldTimesTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - WorldTimesTable.addSessionWorldTimesToBatch(statement, session, GMTimes.getGMKeyArray()); - } - }; - } - - /** - * Store player's Geo Information in the database. - * - * @param playerUUID UUID of the player. - * @param geoInfo GeoInfo of the player. - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeGeoInfo(UUID playerUUID, GeoInfo geoInfo) { - return connection -> { - if (!updateGeoInfo(playerUUID, geoInfo).execute(connection)) { - return insertGeoInfo(playerUUID, geoInfo).execute(connection); - } - return false; - }; - } - - private static Executable updateGeoInfo(UUID playerUUID, GeoInfo geoInfo) { - return new ExecStatement(GeoInfoTable.UPDATE_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, geoInfo.getDate()); - statement.setString(2, playerUUID.toString()); - statement.setString(3, geoInfo.getGeolocation()); - } - }; - } - - private static Executable insertGeoInfo(UUID playerUUID, GeoInfo geoInfo) { - return new ExecStatement(GeoInfoTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - statement.setString(2, geoInfo.getIp()); - statement.setString(3, geoInfo.getGeolocation()); - statement.setLong(4, geoInfo.getDate()); - } - }; - } - - /** - * Store a BaseUser for the player in the database. - * - * @param playerUUID UUID of the player. - * @param registered Time the player registered on the server for the first time. - * @param playerName Name of the player. - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable registerBaseUser(UUID playerUUID, long registered, String playerName) { - return new ExecStatement(UsersTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - statement.setString(2, playerName); - statement.setLong(3, registered); - statement.setInt(4, 0); // times kicked - } - }; - } - - /** - * Update player's name in the database in case they have changed it. - * - * @param playerUUID UUID of the player. - * @param playerName Name of the player. - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable updatePlayerName(UUID playerUUID, String playerName) { - String sql = "UPDATE " + UsersTable.TABLE_NAME + " SET " + UsersTable.USER_NAME + "=?" + - " WHERE " + UsersTable.USER_UUID + "=?"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerName); - statement.setString(2, playerUUID.toString()); - } - }; - } - - /** - * Store UserInfo about a player on a server in the database. - * - * @param playerUUID UUID of the player. - * @param registered Time the player registered on the server. - * @param serverUUID UUID of the Plan server. - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable registerUserInfo(UUID playerUUID, long registered, UUID serverUUID) { - return new ExecStatement(UserInfoTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - statement.setLong(2, registered); - statement.setString(3, serverUUID.toString()); - statement.setBoolean(4, false); // Banned - statement.setBoolean(5, false); // Operator - } - }; - } - - /** - * Store Ping data of a player on a server. - * - * @param playerUUID UUID of the player. - * @param serverUUID UUID of the Plan server. - * @param ping Ping data entry - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storePing(UUID playerUUID, UUID serverUUID, Ping ping) { - return new ExecStatement(PingTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - statement.setString(2, serverUUID.toString()); - statement.setLong(3, ping.getDate()); - statement.setInt(4, ping.getMin()); - statement.setInt(5, ping.getMax()); - statement.setDouble(6, ping.getAverage()); - } - }; - } - - /** - * Store TPS data of a server. - * - * @param serverUUID UUID of the Plan server. - * @param tps TPS data entry - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeTPS(UUID serverUUID, TPS tps) { - return new ExecStatement(TPSTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - statement.setLong(2, tps.getDate()); - statement.setDouble(3, tps.getTicksPerSecond()); - statement.setInt(4, tps.getPlayers()); - statement.setDouble(5, tps.getCPUUsage()); - statement.setLong(6, tps.getUsedMemory()); - statement.setDouble(7, tps.getEntityCount()); - statement.setDouble(8, tps.getChunksLoaded()); - statement.setLong(9, tps.getFreeDiskSpace()); - } - }; - } - - /** - * Store nickname information of a player on a server. - * - * @param playerUUID UUID of the player. - * @param nickname Nickname information. - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storePlayerNickname(UUID playerUUID, Nickname nickname) { - return connection -> { - if (!updatePlayerNickname(playerUUID, nickname).execute(connection)) { - insertPlayerNickname(playerUUID, nickname).execute(connection); - } - return false; - }; - } - - private static Executable updatePlayerNickname(UUID playerUUID, Nickname nickname) { - return new ExecStatement(NicknamesTable.UPDATE_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, nickname.getDate()); - statement.setString(2, nickname.getName()); - statement.setString(3, playerUUID.toString()); - statement.setString(4, nickname.getServerUUID().toString()); - } - }; - } - - private static Executable insertPlayerNickname(UUID playerUUID, Nickname nickname) { - return new ExecStatement(NicknamesTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - statement.setString(2, nickname.getServerUUID().toString()); - statement.setString(3, nickname.getName()); - statement.setLong(4, nickname.getDate()); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeFetchQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeFetchQueries.java deleted file mode 100644 index 645bd024c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeFetchQueries.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.builders.TPSBuilder; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.sql.tables.CommandUseTable; -import com.djrapitops.plan.db.sql.tables.ServerTable; -import com.djrapitops.plan.db.sql.tables.TPSTable; -import com.djrapitops.plan.db.sql.tables.WorldTable; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -/** - * Static method class for queries that use large amount of memory. - * - * @author Rsl1122 - */ -public class LargeFetchQueries { - - private LargeFetchQueries() { - /* Static method class */ - } - - /** - * Query database for all command usage data. - * - * @return Multi map: Server UUID - (Command name - Usage count) - */ - public static Query>> fetchAllCommandUsageData() { - String serverIDColumn = ServerTable.TABLE_NAME + "." + ServerTable.SERVER_ID; - String serverUUIDColumn = ServerTable.TABLE_NAME + "." + ServerTable.SERVER_UUID + " as s_uuid"; - String sql = "SELECT " + - CommandUseTable.COMMAND + ", " + - CommandUseTable.TIMES_USED + ", " + - serverUUIDColumn + - " FROM " + CommandUseTable.TABLE_NAME + - " INNER JOIN " + ServerTable.TABLE_NAME + " on " + serverIDColumn + "=" + CommandUseTable.SERVER_ID; - - return new QueryAllStatement>>(sql, 10000) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> map = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString("s_uuid")); - - Map serverMap = map.getOrDefault(serverUUID, new HashMap<>()); - - String command = set.getString(CommandUseTable.COMMAND); - int timesUsed = set.getInt(CommandUseTable.TIMES_USED); - - serverMap.put(command, timesUsed); - map.put(serverUUID, serverMap); - } - return map; - } - }; - } - - /** - * Query database for TPS data. - * - * @return Map: Server UUID - List of TPS data - */ - public static Query>> fetchAllTPSData() { - String serverIDColumn = ServerTable.TABLE_NAME + "." + ServerTable.SERVER_ID; - String serverUUIDColumn = ServerTable.TABLE_NAME + "." + ServerTable.SERVER_UUID + " as s_uuid"; - String sql = "SELECT " + - TPSTable.DATE + ", " + - TPSTable.TPS + ", " + - TPSTable.PLAYERS_ONLINE + ", " + - TPSTable.CPU_USAGE + ", " + - TPSTable.RAM_USAGE + ", " + - TPSTable.ENTITIES + ", " + - TPSTable.CHUNKS + ", " + - TPSTable.FREE_DISK + ", " + - serverUUIDColumn + - " FROM " + TPSTable.TABLE_NAME + - " INNER JOIN " + ServerTable.TABLE_NAME + " on " + serverIDColumn + "=" + TPSTable.SERVER_ID; - - return new QueryAllStatement>>(sql, 50000) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> serverMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString("s_uuid")); - - List tpsList = serverMap.getOrDefault(serverUUID, new ArrayList<>()); - - TPS tps = TPSBuilder.get() - .date(set.getLong(TPSTable.DATE)) - .tps(set.getDouble(TPSTable.TPS)) - .playersOnline(set.getInt(TPSTable.PLAYERS_ONLINE)) - .usedCPU(set.getDouble(TPSTable.CPU_USAGE)) - .usedMemory(set.getLong(TPSTable.RAM_USAGE)) - .entities(set.getInt(TPSTable.ENTITIES)) - .chunksLoaded(set.getInt(TPSTable.CHUNKS)) - .freeDiskSpace(set.getLong(TPSTable.FREE_DISK)) - .toTPS(); - - tpsList.add(tps); - serverMap.put(serverUUID, tpsList); - } - return serverMap; - } - }; - } - - /** - * Query database for world names. - * - * @return Map: Server UUID - List of world names - */ - public static Query>> fetchAllWorldNames() { - String sql = "SELECT * FROM " + WorldTable.TABLE_NAME; - - return new QueryAllStatement>>(sql, 1000) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> worldMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(WorldTable.SERVER_UUID)); - Collection worlds = worldMap.getOrDefault(serverUUID, new HashSet<>()); - worlds.add(set.getString(WorldTable.NAME)); - worldMap.put(serverUUID, worlds); - } - return worldMap; - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeStoreQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeStoreQueries.java deleted file mode 100644 index 6014fc86e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeStoreQueries.java +++ /dev/null @@ -1,422 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries; - -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.data.container.*; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.data.time.GMTimes; -import com.djrapitops.plan.db.access.ExecBatchStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plugin.utilities.Verify; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * Static method class for large storage queries. - * - * @author Rsl1122 - */ -public class LargeStoreQueries { - - private LargeStoreQueries() { - /* Static method class */ - } - - /** - * Execute a big batch of command use insert statements. - * - * @param ofServers Multi map: Server UUID - (Command name - Usage count) - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeAllCommandUsageData(Map> ofServers) { - if (ofServers.isEmpty()) { - return Executable.empty(); - } - - return new ExecBatchStatement(CommandUseTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - // Every Server - for (Map.Entry> serverEntry : ofServers.entrySet()) { - UUID serverUUID = serverEntry.getKey(); - // Every Command - for (Map.Entry entry : serverEntry.getValue().entrySet()) { - String command = entry.getKey(); - int timesUsed = entry.getValue(); - - statement.setString(1, command); - statement.setInt(2, timesUsed); - statement.setString(3, serverUUID.toString()); - statement.addBatch(); - } - } - } - }; - } - - /** - * Execute a big batch of GeoInfo insert statements. - * - * @param ofUsers Map: Player UUID - List of GeoInfo - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeAllGeoInformation(Map> ofUsers) { - if (Verify.isEmpty(ofUsers)) { - return Executable.empty(); - } - - return new ExecBatchStatement(GeoInfoTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - // Every User - for (Map.Entry> playerEntry : ofUsers.entrySet()) { - UUID playerUUID = playerEntry.getKey(); - // Every GeoInfo - for (GeoInfo info : playerEntry.getValue()) { - String ip = info.getIp(); - String geoLocation = info.getGeolocation(); - long lastUsed = info.getDate(); - - statement.setString(1, playerUUID.toString()); - statement.setString(2, ip); - statement.setString(3, geoLocation); - statement.setLong(4, lastUsed); - - statement.addBatch(); - } - } - } - }; - } - - /** - * Execute a big batch of nickname insert statements. - * - * @param ofServersAndUsers Multimap: Server UUID - (Player UUID - List of nicknames) - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeAllNicknameData(Map>> ofServersAndUsers) { - if (Verify.isEmpty(ofServersAndUsers)) { - return Executable.empty(); - } - - return new ExecBatchStatement(NicknamesTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - // Every Server - for (Map.Entry>> serverEntry : ofServersAndUsers.entrySet()) { - UUID serverUUID = serverEntry.getKey(); - // Every User - for (Map.Entry> entry : serverEntry.getValue().entrySet()) { - UUID uuid = entry.getKey(); - // Every Nickname - List nicknames = entry.getValue(); - for (Nickname nickname : nicknames) { - statement.setString(1, uuid.toString()); - statement.setString(2, serverUUID.toString()); - statement.setString(3, nickname.getName()); - statement.setLong(4, nickname.getDate()); - statement.addBatch(); - } - } - } - } - }; - } - - /** - * Execute a big batch of web user insert statements. - * - * @param users Collection of Plan WebUsers. - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeAllPlanWebUsers(Collection users) { - if (Verify.isEmpty(users)) { - return Executable.empty(); - } - - return new ExecBatchStatement(SecurityTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (WebUser user : users) { - String userName = user.getName(); - String pass = user.getSaltedPassHash(); - int permLvl = user.getPermLevel(); - - statement.setString(1, userName); - statement.setString(2, pass); - statement.setInt(3, permLvl); - statement.addBatch(); - } - } - }; - } - - /** - * Execute a big batch of server infromation insert statements. - * - * @param servers Collection of Plan Servers. - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeAllPlanServerInformation(Collection servers) { - if (Verify.isEmpty(servers)) { - return Executable.empty(); - } - - return new ExecBatchStatement(ServerTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (Server info : servers) { - UUID uuid = info.getUuid(); - String name = info.getName(); - String webAddress = info.getWebAddress(); - - if (uuid == null) { - continue; - } - - statement.setString(1, uuid.toString()); - statement.setString(2, name); - statement.setString(3, webAddress); - statement.setBoolean(4, true); - statement.setInt(5, info.getMaxPlayers()); - statement.addBatch(); - } - } - }; - } - - /** - * Execute a big batch of TPS insert statements. - * - * @param ofServers Map: Server UUID - List of TPS data - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeAllTPSData(Map> ofServers) { - if (Verify.isEmpty(ofServers)) { - return Executable.empty(); - } - - return new ExecBatchStatement(TPSTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - // Every Server - for (Map.Entry> entry : ofServers.entrySet()) { - UUID serverUUID = entry.getKey(); - // Every TPS Data point - List tpsList = entry.getValue(); - for (TPS tps : tpsList) { - statement.setString(1, serverUUID.toString()); - statement.setLong(2, tps.getDate()); - statement.setDouble(3, tps.getTicksPerSecond()); - statement.setInt(4, tps.getPlayers()); - statement.setDouble(5, tps.getCPUUsage()); - statement.setLong(6, tps.getUsedMemory()); - statement.setDouble(7, tps.getEntityCount()); - statement.setDouble(8, tps.getChunksLoaded()); - statement.setLong(9, tps.getFreeDiskSpace()); - statement.addBatch(); - } - } - } - }; - } - - /** - * Execute a big batch of Per server UserInfo insert statements. - * - * @param ofServers Map: Server UUID - List of user information - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storePerServerUserInformation(Map> ofServers) { - if (Verify.isEmpty(ofServers)) { - return Executable.empty(); - } - - return new ExecBatchStatement(UserInfoTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - // Every Server - for (Map.Entry> entry : ofServers.entrySet()) { - UUID serverUUID = entry.getKey(); - // Every User - for (UserInfo user : entry.getValue()) { - statement.setString(1, user.getPlayerUuid().toString()); - statement.setLong(2, user.getRegistered()); - statement.setString(3, serverUUID.toString()); - statement.setBoolean(4, user.isBanned()); - statement.setBoolean(5, user.isOperator()); - statement.addBatch(); - } - } - } - }; - } - - /** - * Execute a big batch of world name insert statements. - * - * @param ofServers Map: Server UUID - Collection of world names - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeAllWorldNames(Map> ofServers) { - if (Verify.isEmpty(ofServers)) { - return Executable.empty(); - } - - return new ExecBatchStatement(WorldTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (Map.Entry> entry : ofServers.entrySet()) { - UUID serverUUID = entry.getKey(); - for (String world : entry.getValue()) { - statement.setString(1, world); - statement.setString(2, serverUUID.toString()); - statement.addBatch(); - } - } - } - }; - } - - /** - * Execute a big batch of user information insert statements. - * - * @param ofUsers Collection of BaseUsers - * @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction} - */ - public static Executable storeAllCommonUserInformation(Collection ofUsers) { - if (Verify.isEmpty(ofUsers)) { - return Executable.empty(); - } - - return new ExecBatchStatement(UsersTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (BaseUser user : ofUsers) { - statement.setString(1, user.getUuid().toString()); - statement.setString(2, user.getName()); - statement.setLong(3, user.getRegistered()); - statement.setInt(4, user.getTimesKicked()); - statement.addBatch(); - } - } - }; - } - - public static Executable storeAllSessionsWithoutKillOrWorldData(Collection sessions) { - if (Verify.isEmpty(sessions)) { - return Executable.empty(); - } - - return new ExecBatchStatement(SessionsTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (Session session : sessions) { - statement.setString(1, session.getUnsafe(SessionKeys.UUID).toString()); - statement.setLong(2, session.getUnsafe(SessionKeys.START)); - statement.setLong(3, session.getUnsafe(SessionKeys.END)); - statement.setInt(4, session.getValue(SessionKeys.DEATH_COUNT).orElse(0)); - statement.setInt(5, session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0)); - statement.setLong(6, session.getValue(SessionKeys.AFK_TIME).orElse(0L)); - statement.setString(7, session.getUnsafe(SessionKeys.SERVER_UUID).toString()); - statement.addBatch(); - } - } - }; - } - - public static Executable storeAllSessionsWithKillAndWorldData(Collection sessions) { - return connection -> { - storeAllSessionsWithoutKillOrWorldData(sessions).execute(connection); - storeSessionKillData(sessions).execute(connection); - return storeSessionWorldTimeData(sessions).execute(connection); - }; - } - - private static Executable storeSessionKillData(Collection sessions) { - if (Verify.isEmpty(sessions)) { - return Executable.empty(); - } - - return new ExecBatchStatement(KillsTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (Session session : sessions) { - KillsTable.addSessionKillsToBatch(statement, session); - } - } - }; - } - - private static Executable storeSessionWorldTimeData(Collection sessions) { - if (Verify.isEmpty(sessions)) { - return Executable.empty(); - } - - return new ExecBatchStatement(WorldTimesTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - String[] gms = GMTimes.getGMKeyArray(); - - for (Session session : sessions) { - WorldTimesTable.addSessionWorldTimesToBatch(statement, session, gms); - } - } - }; - } - - public static Executable storeAllPingData(Map> ofUsers) { - if (Verify.isEmpty(ofUsers)) { - return Executable.empty(); - } - - return new ExecBatchStatement(PingTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (Map.Entry> entry : ofUsers.entrySet()) { - UUID uuid = entry.getKey(); - List pings = entry.getValue(); - for (Ping ping : pings) { - UUID serverUUID = ping.getServerUUID(); - long date = ping.getDate(); - int minPing = ping.getMin(); - int maxPing = ping.getMax(); - double avgPing = ping.getAverage(); - - statement.setString(1, uuid.toString()); - statement.setString(2, serverUUID.toString()); - statement.setLong(3, date); - statement.setInt(4, minPing); - statement.setInt(5, maxPing); - statement.setDouble(6, avgPing); - statement.addBatch(); - } - } - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/PerServerAggregateQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/PerServerAggregateQueries.java deleted file mode 100644 index 185cc67a2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/PerServerAggregateQueries.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries; - -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.KillsTable; -import com.djrapitops.plan.db.sql.tables.SessionsTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Static method class for queries that count together counts for a player on a per server basis. - *

- * Example: - * Fetch how much a player has played on servers - * - * @author Rsl1122 - */ -public class PerServerAggregateQueries { - - private PerServerAggregateQueries() { - /* Static method class */ - } - - /** - * Find last seen date on servers. - * - * @param playerUUID UUID of the player. - * @return Map: Server UUID - Last seen epoch ms. - */ - public static Query> lastSeenOnServers(UUID playerUUID) { - String sql = "SELECT MAX(" + SessionsTable.SESSION_END + ") as last_seen, " + - SessionsTable.SERVER_UUID + - FROM + SessionsTable.TABLE_NAME + - WHERE + SessionsTable.USER_UUID + "=?" + - GROUP_BY + SessionsTable.SERVER_UUID; - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map lastSeenMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(SessionsTable.SERVER_UUID)); - long lastSeen = set.getLong("last_seen"); - lastSeenMap.put(serverUUID, lastSeen); - } - return lastSeenMap; - } - }; - } - - /** - * Find player kill count on servers. - * - * @param playerUUID UUID of the player. - * @return Map: Server UUID - Player kill count - */ - public static Query> playerKillCountOnServers(UUID playerUUID) { - String sql = "SELECT COUNT(1) as kill_count, " + KillsTable.SERVER_UUID + FROM + KillsTable.TABLE_NAME + - WHERE + KillsTable.KILLER_UUID + "=?" + - GROUP_BY + KillsTable.SERVER_UUID; - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map killCountMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(SessionsTable.SERVER_UUID)); - int lastSeen = set.getInt("kill_count"); - killCountMap.put(serverUUID, lastSeen); - } - return killCountMap; - } - }; - } - - /** - * Find mob kill count on servers. - * - * @param playerUUID UUID of the player. - * @return Map: Server UUID - Mob kill count - */ - public static Query> mobKillCountOnServers(UUID playerUUID) { - String sql = "SELECT SUM(" + SessionsTable.MOB_KILLS + ") as kill_count, " + - SessionsTable.SERVER_UUID + FROM + SessionsTable.TABLE_NAME + - WHERE + SessionsTable.USER_UUID + "=?" + - GROUP_BY + SessionsTable.SERVER_UUID; - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map killCountMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(SessionsTable.SERVER_UUID)); - int lastSeen = set.getInt("kill_count"); - killCountMap.put(serverUUID, lastSeen); - } - return killCountMap; - } - }; - } - - /** - * Find how many times a player killed the player on servers. - * - * @param playerUUID UUID of the player. - * @return Map: Server UUID - Mob kill count - */ - public static Query> playerDeathCountOnServers(UUID playerUUID) { - String sql = "SELECT COUNT(1) as death_count, " + KillsTable.SERVER_UUID + FROM + KillsTable.TABLE_NAME + - WHERE + KillsTable.VICTIM_UUID + "=?" + - GROUP_BY + KillsTable.SERVER_UUID; - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map killCountMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(SessionsTable.SERVER_UUID)); - int lastSeen = set.getInt("death_count"); - killCountMap.put(serverUUID, lastSeen); - } - return killCountMap; - } - }; - } - - public static Query> totalDeathCountOnServers(UUID playerUUID) { - String sql = "SELECT SUM(" + SessionsTable.DEATHS + ") as death_count, " + - SessionsTable.SERVER_UUID + FROM + SessionsTable.TABLE_NAME + - WHERE + SessionsTable.USER_UUID + "=?" + - GROUP_BY + SessionsTable.SERVER_UUID; - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map killCountMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(SessionsTable.SERVER_UUID)); - int lastSeen = set.getInt("death_count"); - killCountMap.put(serverUUID, lastSeen); - } - return killCountMap; - } - }; - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/PlayerFetchQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/PlayerFetchQueries.java deleted file mode 100644 index 95e09b5ab..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/PlayerFetchQueries.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries; - -import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.UserInfoTable; -import com.djrapitops.plan.db.sql.tables.UsersTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Optional; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Static method class for queries that return information related to a single player. - * - * @author Rsl1122 - */ -public class PlayerFetchQueries { - - private PlayerFetchQueries() { - /* static method class */ - } - - /** - * Query Player's name by player's UUID. - * - * @param playerUUID UUID of the player. - * @return Optional, Name if found. - */ - public static Query> playerUserName(UUID playerUUID) { - String sql = "SELECT " + UsersTable.USER_NAME + - FROM + UsersTable.TABLE_NAME + - WHERE + UsersTable.USER_UUID + "=?"; - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Optional processResults(ResultSet set) throws SQLException { - if (set.next()) { - return Optional.of(set.getString(UsersTable.USER_NAME)); - } - return Optional.empty(); - } - }; - } - - /** - * Check if the player's BaseUser is registered. - * - * @param playerUUID UUID of the player. - * @return True if the player's BaseUser is found - */ - public static Query isPlayerRegistered(UUID playerUUID) { - String sql = "SELECT COUNT(1) as c FROM " + UsersTable.TABLE_NAME + - WHERE + UsersTable.USER_UUID + "=?"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - }; - } - - /** - * Check if the player's UserInfo is registered. - * - * @param playerUUID UUID of the player. - * @param serverUUID UUID of the Plan server. - * @return True if the player's UserInfo is found - */ - public static Query isPlayerRegisteredOnServer(UUID playerUUID, UUID serverUUID) { - String sql = "SELECT COUNT(1) as c FROM " + UserInfoTable.TABLE_NAME + - WHERE + UserInfoTable.USER_UUID + "=?" + - AND + UserInfoTable.SERVER_UUID + "=?"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - statement.setString(2, serverUUID.toString()); - } - }; - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/ServerAggregateQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/ServerAggregateQueries.java deleted file mode 100644 index 53133a9dc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/ServerAggregateQueries.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries; - -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.*; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Static method class for queries that count how many entries of particular kinds there are for a server. - * - * @author Rsl1122 - */ -public class ServerAggregateQueries { - - private ServerAggregateQueries() { - /* Static method class */ - } - - /** - * Count how many users are in the Plan database. - * - * @return Count of base users, all users in a network after Plan installation. - */ - public static Query baseUserCount() { - String sql = "SELECT COUNT(1) as c FROM " + UsersTable.TABLE_NAME; - return new QueryAllStatement(sql) { - @Override - public Integer processResults(ResultSet set) throws SQLException { - return set.next() ? set.getInt("c") : 0; - } - }; - } - - /** - * Count how many users are on a server in the network. - * - * @param serverUUID ServerUUID of the Plan server. - * @return Count of users registered to that server after Plan installation. - */ - public static Query serverUserCount(UUID serverUUID) { - String sql = "SELECT COUNT(1) as c FROM " + UserInfoTable.TABLE_NAME + - WHERE + UserInfoTable.SERVER_UUID + "=?"; - return new QueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Integer processResults(ResultSet set) throws SQLException { - return set.next() ? set.getInt("c") : 0; - } - }; - } - - /** - * Count how many users are on each server in the network. - *

- * Please note that counts can overlap as one user can join multiple servers. - * Use {@link ServerAggregateQueries#baseUserCount()} if you want to count total number of users. - * - * @return Map: Server UUID - Count of users registered to that server - */ - public static Query> serverUserCounts() { - String sql = "SELECT COUNT(1) as c, " + UserInfoTable.SERVER_UUID + FROM + UserInfoTable.TABLE_NAME + - GROUP_BY + UserInfoTable.SERVER_UUID; - return new QueryAllStatement>(sql, 100) { - @Override - public Map processResults(ResultSet set) throws SQLException { - Map ofServer = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(UserInfoTable.SERVER_UUID)); - int count = set.getInt("c"); - ofServer.put(serverUUID, count); - } - return ofServer; - } - }; - } - - /** - * Count how many times commands have been used on a server. - * - * @param serverUUID Server UUID of the Plan server. - * @return Map: Lowercase used command - Count of use times. - */ - public static Query> commandUsageCounts(UUID serverUUID) { - String sql = SELECT + CommandUseTable.COMMAND + ", " + CommandUseTable.TIMES_USED + FROM + CommandUseTable.TABLE_NAME + - WHERE + CommandUseTable.SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID; - - return new QueryStatement>(sql, 5000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map commandUse = new HashMap<>(); - while (set.next()) { - String cmd = set.getString(CommandUseTable.COMMAND).toLowerCase(); - int amountUsed = set.getInt(CommandUseTable.TIMES_USED); - commandUse.put(cmd, amountUsed); - } - return commandUse; - } - }; - } - - public static Query> networkGeolocationCounts() { - String subQuery1 = SELECT + - GeoInfoTable.USER_UUID + ", " + - GeoInfoTable.GEOLOCATION + ", " + - GeoInfoTable.LAST_USED + - FROM + GeoInfoTable.TABLE_NAME; - String subQuery2 = SELECT + - GeoInfoTable.USER_UUID + ", " + - "MAX(" + GeoInfoTable.LAST_USED + ") as m" + - FROM + GeoInfoTable.TABLE_NAME + - GROUP_BY + GeoInfoTable.USER_UUID; - String sql = SELECT + GeoInfoTable.GEOLOCATION + ", COUNT(1) as c FROM (" + - "(" + subQuery1 + ") AS q1" + - " INNER JOIN (" + subQuery2 + ") AS q2 ON q1.uuid = q2.uuid)" + - WHERE + GeoInfoTable.LAST_USED + "=m" + - GROUP_BY + GeoInfoTable.GEOLOCATION; - - return new QueryAllStatement>(sql) { - @Override - public Map processResults(ResultSet set) throws SQLException { - Map geolocationCounts = new HashMap<>(); - while (set.next()) { - geolocationCounts.put(set.getString(GeoInfoTable.GEOLOCATION), set.getInt("c")); - } - return geolocationCounts; - } - }; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/AllPlayerContainersQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/AllPlayerContainersQuery.java deleted file mode 100644 index a03cc51dc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/AllPlayerContainersQuery.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.containers; - -import com.djrapitops.plan.data.container.*; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.containers.SupplierDataContainer; -import com.djrapitops.plan.data.store.keys.PerServerKeys; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.mutators.PerServerMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.queries.objects.*; - -import java.util.*; - -/** - * Used to get PlayerContainers of all players on the network, some limitations apply to DataContainer keys. - *

- * Limitations: - * - PlayerContainers do not support: PlayerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT - * - PlayerContainers PlayerKeys.PER_SERVER does not support: PerServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @author Rsl1122 - */ -public class AllPlayerContainersQuery implements Query> { - - /** - * Create PerServerContainers for each player. - * - * @param sessions Map: Server UUID - Map: Player UUID - List of Sessions - * @param allUserInfo Map: Server UUID - List of Users - * @param allPings Map: Player UUID - List of Ping data - * @return Map: Player UUID - PerServerContainer - */ - private Map getPerServerData( - Map>> sessions, - Map> allUserInfo, - Map> allPings - ) { - Map perServerContainers = new HashMap<>(); - - for (Map.Entry> entry : allUserInfo.entrySet()) { - UUID serverUUID = entry.getKey(); - List serverUserInfo = entry.getValue(); - - for (UserInfo userInfo : serverUserInfo) { - UUID uuid = userInfo.getPlayerUuid(); - if (uuid == null) { - continue; - } - PerServerContainer perServerContainer = perServerContainers.getOrDefault(uuid, new PerServerContainer()); - DataContainer container = perServerContainer.getOrDefault(serverUUID, new SupplierDataContainer()); - container.putRawData(PlayerKeys.REGISTERED, userInfo.getRegistered()); - container.putRawData(PlayerKeys.BANNED, userInfo.isBanned()); - container.putRawData(PlayerKeys.OPERATOR, userInfo.isOperator()); - perServerContainer.put(serverUUID, container); - perServerContainers.put(uuid, perServerContainer); - } - } - - for (Map.Entry>> entry : sessions.entrySet()) { - UUID serverUUID = entry.getKey(); - Map> serverUserSessions = entry.getValue(); - - for (Map.Entry> sessionEntry : serverUserSessions.entrySet()) { - UUID playerUUID = sessionEntry.getKey(); - PerServerContainer perServerContainer = perServerContainers.getOrDefault(playerUUID, new PerServerContainer()); - DataContainer container = perServerContainer.getOrDefault(serverUUID, new SupplierDataContainer()); - - List serverSessions = sessionEntry.getValue(); - container.putRawData(PerServerKeys.SESSIONS, serverSessions); - - container.putSupplier(PerServerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen()); - - container.putSupplier(PerServerKeys.WORLD_TIMES, () -> SessionsMutator.forContainer(container).toTotalWorldTimes()); - container.putSupplier(PerServerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList()); - container.putSupplier(PerServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList()); - container.putSupplier(PerServerKeys.PLAYER_KILL_COUNT, () -> container.getValue(PerServerKeys.PLAYER_KILLS).map(Collection::size).orElse(0)); - container.putSupplier(PerServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount()); - container.putSupplier(PerServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount()); - container.putSupplier(PerServerKeys.PLAYER_DEATH_COUNT, () -> SessionsMutator.forContainer(container).toPlayerDeathCount()); - container.putSupplier(PerServerKeys.MOB_DEATH_COUNT, () -> - container.getValue(PerServerKeys.DEATH_COUNT).orElse(0) - container.getValue(PerServerKeys.PLAYER_DEATH_COUNT).orElse(0) - ); - perServerContainer.put(serverUUID, container); - perServerContainers.put(playerUUID, perServerContainer); - } - } - - for (Map.Entry> entry : allPings.entrySet()) { - UUID uuid = entry.getKey(); - for (Ping ping : entry.getValue()) { - UUID serverUUID = ping.getServerUUID(); - PerServerContainer perServerContainer = perServerContainers.getOrDefault(uuid, new PerServerContainer()); - DataContainer container = perServerContainer.getOrDefault(serverUUID, new SupplierDataContainer()); - - if (!container.supports(PerServerKeys.PING)) { - container.putRawData(PerServerKeys.PING, new ArrayList<>()); - } - container.getUnsafe(PerServerKeys.PING).add(ping); - - perServerContainer.put(serverUUID, container); - perServerContainers.put(uuid, perServerContainer); - } - } - - return perServerContainers; - } - - @Override - public List executeQuery(SQLDB db) { - List containers = new ArrayList<>(); - - Collection users = db.query(BaseUserQueries.fetchAllBaseUsers()); - Map> geoInfo = db.query(GeoInfoQueries.fetchAllGeoInformation()); - Map> allPings = db.query(PingQueries.fetchAllPingData()); - Map> allNicknames = db.query(NicknameQueries.fetchAllNicknameDataByPlayerUUIDs()); - - Map>> sessions = db.query(SessionQueries.fetchAllSessionsWithoutKillOrWorldData()); - Map> allUserInfo = db.query(UserInfoQueries.fetchAllUserInformation()); - Map perServerInfo = getPerServerData(sessions, allUserInfo, allPings); - - for (BaseUser baseUser : users) { - PlayerContainer container = new PlayerContainer(); - UUID uuid = baseUser.getUuid(); - container.putRawData(PlayerKeys.UUID, uuid); - - container.putRawData(PlayerKeys.REGISTERED, baseUser.getRegistered()); - container.putRawData(PlayerKeys.NAME, baseUser.getName()); - container.putRawData(PlayerKeys.KICK_COUNT, baseUser.getTimesKicked()); - container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid)); - container.putRawData(PlayerKeys.PING, allPings.get(uuid)); - container.putRawData(PlayerKeys.NICKNAMES, allNicknames.get(uuid)); - container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid)); - - container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { - List playerSessions = PerServerMutator.forContainer(container).flatMapSessions(); - container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add); - return playerSessions; - } - ); - - // Calculating getters - container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen()); - - container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount()); - container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount()); - - containers.add(container); - } - return containers; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ContainerFetchQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ContainerFetchQueries.java deleted file mode 100644 index dc18b6a5d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ContainerFetchQueries.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.containers; - -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.containers.ServerContainer; -import com.djrapitops.plan.db.access.Query; - -import java.util.List; -import java.util.UUID; - -/** - * Static method class for queries that return some kind of {@link com.djrapitops.plan.data.store.containers.DataContainer}. - * - * @author Rsl1122 - */ -public class ContainerFetchQueries { - - private ContainerFetchQueries() { - /* Static method class */ - } - - /** - * Used to get a NetworkContainer, some limitations apply to values returned by DataContainer keys. - * - * @return a new NetworkContainer. - * @see NetworkContainerQuery - */ - public static Query fetchNetworkContainer() { - return new NetworkContainerQuery(); - } - - /** - * Used to get a ServerContainer, some limitations apply to values returned by DataContainer keys. - * - * @param serverUUID UUID of the Server. - * @return a new ServerContainer. - * @see ServerContainerQuery - */ - public static Query fetchServerContainer(UUID serverUUID) { - return new ServerContainerQuery(serverUUID); - } - - /** - * Used to get a PlayerContainer of a specific player. - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @param playerUUID UUID of the player. - * @return a new PlayerContainer. - * @see PlayerContainerQuery - */ - public static Query fetchPlayerContainer(UUID playerUUID) { - return new PlayerContainerQuery(playerUUID); - } - - /** - * Used to get PlayerContainers of all players on the network, some limitations apply to DataContainer keys. - *

- * Limitations: - * - PlayerContainers do not support: PlayerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT - * - PlayerContainers PlayerKeys.PER_SERVER does not support: PerServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @return a list of PlayerContainers in Plan database. - */ - public static Query> fetchAllPlayerContainers() { - return new AllPlayerContainersQuery(); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/NetworkContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/NetworkContainerQuery.java deleted file mode 100644 index dd8dae581..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/NetworkContainerQuery.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.containers; - -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.data.store.containers.ServerContainer; -import com.djrapitops.plan.data.store.keys.NetworkKeys; -import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.queries.objects.TPSQueries; -import com.djrapitops.plan.system.info.server.Server; - -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; - -/** - * Used to get a NetworkContainer, some limitations apply to values returned by DataContainer keys. - *

- * Limitations: - * - Bungee ServerContainer does not support: ServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_DEATHS, PLAYER_KILL_COUNT - * - Bungee ServerContainer ServerKeys.TPS only contains playersOnline values - * - NetworkKeys.PLAYERS PlayerContainers: - * - do not support: PlayerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_DEATHS, PLAYER_KILL_COUNT - * - PlayerKeys.PER_SERVER does not support: PerServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_DEATHS, PLAYER_KILL_COUNT - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @author Rsl1122 - */ -public class NetworkContainerQuery implements Query { - - private static Query getProxyServerContainer() { - return db -> { - Optional proxyInformation = db.query(ServerQueries.fetchProxyServerInformation()); - if (!proxyInformation.isPresent()) { - return new ServerContainer(); - } - - UUID proxyUUID = proxyInformation.get().getUuid(); - ServerContainer container = db.query(ContainerFetchQueries.fetchServerContainer(proxyUUID)); - container.putCachingSupplier(ServerKeys.PLAYERS, () -> db.query(ContainerFetchQueries.fetchAllPlayerContainers())); - container.putCachingSupplier(ServerKeys.TPS, () -> db.query(TPSQueries.fetchTPSDataOfServer(proxyUUID))); - container.putSupplier(ServerKeys.WORLD_TIMES, null); // Additional Session information not supported - container.putSupplier(ServerKeys.PLAYER_KILLS, null); - container.putSupplier(ServerKeys.PLAYER_KILL_COUNT, null); - - return container; - }; - } - - @Override - public NetworkContainer executeQuery(SQLDB db) { - ServerContainer bungeeContainer = db.query(getProxyServerContainer()); - NetworkContainer networkContainer = db.getNetworkContainerFactory().forBungeeContainer(bungeeContainer); - networkContainer.putCachingSupplier(NetworkKeys.BUKKIT_SERVERS, () -> - db.query(ServerQueries.fetchPlanServerInformation()).values() - .stream().filter(Server::isNotProxy).collect(Collectors.toSet()) - ); - return networkContainer; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java deleted file mode 100644 index 2322319e6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.containers; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.container.UserInfo; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.store.containers.SupplierDataContainer; -import com.djrapitops.plan.data.store.keys.PerServerKeys; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.queries.PerServerAggregateQueries; -import com.djrapitops.plan.db.access.queries.objects.SessionQueries; -import com.djrapitops.plan.db.access.queries.objects.UserInfoQueries; -import com.djrapitops.plan.db.access.queries.objects.WorldTimesQueries; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * Used to get a PerServerContainer for a specific player. - * - * @author Rsl1122 - */ -public class PerServerContainerQuery implements Query { - - private final UUID playerUUID; - - public PerServerContainerQuery(UUID playerUUID) { - this.playerUUID = playerUUID; - } - - @Override - public PerServerContainer executeQuery(SQLDB db) { - PerServerContainer perServerContainer = new PerServerContainer(); - - userInformation(db, perServerContainer); - lastSeen(db, perServerContainer); - playerKillCount(db, perServerContainer); - playerDeathCount(db, perServerContainer); - mobKillCount(db, perServerContainer); - totalDeathCount(db, perServerContainer); - worldTimes(db, perServerContainer); - - // After-values that can be calculated without database. - for (DataContainer serverContainer : perServerContainer.values()) { - serverContainer.putSupplier(PerServerKeys.MOB_DEATH_COUNT, () -> - serverContainer.getValue(PerServerKeys.DEATH_COUNT).orElse(0) - serverContainer.getValue(PerServerKeys.PLAYER_DEATH_COUNT).orElse(0) - ); - } - - Map> sessions = db.query(SessionQueries.fetchSessionsOfPlayer(playerUUID)); - for (Map.Entry> entry : sessions.entrySet()) { - UUID serverUUID = entry.getKey(); - List serverSessions = entry.getValue(); - - DataContainer serverContainer = perServerContainer.getOrDefault(serverUUID, new SupplierDataContainer()); - serverContainer.putRawData(PerServerKeys.SESSIONS, serverSessions); - - serverContainer.putSupplier(PerServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(serverContainer).toPlayerKillList()); - serverContainer.putSupplier(PerServerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(serverContainer).toPlayerDeathList()); - - perServerContainer.put(serverUUID, serverContainer); - } - - return perServerContainer; - } - - private void totalDeathCount(SQLDB db, PerServerContainer container) { - matchingEntrySet(PerServerKeys.DEATH_COUNT, PerServerAggregateQueries.totalDeathCountOnServers(playerUUID), db, container); - } - - private void worldTimes(SQLDB db, PerServerContainer container) { - matchingEntrySet(PerServerKeys.WORLD_TIMES, WorldTimesQueries.fetchPlayerWorldTimesOnServers(playerUUID), db, container); - } - - private void playerDeathCount(SQLDB db, PerServerContainer container) { - matchingEntrySet(PerServerKeys.PLAYER_DEATH_COUNT, PerServerAggregateQueries.playerDeathCountOnServers(playerUUID), db, container); - } - - private void mobKillCount(SQLDB db, PerServerContainer container) { - matchingEntrySet(PerServerKeys.MOB_KILL_COUNT, PerServerAggregateQueries.mobKillCountOnServers(playerUUID), db, container); - } - - private void playerKillCount(SQLDB db, PerServerContainer container) { - matchingEntrySet(PerServerKeys.PLAYER_KILL_COUNT, PerServerAggregateQueries.playerKillCountOnServers(playerUUID), db, container); - } - - private void lastSeen(SQLDB db, PerServerContainer container) { - matchingEntrySet(PerServerKeys.LAST_SEEN, PerServerAggregateQueries.lastSeenOnServers(playerUUID), db, container); - } - - private void userInformation(SQLDB db, PerServerContainer container) { - List userInformation = db.query(UserInfoQueries.fetchUserInformationOfUser(playerUUID)); - container.putUserInfo(userInformation); - } - - private void matchingEntrySet(Key key, Query> map, SQLDB db, PerServerContainer container) { - for (Map.Entry entry : db.query(map).entrySet()) { - container.putToContainerOfServer(entry.getKey(), key, entry.getValue()); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PlayerContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PlayerContainerQuery.java deleted file mode 100644 index 415272f45..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PlayerContainerQuery.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.containers; - -import com.djrapitops.plan.data.container.BaseUser; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.PerServerMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.queries.objects.*; - -import java.util.Collection; -import java.util.List; -import java.util.UUID; - -/** - * Used to get a PlayerContainer of a specific player. - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @author Rsl1122 - */ -public class PlayerContainerQuery implements Query { - - private final UUID uuid; - - public PlayerContainerQuery(UUID uuid) { - this.uuid = uuid; - } - - @Override - public PlayerContainer executeQuery(SQLDB db) { - PlayerContainer container = new PlayerContainer(); - container.putRawData(PlayerKeys.UUID, uuid); - - Key baseUserKey = new Key<>(BaseUser.class, "BASE_USER"); - container.putSupplier(baseUserKey, () -> db.query(BaseUserQueries.fetchBaseUserOfPlayer(uuid)).orElse(null)); - container.putSupplier(PlayerKeys.REGISTERED, () -> container.getValue(baseUserKey).map(BaseUser::getRegistered).orElse(null)); - container.putSupplier(PlayerKeys.NAME, () -> container.getValue(baseUserKey).map(BaseUser::getName).orElse(null)); - container.putSupplier(PlayerKeys.KICK_COUNT, () -> container.getValue(baseUserKey).map(BaseUser::getTimesKicked).orElse(null)); - - container.putCachingSupplier(PlayerKeys.GEO_INFO, () -> db.query(GeoInfoQueries.fetchPlayerGeoInformation(uuid))); - container.putCachingSupplier(PlayerKeys.PING, () -> db.query(PingQueries.fetchPingDataOfPlayer(uuid))); - container.putCachingSupplier(PlayerKeys.NICKNAMES, () -> db.query(NicknameQueries.fetchNicknameDataOfPlayer(uuid))); - container.putCachingSupplier(PlayerKeys.PER_SERVER, () -> db.query(new PerServerContainerQuery(uuid))); - - container.putSupplier(PlayerKeys.BANNED, () -> new PerServerMutator(container.getValue(PlayerKeys.PER_SERVER).orElse(new PerServerContainer())).isBanned()); - container.putSupplier(PlayerKeys.OPERATOR, () -> new PerServerMutator(container.getValue(PlayerKeys.PER_SERVER).orElse(new PerServerContainer())).isOperator()); - - container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { - List sessions = new PerServerMutator(container.getValue(PlayerKeys.PER_SERVER).orElse(new PerServerContainer())).flatMapSessions(); - container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(sessions::add); - return sessions; - } - ); - container.putCachingSupplier(PlayerKeys.WORLD_TIMES, () -> - { - WorldTimes worldTimes = db.query(WorldTimesQueries.fetchPlayerTotalWorldTimes(uuid)); - container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(session -> worldTimes.add( - session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes())) - ); - return worldTimes; - }); - - container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen()); - - container.putSupplier(PlayerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList()); - container.putSupplier(PlayerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList()); - container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getValue(PlayerKeys.PLAYER_KILLS).map(Collection::size).orElse(0)); - container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount()); - container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount()); - - return container; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerContainerQuery.java deleted file mode 100644 index 6c7411769..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerContainerQuery.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.containers; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.containers.ServerContainer; -import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.queries.ServerAggregateQueries; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.queries.objects.TPSQueries; -import com.djrapitops.plan.db.access.queries.objects.WorldTimesQueries; -import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionServerDataQuery; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.info.server.Server; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -/** - * Used to get a ServerContainer, some limitations apply to values returned by DataContainer keys. - *

- * Limitations: - * - ServerKeys.PLAYERS PlayerContainers PlayerKeys.PER_SERVER only contains information about the queried server. - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @author Rsl1122 - */ -public class ServerContainerQuery implements Query { - - private final UUID serverUUID; - - public ServerContainerQuery(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - @Override - public ServerContainer executeQuery(SQLDB db) { - ServerContainer container = new ServerContainer(); - - Optional serverInfo = db.query(ServerQueries.fetchServerMatchingIdentifier(serverUUID)); - if (!serverInfo.isPresent()) { - return container; - } - - container.putRawData(ServerKeys.SERVER_UUID, serverUUID); - container.putRawData(ServerKeys.NAME, serverInfo.get().getName()); - container.putCachingSupplier(ServerKeys.PLAYERS, () -> db.query(new ServerPlayerContainersQuery(serverUUID))); - container.putSupplier(ServerKeys.PLAYER_COUNT, () -> container.getValue(ServerKeys.PLAYERS).map(Collection::size).orElse(0)); - - container.putCachingSupplier(ServerKeys.TPS, () -> db.query(TPSQueries.fetchTPSDataOfServer(serverUUID))); - container.putCachingSupplier(ServerKeys.PING, () -> PlayersMutator.forContainer(container).pings()); - container.putCachingSupplier(ServerKeys.ALL_TIME_PEAK_PLAYERS, () -> - db.query(TPSQueries.fetchAllTimePeakPlayerCount(serverUUID)).orElse(null) - ); - container.putCachingSupplier(ServerKeys.RECENT_PEAK_PLAYERS, () -> { - long twoDaysAgo = System.currentTimeMillis() - (TimeUnit.DAYS.toMillis(2L)); - return db.query(TPSQueries.fetchPeakPlayerCount(serverUUID, twoDaysAgo)).orElse(null); - }); - - container.putCachingSupplier(ServerKeys.COMMAND_USAGE, () -> db.query(ServerAggregateQueries.commandUsageCounts(serverUUID))); - container.putCachingSupplier(ServerKeys.WORLD_TIMES, () -> db.query(WorldTimesQueries.fetchServerTotalWorldTimes(serverUUID))); - - // Calculating getters - container.putCachingSupplier(ServerKeys.OPERATORS, () -> PlayersMutator.forContainer(container).operators()); - container.putCachingSupplier(ServerKeys.SESSIONS, () -> { - List sessions = PlayersMutator.forContainer(container).getSessions(); - if (serverUUID.equals(serverInfo.get().getUuid())) { - sessions.addAll(SessionCache.getActiveSessions().values()); - } - return sessions; - }); - container.putCachingSupplier(ServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList()); - container.putCachingSupplier(ServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(ServerKeys.PLAYER_KILLS).size()); - container.putCachingSupplier(ServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount()); - container.putCachingSupplier(ServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount()); - - container.putCachingSupplier(ServerKeys.EXTENSION_DATA, () -> db.query(new ExtensionServerDataQuery(serverUUID))); - - return container; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java deleted file mode 100644 index d5b757e77..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.containers; - -import com.djrapitops.plan.data.container.*; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.PerServerMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.queries.objects.*; - -import java.util.*; - -/** - * Used to get PlayerContainers of all players on a server, some limitations apply to DataContainer keys. - *

- * Limitations: - * - PlayerContainers do not support: PlayerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT - * - PlayerContainers PlayerKeys.PER_SERVER does not support: PerServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @author Rsl1122 - */ -public class ServerPlayerContainersQuery implements Query> { - - private final UUID serverUUID; - - public ServerPlayerContainersQuery(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - @Override - public List executeQuery(SQLDB db) { - List containers = new ArrayList<>(); - - Collection baseUsers = db.query(BaseUserQueries.fetchServerBaseUsers(serverUUID)); - - Map> geoInformation = db.query(GeoInfoQueries.fetchServerGeoInformation(serverUUID)); - Map> nicknames = db.query(NicknameQueries.fetchNicknameDataOfServer(serverUUID)); - Map> pingData = db.query(PingQueries.fetchPingDataOfServer(serverUUID)); - Map> sessions = db.query(SessionQueries.fetchSessionsOfServer(serverUUID)); - - Map userInformation = db.query(UserInfoQueries.fetchUserInformationOfServer(serverUUID)); - - Map perServerInfo = getPerServerData( - userInformation, - sessions, - pingData - ); - - for (BaseUser user : baseUsers) { - PlayerContainer container = new PlayerContainer(); - - // BaseUser - UUID uuid = user.getUuid(); - container.putRawData(PlayerKeys.UUID, uuid); - container.putRawData(PlayerKeys.NAME, user.getName()); - container.putRawData(PlayerKeys.REGISTERED, user.getRegistered()); - container.putRawData(PlayerKeys.KICK_COUNT, user.getTimesKicked()); - - // GeoInfo - container.putRawData(PlayerKeys.GEO_INFO, geoInformation.getOrDefault(uuid, new ArrayList<>())); - - // Ping - container.putRawData(PlayerKeys.PING, pingData.get(uuid)); - - // Nickname, only used for the raw server JSON. - container.putRawData(PlayerKeys.NICKNAMES, nicknames.get(uuid)); - - // PerServerContainer - container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid)); - - container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { - List playerSessions = sessions.getOrDefault(uuid, new ArrayList<>()); - container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add); - return playerSessions; - } - ); - - // Calculating getters - container.putCachingSupplier(PlayerKeys.WORLD_TIMES, () -> { - WorldTimes worldTimes = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapWorldTimes(); - container.getValue(PlayerKeys.ACTIVE_SESSION) - .ifPresent(session -> worldTimes.add( - session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes())) - ); - return worldTimes; - }); - container.putSupplier(PlayerKeys.BANNED, () -> PerServerMutator.forContainer(container).isBanned()); - container.putSupplier(PlayerKeys.OPERATOR, () -> PerServerMutator.forContainer(container).isOperator()); - - container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen()); - - container.putSupplier(PlayerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList()); - container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PlayerKeys.PLAYER_KILLS).size()); - container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount()); - container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount()); - - containers.add(container); - } - return containers; - } - - /** - * Create PerServerContainers for each player. - * - * @param userInformation Map: Player UUID - UserInfo of this server - * @param sessions Map: Player UUID - List of Sessions of this server - * @param ping Map: Player UUID - List of Ping data of this server - * @return Map: Player UUID - PerServerContainer - */ - private Map getPerServerData( - Map userInformation, - Map> sessions, - Map> ping - ) { - Map perServerContainers = new HashMap<>(); - - for (Map.Entry entry : userInformation.entrySet()) { - UUID playerUUID = entry.getKey(); - PerServerContainer perServerContainer = perServerContainers.getOrDefault(playerUUID, new PerServerContainer()); - - perServerContainer.putUserInfo(entry.getValue()); // Information found withing UserInfo - perServerContainer.putSessions(sessions.get(playerUUID)); // Session list - perServerContainer.putPing(ping.get(playerUUID)); // Ping list - perServerContainer.putCalculatingSuppliers(); // Derivative values - - perServerContainers.put(playerUUID, perServerContainer); - } - - return perServerContainers; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayersTableContainersQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayersTableContainersQuery.java deleted file mode 100644 index c1594e184..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayersTableContainersQuery.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.containers; - -import com.djrapitops.plan.data.container.BaseUser; -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.queries.objects.BaseUserQueries; -import com.djrapitops.plan.db.access.queries.objects.GeoInfoQueries; -import com.djrapitops.plan.db.access.queries.objects.SessionQueries; -import com.djrapitops.plan.db.access.queries.objects.UserInfoQueries; - -import java.util.*; - -/** - * Optimized version of {@link ServerPlayerContainersQuery} for /server page Players table. - * - * @author Rsl1122 - * @see com.djrapitops.plan.utilities.html.tables.PlayersTableJSONParser For what needs to be included. - */ -public class ServerPlayersTableContainersQuery implements Query> { - - private final UUID serverUUID; - - public ServerPlayersTableContainersQuery(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - @Override - public List executeQuery(SQLDB db) { - List containers = new ArrayList<>(); - - Collection baseUsers = db.query(BaseUserQueries.fetchServerBaseUsers(serverUUID)); - - Map> geoInformation = db.query(GeoInfoQueries.fetchServerGeoInformation(serverUUID)); - Map> sessions = db.query(SessionQueries.fetchSessionsOfServer(serverUUID)); - Set bannedUsers = db.query(UserInfoQueries.fetchBannedUUIDsOfServer(serverUUID)); - - for (BaseUser user : baseUsers) { - PlayerContainer container = new PlayerContainer(); - - // BaseUser - UUID uuid = user.getUuid(); - container.putRawData(PlayerKeys.UUID, uuid); - container.putRawData(PlayerKeys.NAME, user.getName()); - container.putRawData(PlayerKeys.REGISTERED, user.getRegistered()); - container.putRawData(PlayerKeys.BANNED, bannedUsers.contains(uuid)); - - // GeoInfo - container.putRawData(PlayerKeys.GEO_INFO, geoInformation.getOrDefault(uuid, new ArrayList<>())); - - container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { - List playerSessions = sessions.getOrDefault(uuid, new ArrayList<>()); - container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add); - return playerSessions; - } - ); - - containers.add(container); - } - return containers; - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/BaseUserQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/BaseUserQueries.java deleted file mode 100644 index 94bf82227..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/BaseUserQueries.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.data.container.BaseUser; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.parsing.Select; -import com.djrapitops.plan.db.sql.tables.UserInfoTable; -import com.djrapitops.plan.db.sql.tables.UsersTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Optional; -import java.util.UUID; - -/** - * Queries for {@link BaseUser} objects. - * - * @author Rsl1122 - */ -public class BaseUserQueries { - - private BaseUserQueries() { - /* Static method class */ - } - - /** - * Query database for common user information. - *

- * Only one {@link BaseUser} per player exists unlike {@link com.djrapitops.plan.data.container.UserInfo} which is available per server. - * - * @return Map: Player UUID - BaseUser - */ - public static Query> fetchAllBaseUsers() { - String sql = Select.all(UsersTable.TABLE_NAME).toString(); - - return new QueryAllStatement>(sql, 20000) { - @Override - public Collection processResults(ResultSet set) throws SQLException { - Collection users = new HashSet<>(); - while (set.next()) { - UUID playerUUID = UUID.fromString(set.getString(UsersTable.USER_UUID)); - String name = set.getString(UsersTable.USER_NAME); - long registered = set.getLong(UsersTable.REGISTERED); - int kicked = set.getInt(UsersTable.TIMES_KICKED); - - users.add(new BaseUser(playerUUID, name, registered, kicked)); - } - return users; - } - }; - } - - /** - * Query database for common user information of a player. - *

- * Only one {@link BaseUser} per player exists unlike {@link com.djrapitops.plan.data.container.UserInfo} which is available per server. - * - * @param playerUUID UUID of the Player. - * @return Optional: BaseUser if found, empty if not. - */ - public static Query> fetchBaseUserOfPlayer(UUID playerUUID) { - String sql = Select.all(UsersTable.TABLE_NAME).where(UsersTable.USER_UUID + "=?").toString(); - - return new QueryStatement>(sql, 20000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Optional processResults(ResultSet set) throws SQLException { - if (set.next()) { - UUID playerUUID = UUID.fromString(set.getString(UsersTable.USER_UUID)); - String name = set.getString(UsersTable.USER_NAME); - long registered = set.getLong(UsersTable.REGISTERED); - int kicked = set.getInt(UsersTable.TIMES_KICKED); - - return Optional.of(new BaseUser(playerUUID, name, registered, kicked)); - } - return Optional.empty(); - } - }; - } - - /** - * Query database for common user information for players that have played on a specific server. - *

- * Only one {@link BaseUser} per player exists unlike {@link com.djrapitops.plan.data.container.UserInfo} which is available per server. - *

- * This will fetch BaseUsers for which UserInfo object also exists on the server. - * - * @param serverUUID UUID of the Plan server. - * @return Collection: BaseUsers - */ - public static Query> fetchServerBaseUsers(UUID serverUUID) { - String sql = "SELECT " + - UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID + ", " + - UsersTable.USER_NAME + ", " + - UsersTable.TABLE_NAME + "." + UsersTable.REGISTERED + ", " + - UsersTable.TIMES_KICKED + - " FROM " + UsersTable.TABLE_NAME + - " INNER JOIN " + UserInfoTable.TABLE_NAME + " on " + - UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID + "=" + UserInfoTable.TABLE_NAME + "." + UserInfoTable.USER_UUID + - " WHERE " + UserInfoTable.SERVER_UUID + "=?"; - return new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Collection processResults(ResultSet set) throws SQLException { - Collection users = new HashSet<>(); - while (set.next()) { - UUID playerUUID = UUID.fromString(set.getString(UsersTable.USER_UUID)); - String name = set.getString(UsersTable.USER_NAME); - long registered = set.getLong(UsersTable.REGISTERED); - int kicked = set.getInt(UsersTable.TIMES_KICKED); - - users.add(new BaseUser(playerUUID, name, registered, kicked)); - } - return users; - } - }; - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/GeoInfoQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/GeoInfoQueries.java deleted file mode 100644 index 8db220947..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/GeoInfoQueries.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.GeoInfoTable; -import com.djrapitops.plan.db.sql.tables.UserInfoTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -/** - * Queries for {@link com.djrapitops.plan.data.container.GeoInfo} objects. - * - * @author Rsl1122 - */ -public class GeoInfoQueries { - - private GeoInfoQueries() { - /* Static method class */ - } - - /** - * Query database for all GeoInfo data. - * - * @return Map: Player UUID - List of GeoInfo - */ - public static Query>> fetchAllGeoInformation() { - String sql = "SELECT " + - GeoInfoTable.IP + ", " + - GeoInfoTable.GEOLOCATION + ", " + - GeoInfoTable.LAST_USED + ", " + - GeoInfoTable.USER_UUID + - " FROM " + GeoInfoTable.TABLE_NAME; - - return new QueryAllStatement>>(sql, 50000) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> geoInformation = new HashMap<>(); - while (set.next()) { - UUID uuid = UUID.fromString(set.getString(GeoInfoTable.USER_UUID)); - - List userGeoInfo = geoInformation.getOrDefault(uuid, new ArrayList<>()); - - String ip = set.getString(GeoInfoTable.IP); - String geolocation = set.getString(GeoInfoTable.GEOLOCATION); - long lastUsed = set.getLong(GeoInfoTable.LAST_USED); - userGeoInfo.add(new GeoInfo(ip, geolocation, lastUsed)); - - geoInformation.put(uuid, userGeoInfo); - } - return geoInformation; - } - }; - } - - /** - * Query Player's GeoInfo by player's UUID. - * - * @param playerUUID UUID of the player. - * @return List of {@link GeoInfo}, empty if none are found. - */ - public static Query> fetchPlayerGeoInformation(UUID playerUUID) { - String sql = "SELECT DISTINCT * FROM " + GeoInfoTable.TABLE_NAME + - " WHERE " + GeoInfoTable.USER_UUID + "=?"; - - return new QueryStatement>(sql, 100) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public List processResults(ResultSet set) throws SQLException { - List geoInfo = new ArrayList<>(); - while (set.next()) { - String ip = set.getString(GeoInfoTable.IP); - String geolocation = set.getString(GeoInfoTable.GEOLOCATION); - long lastUsed = set.getLong(GeoInfoTable.LAST_USED); - geoInfo.add(new GeoInfo(ip, geolocation, lastUsed)); - } - return geoInfo; - } - }; - } - - public static Query>> fetchServerGeoInformation(UUID serverUUID) { - String sql = "SELECT " + GeoInfoTable.TABLE_NAME + "." + GeoInfoTable.USER_UUID + ", " + - GeoInfoTable.GEOLOCATION + ", " + - GeoInfoTable.LAST_USED + ", " + - GeoInfoTable.IP + - " FROM " + GeoInfoTable.TABLE_NAME + - " INNER JOIN " + UserInfoTable.TABLE_NAME + " on " + - GeoInfoTable.TABLE_NAME + "." + GeoInfoTable.USER_UUID + "=" + UserInfoTable.TABLE_NAME + "." + UserInfoTable.USER_UUID + - " WHERE " + UserInfoTable.SERVER_UUID + "=?"; - return new QueryStatement>>(sql, 10000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> geoInformation = new HashMap<>(); - while (set.next()) { - UUID uuid = UUID.fromString(set.getString(GeoInfoTable.USER_UUID)); - - List userGeoInfo = geoInformation.getOrDefault(uuid, new ArrayList<>()); - - String ip = set.getString(GeoInfoTable.IP); - String geolocation = set.getString(GeoInfoTable.GEOLOCATION); - long lastUsed = set.getLong(GeoInfoTable.LAST_USED); - userGeoInfo.add(new GeoInfo(ip, geolocation, lastUsed)); - - geoInformation.put(uuid, userGeoInfo); - } - return geoInformation; - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/NewerConfigQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/NewerConfigQuery.java deleted file mode 100644 index 2f1022d88..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/NewerConfigQuery.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.system.settings.config.Config; -import com.djrapitops.plan.system.settings.config.ConfigReader; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Optional; -import java.util.Scanner; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.tables.SettingsTable.*; - -/** - * Query to fetch a newer config from the database. - * - * @author Rsl1122 - */ -public class NewerConfigQuery extends QueryStatement> { - - private static final String SELECT_STATEMENT = "SELECT " + CONFIG_CONTENT + " FROM " + TABLE_NAME + - " WHERE " + UPDATED + ">? AND " + - SERVER_UUID + "=? LIMIT 1"; - - private final UUID serverUUID; - private final long updatedAfter; - - /** - * Create a new Query. - * - * @param serverUUID UUID of the server - * @param updatedAfter Epoch ms. - */ - public NewerConfigQuery(UUID serverUUID, long updatedAfter) { - super(SELECT_STATEMENT); - this.serverUUID = serverUUID; - this.updatedAfter = updatedAfter; - } - - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, updatedAfter); - statement.setString(2, serverUUID.toString()); - } - - @Override - public Optional processResults(ResultSet set) throws SQLException { - if (set.next()) { - try (ConfigReader reader = new ConfigReader(new Scanner(set.getString(CONFIG_CONTENT)))) { - return Optional.of(reader.read()); - } - } else { - return Optional.empty(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/NicknameQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/NicknameQueries.java deleted file mode 100644 index aa8a17652..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/NicknameQueries.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.NicknamesTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Queries for {@link com.djrapitops.plan.data.store.objects.Nickname} objects. - * - * @author Rsl1122 - */ -public class NicknameQueries { - - private NicknameQueries() { - /* Static method class */ - } - - /** - * Query database for all nickname data. - * - * @return Multimap: Server UUID - (Player UUID - List of nicknames) - */ - public static Query>>> fetchAllNicknameData() { - String sql = SELECT + - NicknamesTable.NICKNAME + ", " + - NicknamesTable.LAST_USED + ", " + - NicknamesTable.USER_UUID + ", " + - NicknamesTable.SERVER_UUID + - FROM + NicknamesTable.TABLE_NAME; - - return new QueryAllStatement>>>(sql, 5000) { - @Override - public Map>> processResults(ResultSet set) throws SQLException { - Map>> map = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(NicknamesTable.SERVER_UUID)); - UUID uuid = UUID.fromString(set.getString(NicknamesTable.USER_UUID)); - - Map> serverMap = map.getOrDefault(serverUUID, new HashMap<>()); - List nicknames = serverMap.getOrDefault(uuid, new ArrayList<>()); - - nicknames.add(new Nickname( - set.getString(NicknamesTable.NICKNAME), - set.getLong(NicknamesTable.LAST_USED), - serverUUID - )); - - serverMap.put(uuid, nicknames); - map.put(serverUUID, serverMap); - } - return map; - } - }; - } - - public static Query> fetchLastSeenNicknameOfPlayer(UUID playerUUID, UUID serverUUID) { - String subQuery = "SELECT MAX(" + NicknamesTable.LAST_USED + ") FROM " + NicknamesTable.TABLE_NAME + - WHERE + NicknamesTable.USER_UUID + "=?" + - AND + NicknamesTable.SERVER_UUID + "=?" + - GROUP_BY + NicknamesTable.USER_UUID; - String sql = SELECT + - NicknamesTable.LAST_USED + ", " + NicknamesTable.NICKNAME + - FROM + NicknamesTable.TABLE_NAME + - WHERE + NicknamesTable.USER_UUID + "=?" + - AND + NicknamesTable.SERVER_UUID + "=?" + - AND + NicknamesTable.LAST_USED + "=(" + subQuery + ")"; - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - statement.setString(2, serverUUID.toString()); - statement.setString(3, playerUUID.toString()); - statement.setString(4, serverUUID.toString()); - } - - @Override - public Optional processResults(ResultSet set) throws SQLException { - if (set.next()) { - return Optional.of(new Nickname( - set.getString(NicknamesTable.NICKNAME), - set.getLong(NicknamesTable.LAST_USED), - serverUUID - )); - } - return Optional.empty(); - } - }; - } - - public static Query> fetchNicknameDataOfPlayer(UUID playerUUID) { - String sql = SELECT + - NicknamesTable.NICKNAME + ", " + - NicknamesTable.LAST_USED + ", " + - NicknamesTable.SERVER_UUID + - FROM + NicknamesTable.TABLE_NAME + - WHERE + NicknamesTable.USER_UUID + "=?"; - - return new QueryStatement>(sql, 5000) { - - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public List processResults(ResultSet set) throws SQLException { - List nicknames = new ArrayList<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(NicknamesTable.SERVER_UUID)); - String nickname = set.getString(NicknamesTable.NICKNAME); - nicknames.add(new Nickname(nickname, set.getLong(NicknamesTable.LAST_USED), serverUUID)); - } - return nicknames; - } - }; - } - - /** - * Query database for all nickname data. - * - * @return Map: Player UUID - List of nicknames. - */ - public static Query>> fetchAllNicknameDataByPlayerUUIDs() { - String sql = SELECT + - NicknamesTable.NICKNAME + ", " + - NicknamesTable.LAST_USED + ", " + - NicknamesTable.USER_UUID + ", " + - NicknamesTable.SERVER_UUID + - FROM + NicknamesTable.TABLE_NAME; - return new QueryAllStatement>>(sql, 5000) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> map = new HashMap<>(); - while (set.next()) { - UUID uuid = UUID.fromString(set.getString(NicknamesTable.USER_UUID)); - UUID serverUUID = UUID.fromString(set.getString(NicknamesTable.SERVER_UUID)); - List nicknames = map.computeIfAbsent(uuid, x -> new ArrayList<>()); - nicknames.add(new Nickname( - set.getString(NicknamesTable.NICKNAME), set.getLong(NicknamesTable.LAST_USED), serverUUID - )); - } - return map; - } - }; - } - - /** - * Query database for nickname information of a server. - * - * @param serverUUID UUID the the Plan server. - * @return Map: Player UUID - List of Nicknames on the server. - */ - public static Query>> fetchNicknameDataOfServer(UUID serverUUID) { - String sql = SELECT + - NicknamesTable.NICKNAME + ", " + - NicknamesTable.LAST_USED + ", " + - NicknamesTable.USER_UUID + ", " + - NicknamesTable.SERVER_UUID + - FROM + NicknamesTable.TABLE_NAME + - WHERE + NicknamesTable.SERVER_UUID + "=?"; - - return new QueryStatement>>(sql, 5000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> serverMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(NicknamesTable.SERVER_UUID)); - UUID uuid = UUID.fromString(set.getString(NicknamesTable.USER_UUID)); - - List nicknames = serverMap.getOrDefault(uuid, new ArrayList<>()); - - nicknames.add(new Nickname( - set.getString(NicknamesTable.NICKNAME), - set.getLong(NicknamesTable.LAST_USED), - serverUUID - )); - - serverMap.put(uuid, nicknames); - } - return serverMap; - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/PingQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/PingQueries.java deleted file mode 100644 index cdd74df72..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/PingQueries.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.PingTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -/** - * Queries for {@link WebUser} objects. - * - * @author Rsl1122 - */ -public class PingQueries { - - private PingQueries() { - /* Static method class */ - } - - /** - * Query database for all Ping data. - * - * @return Map: Player UUID - List of ping data. - */ - public static Query>> fetchAllPingData() { - String sql = "SELECT " + - PingTable.DATE + ", " + - PingTable.MAX_PING + ", " + - PingTable.MIN_PING + ", " + - PingTable.AVG_PING + ", " + - PingTable.USER_UUID + ", " + - PingTable.SERVER_UUID + - " FROM " + PingTable.TABLE_NAME; - return new QueryAllStatement>>(sql, 100000) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> userPings = new HashMap<>(); - - while (set.next()) { - UUID uuid = UUID.fromString(set.getString(PingTable.USER_UUID)); - UUID serverUUID = UUID.fromString(set.getString(PingTable.SERVER_UUID)); - long date = set.getLong(PingTable.DATE); - double avgPing = set.getDouble(PingTable.AVG_PING); - int minPing = set.getInt(PingTable.MIN_PING); - int maxPing = set.getInt(PingTable.MAX_PING); - - List pings = userPings.getOrDefault(uuid, new ArrayList<>()); - pings.add(new Ping(date, serverUUID, - minPing, - maxPing, - avgPing)); - userPings.put(uuid, pings); - } - - return userPings; - } - }; - } - - /** - * Query database for Ping data of a specific player. - * - * @param playerUUID UUID of the player. - * @return List of Ping entries for this player. - */ - public static Query> fetchPingDataOfPlayer(UUID playerUUID) { - String sql = "SELECT * FROM " + PingTable.TABLE_NAME + - " WHERE " + PingTable.USER_UUID + "=?"; - - return new QueryStatement>(sql, 10000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public List processResults(ResultSet set) throws SQLException { - List pings = new ArrayList<>(); - - while (set.next()) { - pings.add(new Ping( - set.getLong(PingTable.DATE), - UUID.fromString(set.getString(PingTable.SERVER_UUID)), - set.getInt(PingTable.MIN_PING), - set.getInt(PingTable.MAX_PING), - set.getDouble(PingTable.AVG_PING) - ) - ); - } - - return pings; - } - }; - } - - public static Query>> fetchPingDataOfServer(UUID serverUUID) { - String sql = "SELECT " + - PingTable.DATE + ", " + - PingTable.MAX_PING + ", " + - PingTable.MIN_PING + ", " + - PingTable.AVG_PING + ", " + - PingTable.USER_UUID + ", " + - PingTable.SERVER_UUID + - " FROM " + PingTable.TABLE_NAME + - " WHERE " + PingTable.SERVER_UUID + "=?"; - return new QueryStatement>>(sql, 100000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> userPings = new HashMap<>(); - - while (set.next()) { - UUID uuid = UUID.fromString(set.getString(PingTable.USER_UUID)); - UUID serverUUID = UUID.fromString(set.getString(PingTable.SERVER_UUID)); - long date = set.getLong(PingTable.DATE); - double avgPing = set.getDouble(PingTable.AVG_PING); - int minPing = set.getInt(PingTable.MIN_PING); - int maxPing = set.getInt(PingTable.MAX_PING); - - List pings = userPings.getOrDefault(uuid, new ArrayList<>()); - pings.add(new Ping(date, serverUUID, - minPing, - maxPing, - avgPing)); - userPings.put(uuid, pings); - } - - return userPings; - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/ServerQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/ServerQueries.java deleted file mode 100644 index 4a5087138..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/ServerQueries.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.parsing.Select; -import com.djrapitops.plan.db.sql.tables.ServerTable; -import com.djrapitops.plan.system.info.server.Server; -import org.apache.commons.lang3.math.NumberUtils; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -/** - * Queries for {@link com.djrapitops.plan.system.info.server.Server} objects. - * - * @author Rsl1122 - */ -public class ServerQueries { - - private ServerQueries() { - /* Static method class */ - } - - /** - * Query database for all Plan server information. - * - * @return Map: Server UUID - Plan Server Information - */ - public static Query> fetchPlanServerInformation() { - String sql = "SELECT * FROM " + ServerTable.TABLE_NAME + " WHERE " + ServerTable.INSTALLED + "=?"; - - return new QueryStatement>(sql, 100) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, true); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map servers = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(ServerTable.SERVER_UUID)); - servers.put(serverUUID, new Server( - set.getInt(ServerTable.SERVER_ID), - serverUUID, - set.getString(ServerTable.NAME), - set.getString(ServerTable.WEB_ADDRESS), - set.getInt(ServerTable.MAX_PLAYERS))); - } - return servers; - } - }; - } - - public static Query> fetchPlanServerInformationCollection() { - return db -> db.query(fetchPlanServerInformation()).values(); - } - - public static Query> fetchServerMatchingIdentifier(UUID serverUUID) { - return fetchServerMatchingIdentifier(serverUUID.toString()); - } - - public static Query> fetchServerMatchingIdentifier(String identifier) { - String sql = "SELECT * FROM " + ServerTable.TABLE_NAME + - " WHERE (LOWER(" + ServerTable.SERVER_UUID + ") LIKE LOWER(?)" + - " OR LOWER(" + ServerTable.NAME + ") LIKE LOWER(?)" + - " OR " + ServerTable.SERVER_ID + "=?)" + - " AND " + ServerTable.INSTALLED + "=?" + - " LIMIT 1"; - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, identifier); - statement.setString(2, identifier); - statement.setInt(3, NumberUtils.isParsable(identifier) ? Integer.parseInt(identifier) : -1); - statement.setBoolean(4, true); - } - - @Override - public Optional processResults(ResultSet set) throws SQLException { - if (set.next()) { - return Optional.of(new Server( - set.getInt(ServerTable.SERVER_ID), - UUID.fromString(set.getString(ServerTable.SERVER_UUID)), - set.getString(ServerTable.NAME), - set.getString(ServerTable.WEB_ADDRESS), - set.getInt(ServerTable.MAX_PLAYERS) - )); - } - return Optional.empty(); - } - }; - } - - public static Query> fetchProxyServerInformation() { - return db -> db.query(fetchServerMatchingIdentifier("BungeeCord")); - } - - public static Query> fetchServerNames() { - String sql = Select.from(ServerTable.TABLE_NAME, - ServerTable.SERVER_UUID, ServerTable.NAME) - .toString(); - - return new QueryAllStatement>(sql) { - @Override - public Map processResults(ResultSet set) throws SQLException { - Map names = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(ServerTable.SERVER_UUID)); - names.put(serverUUID, set.getString(ServerTable.NAME)); - } - return names; - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java deleted file mode 100644 index 8f9e21046..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.data.time.GMTimes; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; -import java.util.stream.Collectors; - -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; - -/** - * Queries for {@link com.djrapitops.plan.data.container.Session} objects. - * - * @author Rsl1122 - */ -public class SessionQueries { - - private SessionQueries() { - /* Static method class */ - } - - private static final String SELECT_SESSIONS_STATEMENT = "SELECT " + - SessionsTable.TABLE_NAME + "." + SessionsTable.ID + ", " + - SessionsTable.TABLE_NAME + "." + SessionsTable.USER_UUID + ", " + - SessionsTable.TABLE_NAME + "." + SessionsTable.SERVER_UUID + ", " + - SessionsTable.SESSION_START + ", " + - SessionsTable.SESSION_END + ", " + - SessionsTable.MOB_KILLS + ", " + - SessionsTable.DEATHS + ", " + - SessionsTable.AFK_TIME + ", " + - WorldTimesTable.SURVIVAL + ", " + - WorldTimesTable.CREATIVE + ", " + - WorldTimesTable.ADVENTURE + ", " + - WorldTimesTable.SPECTATOR + ", " + - WorldTable.NAME + ", " + - KillsTable.VICTIM_UUID + ", " + - UsersTable.USER_NAME + " as victim_name, " + - KillsTable.DATE + ", " + - KillsTable.WEAPON + - " FROM " + SessionsTable.TABLE_NAME + - " LEFT JOIN " + KillsTable.TABLE_NAME + " ON " + SessionsTable.TABLE_NAME + "." + SessionsTable.ID + "=" + KillsTable.TABLE_NAME + "." + KillsTable.SESSION_ID + - " LEFT JOIN " + UsersTable.TABLE_NAME + " on " + UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID + "=" + KillsTable.VICTIM_UUID + - " INNER JOIN " + WorldTimesTable.TABLE_NAME + " ON " + SessionsTable.TABLE_NAME + "." + SessionsTable.ID + "=" + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SESSION_ID + - " INNER JOIN " + WorldTable.TABLE_NAME + " ON " + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.WORLD_ID + "=" + WorldTable.TABLE_NAME + "." + WorldTable.ID; - - private static final String ORDER_BY_SESSION_START_DESC = " ORDER BY " + SessionsTable.SESSION_START + " DESC"; - - /** - * Query the database for Session data without kill, death or world data. - * - * @return Multimap: Server UUID - (Player UUID - List of sessions) - */ - public static Query>>> fetchAllSessionsWithoutKillOrWorldData() { - String sql = "SELECT " + - SessionsTable.ID + ", " + - SessionsTable.USER_UUID + ", " + - SessionsTable.SERVER_UUID + ", " + - SessionsTable.SESSION_START + ", " + - SessionsTable.SESSION_END + ", " + - SessionsTable.DEATHS + ", " + - SessionsTable.MOB_KILLS + ", " + - SessionsTable.AFK_TIME + - " FROM " + SessionsTable.TABLE_NAME; - - return new QueryAllStatement>>>(sql, 20000) { - @Override - public Map>> processResults(ResultSet set) throws SQLException { - Map>> map = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(SessionsTable.SERVER_UUID)); - UUID uuid = UUID.fromString(set.getString(SessionsTable.USER_UUID)); - - Map> sessionsByUser = map.getOrDefault(serverUUID, new HashMap<>()); - List sessions = sessionsByUser.getOrDefault(uuid, new ArrayList<>()); - - long start = set.getLong(SessionsTable.SESSION_START); - long end = set.getLong(SessionsTable.SESSION_END); - - int deaths = set.getInt(SessionsTable.DEATHS); - int mobKills = set.getInt(SessionsTable.MOB_KILLS); - int id = set.getInt(SessionsTable.ID); - - long timeAFK = set.getLong(SessionsTable.AFK_TIME); - - sessions.add(new Session(id, uuid, serverUUID, start, end, mobKills, deaths, timeAFK)); - - sessionsByUser.put(uuid, sessions); - map.put(serverUUID, sessionsByUser); - } - return map; - } - }; - } - - /** - * Query the database for Session data with kill, death or world data. - * - * @return List of sessions - */ - public static Query> fetchAllSessions() { - String sql = SELECT_SESSIONS_STATEMENT + - ORDER_BY_SESSION_START_DESC; - return new QueryAllStatement>(sql, 50000) { - @Override - public List processResults(ResultSet set) throws SQLException { - return extractDataFromSessionSelectStatement(set); - } - }; - } - - /** - * Query the database for Session data of a server with kill and world data. - * - * @param serverUUID UUID of the Plan server. - * @return Map: Player UUID - List of sessions on the server. - */ - public static Query>> fetchSessionsOfServer(UUID serverUUID) { - String sql = SELECT_SESSIONS_STATEMENT + - WHERE + SessionsTable.TABLE_NAME + "." + SessionsTable.SERVER_UUID + "=?" + - ORDER_BY_SESSION_START_DESC; - return new QueryStatement>>(sql, 50000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - List sessions = extractDataFromSessionSelectStatement(set); - return SessionsMutator.sortByPlayers(sessions); - } - }; - } - - /** - * Query the database for Session data of a player with kill and world data. - * - * @param playerUUID UUID of the Player. - * @return Map: Server UUID - List of sessions on the server. - */ - public static Query>> fetchSessionsOfPlayer(UUID playerUUID) { - String sql = SELECT_SESSIONS_STATEMENT + - WHERE + SessionsTable.TABLE_NAME + "." + SessionsTable.USER_UUID + "=?" + - ORDER_BY_SESSION_START_DESC; - return new QueryStatement>>(sql, 50000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - List sessions = extractDataFromSessionSelectStatement(set); - return SessionsMutator.sortByServers(sessions); - } - }; - } - - private static List extractDataFromSessionSelectStatement(ResultSet set) throws SQLException { - // Server UUID - Player UUID - Session Start - Session - Map>> tempSessionMap = new HashMap<>(); - - // Utilities - String[] gms = GMTimes.getGMKeyArray(); - Comparator dateColderRecentComparator = new DateHolderRecentComparator(); - Comparator longRecentComparator = (one, two) -> Long.compare(two, one); // Descending order, most recent first. - - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(SessionsTable.SERVER_UUID)); - Map> serverSessions = tempSessionMap.getOrDefault(serverUUID, new HashMap<>()); - - UUID playerUUID = UUID.fromString(set.getString(SessionsTable.USER_UUID)); - SortedMap playerSessions = serverSessions.getOrDefault(playerUUID, new TreeMap<>(longRecentComparator)); - - long sessionStart = set.getLong(SessionsTable.SESSION_START); - // id, uuid, serverUUID, sessionStart, sessionEnd, mobKills, deaths, afkTime - Session session = playerSessions.getOrDefault(sessionStart, new Session( - set.getInt(SessionsTable.ID), - playerUUID, - serverUUID, - sessionStart, - set.getLong(SessionsTable.SESSION_END), - set.getInt(SessionsTable.MOB_KILLS), - set.getInt(SessionsTable.DEATHS), - set.getLong(SessionsTable.AFK_TIME) - )); - - WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()); - String worldName = set.getString(WorldTable.NAME); - - if (!worldTimes.contains(worldName)) { - Map gmMap = new HashMap<>(); - gmMap.put(gms[0], set.getLong(WorldTimesTable.SURVIVAL)); - gmMap.put(gms[1], set.getLong(WorldTimesTable.CREATIVE)); - gmMap.put(gms[2], set.getLong(WorldTimesTable.ADVENTURE)); - gmMap.put(gms[3], set.getLong(WorldTimesTable.SPECTATOR)); - GMTimes gmTimes = new GMTimes(gmMap); - worldTimes.setGMTimesForWorld(worldName, gmTimes); - } - - String victimName = set.getString("victim_name"); - if (victimName != null) { - UUID victim = UUID.fromString(set.getString(KillsTable.VICTIM_UUID)); - long date = set.getLong(KillsTable.DATE); - String weapon = set.getString(KillsTable.WEAPON); - List playerKills = session.getPlayerKills(); - playerKills.add(new PlayerKill(victim, weapon, date, victimName)); - playerKills.sort(dateColderRecentComparator); - } - - playerSessions.put(sessionStart, session); - serverSessions.put(playerUUID, playerSessions); - tempSessionMap.put(serverUUID, serverSessions); - } - - return tempSessionMap.values().stream() - .map(Map::values) - .flatMap(Collection::stream) - .map(SortedMap::values) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/TPSQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/TPSQueries.java deleted file mode 100644 index 62a444a3f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/TPSQueries.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.builders.TPSBuilder; -import com.djrapitops.plan.data.store.objects.DateObj; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.parsing.Select; -import com.djrapitops.plan.db.sql.tables.ServerTable; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plugin.api.TimeAmount; -import org.apache.commons.text.TextStringBuilder; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; -import static com.djrapitops.plan.db.sql.tables.TPSTable.*; - -/** - * Queries for {@link com.djrapitops.plan.data.container.TPS} objects. - * - * @author Rsl1122 - */ -public class TPSQueries { - - private TPSQueries() { - /* Static method class */ - } - - public static Query> fetchTPSDataOfServer(UUID serverUUID) { - String sql = Select.all(TABLE_NAME) - .where(SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID) - .toString(); - - return new QueryStatement>(sql, 50000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public List processResults(ResultSet set) throws SQLException { - List data = new ArrayList<>(); - while (set.next()) { - - TPS tps = TPSBuilder.get() - .date(set.getLong(DATE)) - .tps(set.getDouble(TPS)) - .playersOnline(set.getInt(PLAYERS_ONLINE)) - .usedCPU(set.getDouble(CPU_USAGE)) - .usedMemory(set.getLong(RAM_USAGE)) - .entities(set.getInt(ENTITIES)) - .chunksLoaded(set.getInt(CHUNKS)) - .freeDiskSpace(set.getLong(FREE_DISK)) - .toTPS(); - - data.add(tps); - } - return data; - } - }; - } - - public static Query>> fetchPlayerOnlineDataOfServers(Collection servers) { - if (servers.isEmpty()) { - return db -> new HashMap<>(); - } - - TextStringBuilder sql = new TextStringBuilder(SELECT); - sql.append(SERVER_ID).append(", ") - .append(DATE).append(", ") - .append(PLAYERS_ONLINE) - .append(FROM).append(TABLE_NAME) - .append(WHERE).append(DATE).append(">").append(System.currentTimeMillis() - TimeAmount.WEEK.toMillis(2L)) - .append(AND).append("("); - sql.appendWithSeparators(servers.stream().map(server -> SERVER_ID + "=" + server.getId()).iterator(), " OR "); - sql.append(")"); - - return new QueryAllStatement>>(sql.toString(), 10000) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> map = new HashMap<>(); - while (set.next()) { - int serverID = set.getInt(SERVER_ID); - int playersOnline = set.getInt(PLAYERS_ONLINE); - long date = set.getLong(DATE); - - List tpsList = map.getOrDefault(serverID, new ArrayList<>()); - - TPS tps = TPSBuilder.get().date(date) - .playersOnline(playersOnline) - .toTPS(); - tpsList.add(tps); - - map.put(serverID, tpsList); - } - return map; - } - }; - } - - public static Query>> fetchPeakPlayerCount(UUID serverUUID, long afterDate) { - String subQuery = "(" + SELECT + "MAX(" + PLAYERS_ONLINE + ")" + FROM + TABLE_NAME + WHERE + SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID + - AND + DATE + ">= ?)"; - String sql = SELECT + - DATE + ", " + PLAYERS_ONLINE + - FROM + TABLE_NAME + - WHERE + SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID + - AND + DATE + ">= ?" + - AND + PLAYERS_ONLINE + "=" + subQuery + - ORDER_BY + DATE + " DESC LIMIT 1"; - - return new QueryStatement>>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - statement.setLong(2, afterDate); - statement.setString(3, serverUUID.toString()); - statement.setLong(4, afterDate); - } - - @Override - public Optional> processResults(ResultSet set) throws SQLException { - if (set.next()) { - return Optional.of(new DateObj<>( - set.getLong(DATE), - set.getInt(PLAYERS_ONLINE) - )); - } - return Optional.empty(); - } - }; - } - - public static Query>> fetchAllTimePeakPlayerCount(UUID serverUUID) { - return fetchPeakPlayerCount(serverUUID, 0); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/UserIdentifierQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/UserIdentifierQueries.java deleted file mode 100644 index 58ba97289..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/UserIdentifierQueries.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.parsing.Select; -import com.djrapitops.plan.db.sql.tables.NicknamesTable; -import com.djrapitops.plan.db.sql.tables.UserInfoTable; -import com.djrapitops.plan.db.sql.tables.UsersTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Queries for fetching different user identifiers in the database. - * - * @author Rsl1122 - */ -public class UserIdentifierQueries { - - private UserIdentifierQueries() { - /* Static method class */ - } - - /** - * Query database for all player UUIDs stored in the Plan database. - * - * @return Set of UUIDs. - */ - public static Query> fetchAllPlayerUUIDs() { - String sql = Select.from(UsersTable.TABLE_NAME, UsersTable.USER_UUID).toString(); - - return new QueryAllStatement>(sql, 20000) { - @Override - public Set processResults(ResultSet set) throws SQLException { - Set playerUUIDs = new HashSet<>(); - while (set.next()) { - UUID playerUUID = UUID.fromString(set.getString(UsersTable.USER_UUID)); - playerUUIDs.add(playerUUID); - } - return playerUUIDs; - } - }; - } - - /** - * Query database for all player UUIDs that have joined a server. - * - * @param serverUUID UUID of the Plan server. - * @return Set of UUIDs. - */ - public static Query> fetchPlayerUUIDsOfServer(UUID serverUUID) { - String sql = SELECT + - UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID + ", " + - FROM + UsersTable.TABLE_NAME + - INNER_JOIN + UserInfoTable.TABLE_NAME + " on " + - UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID + "=" + UserInfoTable.TABLE_NAME + "." + UserInfoTable.USER_UUID + - WHERE + UserInfoTable.SERVER_UUID + "=?"; - return new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Set processResults(ResultSet set) throws SQLException { - Set playerUUIDs = new HashSet<>(); - while (set.next()) { - UUID playerUUID = UUID.fromString(set.getString(UsersTable.USER_UUID)); - playerUUIDs.add(playerUUID); - } - return playerUUIDs; - } - }; - } - - /** - * Query database for a Map for all UUIDs and Player names. - * - * @return Map: Player UUID - Player name - */ - public static Query> fetchAllPlayerNames() { - String sql = Select.from(UsersTable.TABLE_NAME, UsersTable.USER_UUID, UsersTable.USER_NAME).toString(); - - return new QueryAllStatement>(sql, 20000) { - @Override - public Map processResults(ResultSet set) throws SQLException { - Map names = new HashMap<>(); - while (set.next()) { - UUID uuid = UUID.fromString(set.getString((UsersTable.USER_UUID))); - String name = set.getString((UsersTable.USER_NAME)); - - names.put(uuid, name); - } - return names; - } - }; - } - - /** - * Query database for a Player UUID matching a specific player's name. - * - * @param playerName Name of the player, case does not matter. - * @return Optional: UUID if found, empty if not. - */ - public static Query> fetchPlayerUUIDOf(String playerName) { - String sql = Select.from(UsersTable.TABLE_NAME, UsersTable.USER_UUID) - .where("UPPER(" + UsersTable.USER_NAME + ")=UPPER(?)") - .toString(); - - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerName); - } - - @Override - public Optional processResults(ResultSet set) throws SQLException { - if (set.next()) { - String uuidS = set.getString(UsersTable.USER_UUID); - return Optional.of(UUID.fromString(uuidS)); - } - return Optional.empty(); - } - }; - } - - /** - * Query database for a Player name matching a specific player's UUID. - * - * @param playerUUID UUID of the Player - * @return Optional: name if found, empty if not - Case is stored unless using a H2 database. - */ - public static Query> fetchPlayerNameOf(UUID playerUUID) { - String sql = Select.from(UsersTable.TABLE_NAME, UsersTable.USER_NAME).where(UsersTable.USER_UUID + "=?").toString(); - - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Optional processResults(ResultSet set) throws SQLException { - if (set.next()) { - return Optional.of(set.getString(UsersTable.USER_NAME)); - } - return Optional.empty(); - } - }; - } - - public static Query> fetchMatchingPlayerNames(String searchFor) { - String sql = SELECT + DISTINCT + UsersTable.USER_NAME + - FROM + UsersTable.TABLE_NAME + - WHERE + "LOWER(" + UsersTable.USER_NAME + ") LIKE LOWER(?)" + - " UNION " + - SELECT + DISTINCT + UsersTable.USER_NAME + - FROM + UsersTable.TABLE_NAME + - INNER_JOIN + NicknamesTable.TABLE_NAME + " on " + - UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID + "=" + NicknamesTable.TABLE_NAME + "." + NicknamesTable.USER_UUID + - WHERE + "LOWER(" + NicknamesTable.NICKNAME + ") LIKE LOWER(?)"; - - return new QueryStatement>(sql, 5000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, '%' + searchFor + '%'); - statement.setString(2, '%' + searchFor + '%'); - } - - @Override - public List processResults(ResultSet set) throws SQLException { - List matchingNames = new ArrayList<>(); - while (set.next()) { - String match = set.getString(UsersTable.USER_NAME); - if (!matchingNames.contains(match)) { - matchingNames.add(match); - } - } - return matchingNames; - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/UserInfoQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/UserInfoQueries.java deleted file mode 100644 index 8d9ec2836..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/UserInfoQueries.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.data.container.UserInfo; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.UserInfoTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Queries for {@link com.djrapitops.plan.data.container.UserInfo} objects. - * - * @author Rsl1122 - */ -public class UserInfoQueries { - - private UserInfoQueries() { - /* Static method class */ - } - - /** - * Query database for user information. - *

- * The user information does not contain player names. - * - * @return Map: Server UUID - List of user information - */ - public static Query>> fetchAllUserInformation() { - String sql = SELECT + - UserInfoTable.REGISTERED + ", " + - UserInfoTable.BANNED + ", " + - UserInfoTable.OP + ", " + - UserInfoTable.USER_UUID + ", " + - UserInfoTable.SERVER_UUID + - FROM + UserInfoTable.TABLE_NAME; - - return new QueryAllStatement>>(sql, 50000) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> serverMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(UserInfoTable.SERVER_UUID)); - UUID uuid = UUID.fromString(set.getString(UserInfoTable.USER_UUID)); - - List userInfos = serverMap.getOrDefault(serverUUID, new ArrayList<>()); - - long registered = set.getLong(UserInfoTable.REGISTERED); - boolean banned = set.getBoolean(UserInfoTable.BANNED); - boolean op = set.getBoolean(UserInfoTable.OP); - - userInfos.add(new UserInfo(uuid, serverUUID, registered, op, banned)); - serverMap.put(serverUUID, userInfos); - } - return serverMap; - } - }; - } - - /** - * Query database for User information of a specific player. - * - * @param playerUUID UUID of the player. - * @return List of UserInfo objects, one for each server where the player has played. - */ - public static Query> fetchUserInformationOfUser(UUID playerUUID) { - String sql = SELECT + - UserInfoTable.TABLE_NAME + "." + UserInfoTable.REGISTERED + ", " + - UserInfoTable.BANNED + ", " + - UserInfoTable.OP + ", " + - UserInfoTable.SERVER_UUID + - FROM + UserInfoTable.TABLE_NAME + - WHERE + UserInfoTable.TABLE_NAME + "." + UserInfoTable.USER_UUID + "=?"; - - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public List processResults(ResultSet set) throws SQLException { - List userInformation = new ArrayList<>(); - while (set.next()) { - long registered = set.getLong(UserInfoTable.REGISTERED); - boolean op = set.getBoolean(UserInfoTable.OP); - boolean banned = set.getBoolean(UserInfoTable.BANNED); - UUID serverUUID = UUID.fromString(set.getString(UserInfoTable.SERVER_UUID)); - userInformation.add(new UserInfo(playerUUID, serverUUID, registered, op, banned)); - } - return userInformation; - } - }; - } - - /** - * Query database for all User information of a specific server. - * - * @param serverUUID UUID of the Plan server. - * @return Map: Player UUID - user information - */ - public static Query> fetchUserInformationOfServer(UUID serverUUID) { - String sql = SELECT + - UserInfoTable.REGISTERED + ", " + - UserInfoTable.BANNED + ", " + - UserInfoTable.OP + ", " + - UserInfoTable.USER_UUID + ", " + - UserInfoTable.SERVER_UUID + - FROM + UserInfoTable.TABLE_NAME + - WHERE + UserInfoTable.SERVER_UUID + "=?"; - return new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map userInformation = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(UserInfoTable.SERVER_UUID)); - UUID uuid = UUID.fromString(set.getString(UserInfoTable.USER_UUID)); - - long registered = set.getLong(UserInfoTable.REGISTERED); - boolean banned = set.getBoolean(UserInfoTable.BANNED); - boolean op = set.getBoolean(UserInfoTable.OP); - - userInformation.put(uuid, new UserInfo(uuid, serverUUID, registered, op, banned)); - } - return userInformation; - } - }; - } - - /** - * Query database for UUIDs of banned players on a server. - * - * @param serverUUID UUID of the Plan server. - * @return Set: Player UUID of a banned player. - */ - public static Query> fetchBannedUUIDsOfServer(UUID serverUUID) { - String sql = SELECT + - UserInfoTable.USER_UUID + - FROM + UserInfoTable.TABLE_NAME + - WHERE + UserInfoTable.SERVER_UUID + "=?" + - AND + UserInfoTable.BANNED + "=?"; - return new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - statement.setBoolean(2, true); - } - - @Override - public Set processResults(ResultSet set) throws SQLException { - Set bannedUsers = new HashSet<>(); - while (set.next()) { - bannedUsers.add(UUID.fromString(set.getString(UserInfoTable.USER_UUID))); - } - return bannedUsers; - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WebUserQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WebUserQueries.java deleted file mode 100644 index 17212d598..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WebUserQueries.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.SecurityTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -/** - * Queries for {@link com.djrapitops.plan.data.WebUser} objects. - * - * @author Rsl1122 - */ -public class WebUserQueries { - - private WebUserQueries() { - /* Static method class */ - } - - /** - * Query database for all Plan WebUsers. - * - * @return List of Plan WebUsers. - */ - public static Query> fetchAllPlanWebUsers() { - String sql = "SELECT * FROM " + SecurityTable.TABLE_NAME + " ORDER BY " + SecurityTable.PERMISSION_LEVEL + " ASC"; - - return new QueryAllStatement>(sql, 5000) { - @Override - public List processResults(ResultSet set) throws SQLException { - List list = new ArrayList<>(); - while (set.next()) { - String user = set.getString(SecurityTable.USERNAME); - String saltedPassHash = set.getString(SecurityTable.SALT_PASSWORD_HASH); - int permissionLevel = set.getInt(SecurityTable.PERMISSION_LEVEL); - WebUser info = new WebUser(user, saltedPassHash, permissionLevel); - list.add(info); - } - return list; - } - }; - } - - public static Query> fetchWebUser(String called) { - String sql = "SELECT * FROM " + SecurityTable.TABLE_NAME + - " WHERE " + SecurityTable.USERNAME + "=? LIMIT 1"; - return new QueryStatement>(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, called); - } - - @Override - public Optional processResults(ResultSet set) throws SQLException { - if (set.next()) { - String saltedPassHash = set.getString(SecurityTable.SALT_PASSWORD_HASH); - int permissionLevel = set.getInt(SecurityTable.PERMISSION_LEVEL); - return Optional.of(new WebUser(called, saltedPassHash, permissionLevel)); - } - return Optional.empty(); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WorldTimesQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WorldTimesQueries.java deleted file mode 100644 index e1fa6ee85..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WorldTimesQueries.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.objects; - -import com.djrapitops.plan.data.time.GMTimes; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.WorldTable; -import com.djrapitops.plan.db.sql.tables.WorldTimesTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Queries for {@link com.djrapitops.plan.data.time.WorldTimes} objects. - * - * @author Rsl1122 - */ -public class WorldTimesQueries { - - private static String worldColumn = "world"; - private static final String SELECT_WORLD_TIMES_JOIN_WORLD_NAME = WorldTable.TABLE_NAME + "." + WorldTable.NAME + " as " + worldColumn + - FROM + WorldTimesTable.TABLE_NAME + - INNER_JOIN + WorldTable.TABLE_NAME + " on " + WorldTable.TABLE_NAME + "." + WorldTable.ID + "=" + WorldTimesTable.WORLD_ID; - private static final String SELECT_WORLD_TIMES_STATEMENT_START = SELECT + - "SUM(" + WorldTimesTable.SURVIVAL + ") as survival, " + - "SUM(" + WorldTimesTable.CREATIVE + ") as creative, " + - "SUM(" + WorldTimesTable.ADVENTURE + ") as adventure, " + - "SUM(" + WorldTimesTable.SPECTATOR + ") as spectator, "; - - private WorldTimesQueries() { - /* Static method class */ - } - - /** - * Sum total playtime per world on a server. - * - * @param serverUUID Server UUID of the Plan server. - * @return WorldTimes with world name - playtime ms information. - */ - public static Query fetchServerTotalWorldTimes(UUID serverUUID) { - String sql = SELECT_WORLD_TIMES_STATEMENT_START + - SELECT_WORLD_TIMES_JOIN_WORLD_NAME + - WHERE + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SERVER_UUID + "=?" + - GROUP_BY + worldColumn; - - return new QueryStatement(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public WorldTimes processResults(ResultSet set) throws SQLException { - String[] gms = GMTimes.getGMKeyArray(); - - WorldTimes worldTimes = new WorldTimes(); - while (set.next()) { - String worldName = set.getString(worldColumn); - - GMTimes gmTimes = extractGMTimes(set, gms); - - worldTimes.setGMTimesForWorld(worldName, gmTimes); - } - return worldTimes; - } - }; - } - - /** - * Sum total playtime per world on all servers. - * - * @param playerUUID UUID of the player. - * @return WorldTimes with world name - playtime ms information. - */ - public static Query fetchPlayerTotalWorldTimes(UUID playerUUID) { - String sql = SELECT_WORLD_TIMES_STATEMENT_START + - SELECT_WORLD_TIMES_JOIN_WORLD_NAME + - WHERE + WorldTimesTable.USER_UUID + "=?" + - GROUP_BY + worldColumn; - - return new QueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public WorldTimes processResults(ResultSet set) throws SQLException { - String[] gms = GMTimes.getGMKeyArray(); - - WorldTimes worldTimes = new WorldTimes(); - while (set.next()) { - String worldName = set.getString(worldColumn); - - GMTimes gmTimes = extractGMTimes(set, gms); - - worldTimes.setGMTimesForWorld(worldName, gmTimes); - } - return worldTimes; - } - }; - } - - /** - * Find total world times of the player on servers. - * - * @param playerUUID UUID of the player. - * @return Map: Server UUID - WorldTimes total for the server - */ - public static Query> fetchPlayerWorldTimesOnServers(UUID playerUUID) { - String sql = SELECT_WORLD_TIMES_STATEMENT_START + - WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SERVER_UUID + ", " + - SELECT_WORLD_TIMES_JOIN_WORLD_NAME + - WHERE + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.USER_UUID + "=?" + - GROUP_BY + worldColumn + ", " + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SERVER_UUID; - - return new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - String[] gms = GMTimes.getGMKeyArray(); - - Map worldTimesMap = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(WorldTimesTable.SERVER_UUID)); - WorldTimes worldTimes = worldTimesMap.getOrDefault(serverUUID, new WorldTimes()); - String worldName = set.getString(worldColumn); - - GMTimes gmTimes = extractGMTimes(set, gms); - - worldTimes.setGMTimesForWorld(worldName, gmTimes); - worldTimesMap.put(serverUUID, worldTimes); - } - return worldTimesMap; - } - }; - } - - private static GMTimes extractGMTimes(ResultSet set, String[] gms) throws SQLException { - Map gmMap = new HashMap<>(); - for (String gameMode : gms) { - gmMap.put(gameMode, set.getLong(gameMode)); - } - return new GMTimes(gmMap); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/H2SchemaQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/H2SchemaQueries.java deleted file mode 100644 index 0587778a3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/H2SchemaQueries.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.schema; - -import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement; -import com.djrapitops.plan.db.access.Query; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -/** - * Static method class for H2 Schema related queries. - * - * @author Rsl1122 - */ -public class H2SchemaQueries { - - private H2SchemaQueries() { - /* Static method class */ - } - - public static Query doesTableExist(String tableName) { - String sql = "SELECT COUNT(1) as c FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=?"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, tableName); - } - }; - } - - public static Query doesColumnExist(String tableName, String columnName) { - String sql = "SELECT COUNT(1) as c FROM INFORMATION_SCHEMA.COLUMNS" + - " WHERE TABLE_NAME=? AND COLUMN_NAME=?"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, tableName); - statement.setString(2, columnName); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/MySQLSchemaQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/MySQLSchemaQueries.java deleted file mode 100644 index 11122b7ed..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/MySQLSchemaQueries.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.schema; - -import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -/** - * Static method class for MySQL Schema related queries. - * - * @author Rsl1122 - */ -public class MySQLSchemaQueries { - - private MySQLSchemaQueries() { - /* Static method class */ - } - - public static Query doesTableExist(String tableName) { - String sql = "SELECT COUNT(1) as c FROM information_schema.TABLES WHERE table_name=? AND TABLE_SCHEMA=DATABASE()"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, tableName); - } - }; - } - - public static Query> foreignKeyConstraintsOf(String referencedTable) { - String keySQL = "SELECT TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE" + - " WHERE REFERENCED_TABLE_SCHEMA = DATABASE()" + - " AND REFERENCED_TABLE_NAME = ?"; - return new QueryStatement>(keySQL) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, referencedTable); - } - - @Override - public List processResults(ResultSet set) throws SQLException { - List constraints = new ArrayList<>(); - - while (set.next()) { - String table = set.getString("TABLE_NAME"); - String referencedTable = set.getString("REFERENCED_TABLE_NAME"); - String column = set.getString("COLUMN_NAME"); - String referencedColumn = set.getString("REFERENCED_COLUMN_NAME"); - String constraintName = set.getString("CONSTRAINT_NAME"); - - constraints.add(new ForeignKeyConstraint( - table, referencedTable, - column, referencedColumn, - constraintName - )); - } - - return constraints; - } - }; - } - - public static Query doesIndexExist(String indexName, String tableName) { - String sql = "SELECT COUNT(1) as c FROM INFORMATION_SCHEMA.STATISTICS " + - "WHERE table_schema=DATABASE() AND table_name=? AND index_name=?"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, tableName); - statement.setString(2, indexName); - } - }; - } - - public static Query doesColumnExist(String tableName, String columnName) { - String sql = "SELECT COUNT(1) as c FROM information_schema.COLUMNS" + - " WHERE TABLE_NAME=? AND COLUMN_NAME=? AND TABLE_SCHEMA=DATABASE()"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, tableName); - statement.setString(2, columnName); - } - }; - } - - /** - * Represents a FOREIGN KEY constraint in a MySQL database. - * - * @author Rsl1122 - */ - public static class ForeignKeyConstraint { - - private final String table; - private final String referencedTable; - private final String column; - private final String referencedColumn; - private final String constraintName; - - public ForeignKeyConstraint( - String table, String referencedTable, - String column, String referencedColumn, - String constraintName - ) { - this.table = table; - this.referencedTable = referencedTable; - this.column = column; - this.referencedColumn = referencedColumn; - this.constraintName = constraintName; - } - - public String getTable() { - return table; - } - - public String getReferencedTable() { - return referencedTable; - } - - public String getColumn() { - return column; - } - - public String getReferencedColumn() { - return referencedColumn; - } - - public String getConstraintName() { - return constraintName; - } - - @Override - public String toString() { - return "FK '" + constraintName + "' " + - table + "." + column + - " references " + - referencedTable + "." + referencedColumn; - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/SQLiteSchemaQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/SQLiteSchemaQueries.java deleted file mode 100644 index bb788a340..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/SQLiteSchemaQueries.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.schema; - -import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * Static method class for SQLite Schema related queries. - * - * @author Rsl1122 - */ -public class SQLiteSchemaQueries { - - private SQLiteSchemaQueries() { - /* Static method class */ - } - - public static Query doesTableExist(String tableName) { - String sql = "SELECT COUNT(1) as c FROM sqlite_master WHERE tbl_name=?"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, tableName); - } - }; - } - - public static Query doesColumnExist(String tableName, String columnName) { - return new QueryAllStatement("PRAGMA table_info(" + tableName + ")") { - @Override - public Boolean processResults(ResultSet set) throws SQLException { - while (set.next()) { - if (columnName.equals(set.getString("name"))) { - return true; - } - } - return false; - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/SessionIDServerIDRelationQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/SessionIDServerIDRelationQuery.java deleted file mode 100644 index c5c178f94..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/schema/SessionIDServerIDRelationQuery.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.queries.schema; - -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.sql.tables.SessionsTable; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; - -import static com.djrapitops.plan.db.sql.parsing.Sql.FROM; -import static com.djrapitops.plan.db.sql.parsing.Sql.SELECT; - -/** - * Query to fetch server id for each session, used by 2 patches. - * - * @author Rsl1122 - * @see com.djrapitops.plan.db.patches.KillsServerIDPatch - * @see com.djrapitops.plan.db.patches.WorldTimesSeverIDPatch - */ -public class SessionIDServerIDRelationQuery extends QueryAllStatement> { - - public SessionIDServerIDRelationQuery() { - super(SELECT + SessionsTable.ID + ", " + - "(SELECT plan_servers.id FROM plan_servers WHERE plan_servers.uuid=" + SessionsTable.SERVER_UUID + ") as server_id" + - FROM + SessionsTable.TABLE_NAME, 50000); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map idServerIdMap = new HashMap<>(); - while (set.next()) { - idServerIdMap.put(set.getInt(SessionsTable.ID), set.getInt("server_id")); - } - return idServerIdMap; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/BackupCopyTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/BackupCopyTransaction.java deleted file mode 100644 index 07381cad4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/BackupCopyTransaction.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions; - -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.queries.LargeFetchQueries; -import com.djrapitops.plan.db.access.queries.LargeStoreQueries; -import com.djrapitops.plan.db.access.queries.objects.*; -import com.djrapitops.plan.db.access.transactions.commands.RemoveEverythingTransaction; - -import java.util.function.Function; - -/** - * Transaction that performs a clear + copy operation to duplicate a source database in the current one. - * - * @author Rsl1122 - */ -public class BackupCopyTransaction extends RemoveEverythingTransaction { - - private final Database sourceDB; - private final Database destinationDB; - - public BackupCopyTransaction(Database sourceDB, Database destinationDB) { - this.sourceDB = sourceDB; - this.destinationDB = destinationDB; - } - - @Override - protected boolean shouldBeExecuted() { - return !sourceDB.equals(destinationDB) && sourceDB.getState() != Database.State.CLOSED; - } - - @Override - protected void performOperations() { - // Clear the database. - super.performOperations(); - - copyPlanServerInformation(); - copyCommonUserInformation(); - copyWorldNames(); - copyTPSData(); - copyPlanWebUsers(); - copyCommandUsageData(); - copyGeoInformation(); - copyNicknameData(); - copySessionsWithKillAndWorldData(); - copyPerServerUserInformation(); - copyPingData(); - } - - private void copy(Function executableCreator, Query dataQuery) { - // Creates a new Executable from the queried data of the source database - execute(executableCreator.apply(sourceDB.query(dataQuery))); - } - - private void copyPingData() { - copy(LargeStoreQueries::storeAllPingData, PingQueries.fetchAllPingData()); - } - - private void copyCommandUsageData() { - copy(LargeStoreQueries::storeAllCommandUsageData, LargeFetchQueries.fetchAllCommandUsageData()); - } - - private void copyGeoInformation() { - copy(LargeStoreQueries::storeAllGeoInformation, GeoInfoQueries.fetchAllGeoInformation()); - } - - private void copyNicknameData() { - copy(LargeStoreQueries::storeAllNicknameData, NicknameQueries.fetchAllNicknameData()); - } - - private void copyPlanWebUsers() { - copy(LargeStoreQueries::storeAllPlanWebUsers, WebUserQueries.fetchAllPlanWebUsers()); - } - - private void copyPlanServerInformation() { - copy(LargeStoreQueries::storeAllPlanServerInformation, ServerQueries.fetchPlanServerInformationCollection()); - } - - private void copyTPSData() { - copy(LargeStoreQueries::storeAllTPSData, LargeFetchQueries.fetchAllTPSData()); - } - - private void copyPerServerUserInformation() { - copy(LargeStoreQueries::storePerServerUserInformation, UserInfoQueries.fetchAllUserInformation()); - } - - private void copyWorldNames() { - copy(LargeStoreQueries::storeAllWorldNames, LargeFetchQueries.fetchAllWorldNames()); - } - - private void copyCommonUserInformation() { - copy(LargeStoreQueries::storeAllCommonUserInformation, BaseUserQueries.fetchAllBaseUsers()); - } - - private void copySessionsWithKillAndWorldData() { - copy(LargeStoreQueries::storeAllSessionsWithKillAndWorldData, SessionQueries.fetchAllSessions()); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/StoreConfigTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/StoreConfigTransaction.java deleted file mode 100644 index 801fe25b9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/StoreConfigTransaction.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.sql.tables.SettingsTable; -import com.djrapitops.plan.system.settings.config.Config; -import com.djrapitops.plan.system.settings.config.ConfigWriter; -import org.apache.commons.text.TextStringBuilder; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.List; -import java.util.UUID; - -/** - * Transaction to store a server's configuration file in the database. - * - * @author Rsl1122 - */ -public class StoreConfigTransaction extends Transaction { - - private final UUID serverUUID; - private final long lastModified; - private final String configSettings; - - public StoreConfigTransaction(UUID serverUUID, Config config, long lastModified) { - this.serverUUID = serverUUID; - this.configSettings = extractConfigSettingLines(config); - this.lastModified = lastModified; - } - - private String extractConfigSettingLines(Config config) { - TextStringBuilder configTextBuilder = new TextStringBuilder(); - List lines = new ConfigWriter().parseLines(config); - configTextBuilder.appendWithSeparators(lines, "\n"); - return configTextBuilder.toString(); - } - - @Override - protected void performOperations() { - if (query(isConfigStored())) { - execute(updateConfig()); - } else { - execute(insertConfig()); - } - } - - private Query isConfigStored() { - String sql = "SELECT COUNT(1) as c FROM " + SettingsTable.TABLE_NAME + - " WHERE " + SettingsTable.SERVER_UUID + "=? LIMIT 1"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - - } - }; - } - - private Executable updateConfig() { - return new ExecStatement(SettingsTable.UPDATE_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, configSettings); - statement.setLong(2, lastModified); - statement.setString(3, serverUUID.toString()); - statement.setString(4, configSettings); - } - }; - } - - private Executable insertConfig() { - return new ExecStatement(SettingsTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - statement.setLong(2, lastModified); - statement.setString(3, configSettings); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/StoreServerInformationTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/StoreServerInformationTransaction.java deleted file mode 100644 index 30585018b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/StoreServerInformationTransaction.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.system.info.server.Server; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -import static com.djrapitops.plan.db.sql.tables.ServerTable.INSERT_STATEMENT; -import static com.djrapitops.plan.db.sql.tables.ServerTable.UPDATE_STATEMENT; - -/** - * Transaction for keeping Plan Server serverrmation up to date in the database. - * - * @author Rsl1122 - */ -public class StoreServerInformationTransaction extends Transaction { - - private final Server server; - - public StoreServerInformationTransaction(Server server) { - this.server = server; - } - - @Override - protected void performOperations() { - if (!execute(updateServerInformation())) { - execute(insertServerInformation()); - } - } - - private Executable updateServerInformation() { - return new ExecStatement(UPDATE_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - String serverUUIDString = server.getUuid().toString(); - statement.setString(1, serverUUIDString); - statement.setString(2, server.getName()); - statement.setString(3, server.getWebAddress()); - statement.setBoolean(4, true); - statement.setInt(5, server.getMaxPlayers()); - statement.setString(6, serverUUIDString); - } - }; - } - - private Executable insertServerInformation() { - return new ExecStatement(INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, server.getUuid().toString()); - statement.setString(2, server.getName()); - statement.setString(3, server.getWebAddress()); - statement.setBoolean(4, true); - statement.setInt(5, server.getMaxPlayers()); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/Transaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/Transaction.java deleted file mode 100644 index 788890e72..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/Transaction.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plugin.utilities.Verify; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.util.UUID; - -/** - * Represents a database transaction. - * - * @author Rsl1122 - */ -public abstract class Transaction { - - private SQLDB db; - protected DBType dbType; - - private Connection connection; - private Savepoint savepoint; - - protected boolean success; - - protected Transaction() { - success = false; - } - - public void executeTransaction(SQLDB db) { - Verify.nullCheck(db, () -> new IllegalArgumentException("Given database was null")); - Verify.isFalse(success, () -> new IllegalStateException("Transaction has already been executed")); - - this.db = db; - this.dbType = db.getType(); - - if (!shouldBeExecuted()) { - success = true; - return; - } - - try { - initializeTransaction(db); - performOperations(); - if (connection != null) connection.commit(); - success = true; - } catch (Exception statementFail) { - manageFailure(statementFail); // Throws a DBOpException. - } finally { - db.returnToPool(connection); - } - } - - private void manageFailure(Exception statementFail) { - String failMsg = getClass().getSimpleName() + " failed: " + statementFail.getMessage(); - try { - if (Verify.notNull(connection, savepoint)) { - connection.rollback(savepoint); - } - } catch (SQLException rollbackFail) { - throw new DBOpException(failMsg + ", additionally Transaction rollback failed: " + rollbackFail.getMessage(), statementFail); - } - throw new DBOpException(failMsg + ", Transaction was rolled back.", statementFail); - } - - /** - * Override this method for conditional execution. - *

- * Please note that the transaction has not been initialized and class variables are not available for - * queries. The condition should depend on other variables (Like the data that is to be stored) given to the transaction. - * - * @return false if the transaction should not execute. - */ - protected boolean shouldBeExecuted() { - return true; - } - - /** - * Implement this method for transaction execution. - */ - protected abstract void performOperations(); - - private void initializeTransaction(SQLDB db) { - try { - this.connection = db.getConnection(); - this.savepoint = connection.setSavepoint(); - } catch (SQLException e) { - throw new DBOpException(getClass().getSimpleName() + " initialization failed: " + e.getMessage(), e); - } - } - - protected T query(Query query) { - return query.executeQuery(db); - } - - protected boolean execute(Executable executable) { - return executable.execute(connection); - } - - protected boolean execute(String sql) { - return execute(new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) { - // Statement is ready for execution. - } - }); - } - - protected void executeSwallowingExceptions(String... statements) { - Verify.nullCheck(statements); - for (String statement : statements) { - try { - execute(statement); - } catch (DBOpException ignore) { - /* Exceptions swallowed */ - } - } - } - - protected void executeOther(Transaction transaction) { - transaction.db = db; - transaction.dbType = dbType; - transaction.connection = this.connection; - transaction.performOperations(); - transaction.connection = null; - transaction.dbType = null; - transaction.db = null; - } - - protected UUID getServerUUID() { - return db.getServerUUIDSupplier().get(); - } - - @Override - public String toString() { - return getClass().getSimpleName() + (success ? " (finished)" : ""); - } - - public boolean wasSuccessful() { - return success; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RegisterWebUserTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RegisterWebUserTransaction.java deleted file mode 100644 index dcf23199a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RegisterWebUserTransaction.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.commands; - -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.SecurityTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -/** - * Transaction to save a new Plan {@link WebUser} to the database. - * - * @author Rsl1122 - */ -public class RegisterWebUserTransaction extends Transaction { - - private WebUser webUser; - - public RegisterWebUserTransaction(WebUser webUser) { - this.webUser = webUser; - } - - @Override - protected void performOperations() { - execute(new ExecStatement(SecurityTable.INSERT_STATEMENT) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, webUser.getName()); - statement.setString(2, webUser.getSaltedPassHash()); - statement.setInt(3, webUser.getPermLevel()); - } - }); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemoveEverythingTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemoveEverythingTransaction.java deleted file mode 100644 index 2ca5cdf1a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemoveEverythingTransaction.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.commands; - -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.*; - -/** - * Transaction that removes everything from the database. - * - * @author Rsl1122 - */ -public class RemoveEverythingTransaction extends Transaction { - - @Override - protected void performOperations() { - // Delete statements are run in a specific order as some tables have foreign keys, - // or had at some point in the past. - clearTable(SettingsTable.TABLE_NAME); - clearTable(GeoInfoTable.TABLE_NAME); - clearTable(NicknamesTable.TABLE_NAME); - clearTable(KillsTable.TABLE_NAME); - clearTable(WorldTimesTable.TABLE_NAME); - clearTable(SessionsTable.TABLE_NAME); - clearTable(WorldTable.TABLE_NAME); - clearTable(PingTable.TABLE_NAME); - clearTable(UserInfoTable.TABLE_NAME); - clearTable(UsersTable.TABLE_NAME); - clearTable(CommandUseTable.TABLE_NAME); - clearTable(TPSTable.TABLE_NAME); - clearTable(SecurityTable.TABLE_NAME); - clearTable(ServerTable.TABLE_NAME); - clearTable(ExtensionPlayerValueTable.TABLE_NAME); - clearTable(ExtensionServerValueTable.TABLE_NAME); - clearTable(ExtensionProviderTable.TABLE_NAME); - clearTable(ExtensionPlayerTableValueTable.TABLE_NAME); - clearTable(ExtensionServerTableValueTable.TABLE_NAME); - clearTable(ExtensionTableProviderTable.TABLE_NAME); - clearTable(ExtensionTabTable.TABLE_NAME); - clearTable(ExtensionPluginTable.TABLE_NAME); - clearTable(ExtensionIconTable.TABLE_NAME); - } - - private void clearTable(String tableName) { - execute("DELETE FROM " + tableName); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemovePlayerTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemovePlayerTransaction.java deleted file mode 100644 index 0ea22cfce..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemovePlayerTransaction.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.commands; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.queries.PlayerFetchQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.*; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -/** - * Transaction for removing a player's data from the database. - * - * @author Rsl1122 - */ -public class RemovePlayerTransaction extends Transaction { - - private final UUID playerUUID; - - public RemovePlayerTransaction(UUID playerUUID) { - this.playerUUID = playerUUID; - } - - @Override - protected boolean shouldBeExecuted() { - return playerUUID != null; - } - - @Override - protected void performOperations() { - query(PlayerFetchQueries.playerUserName(playerUUID)).ifPresent(this::deleteWebUser); - - deleteFromTable(GeoInfoTable.TABLE_NAME); - deleteFromTable(NicknamesTable.TABLE_NAME); - deleteFromKillsTable(); - deleteFromTable(WorldTimesTable.TABLE_NAME); - deleteFromTable(SessionsTable.TABLE_NAME); - deleteFromTable(PingTable.TABLE_NAME); - deleteFromTable(UserInfoTable.TABLE_NAME); - deleteFromTable(UsersTable.TABLE_NAME); - } - - private void deleteWebUser(String username) { - executeOther(new RemoveWebUserTransaction(username)); - } - - private void deleteFromTable(String tableName) { - execute(new ExecStatement("DELETE FROM " + tableName + " WHERE uuid=?") { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - }); - } - - private void deleteFromKillsTable() { - String sql = "DELETE FROM " + KillsTable.TABLE_NAME + - " WHERE " + KillsTable.KILLER_UUID + "=?" + - " OR " + KillsTable.VICTIM_UUID + "=?"; - execute(new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - statement.setString(2, playerUUID.toString()); - } - }); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemoveWebUserTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemoveWebUserTransaction.java deleted file mode 100644 index bbf3752a5..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/RemoveWebUserTransaction.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.commands; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.SecurityTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -/** - * Transaction to remove a Plan {@link com.djrapitops.plan.data.WebUser} from the database. - * - * @author Rsl1122 - */ -public class RemoveWebUserTransaction extends Transaction { - - private final String username; - - public RemoveWebUserTransaction(String username) { - this.username = username; - } - - @Override - protected void performOperations() { - String sql = "DELETE FROM " + SecurityTable.TABLE_NAME + " WHERE " + SecurityTable.USERNAME + "=?"; - - execute(new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, username); - } - }); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/SetServerAsUninstalledTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/SetServerAsUninstalledTransaction.java deleted file mode 100644 index 9de5d3f0f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/commands/SetServerAsUninstalledTransaction.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.commands; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ServerTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; - -/** - * Transaction for telling Plan that Plan has been uninstalled from the server. - * - * @author Rsl1122 - */ -public class SetServerAsUninstalledTransaction extends Transaction { - - private final UUID serverUUID; - - public SetServerAsUninstalledTransaction(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - @Override - protected void performOperations() { - execute(updateServerAsUninstalled()); - } - - private Executable updateServerAsUninstalled() { - String sql = "UPDATE " + ServerTable.TABLE_NAME + " SET " + ServerTable.INSTALLED + "=?" + - WHERE + ServerTable.SERVER_UUID + "=?"; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, false); - statement.setString(2, serverUUID.toString()); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/BanStatusTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/BanStatusTransaction.java deleted file mode 100644 index 6a7593478..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/BanStatusTransaction.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.parsing.Update; -import com.djrapitops.plan.db.sql.tables.UserInfoTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; -import java.util.function.BooleanSupplier; - -/** - * Transaction to update a player's ban status. - * - * @author Rsl1122 - */ -public class BanStatusTransaction extends Transaction { - - private UUID playerUUID; - private BooleanSupplier banStatus; - - public BanStatusTransaction(UUID playerUUID, BooleanSupplier banStatus) { - this.playerUUID = playerUUID; - this.banStatus = banStatus; - } - - @Override - protected void performOperations() { - execute(updateBanStatus()); - } - - private Executable updateBanStatus() { - String sql = Update.values(UserInfoTable.TABLE_NAME, UserInfoTable.BANNED) - .where(UserInfoTable.USER_UUID + "=?") - .toString(); - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, banStatus.getAsBoolean()); - statement.setString(2, playerUUID.toString()); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/CommandStoreTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/CommandStoreTransaction.java deleted file mode 100644 index 42602ddae..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/CommandStoreTransaction.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.db.access.queries.DataStoreQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; - -import java.util.UUID; - -/** - * Transaction to update command usage information in the database. - * - * @author Rsl1122 - */ -public class CommandStoreTransaction extends Transaction { - - private final UUID serverUUID; - private final String commandName; - - public CommandStoreTransaction( - UUID serverUUID, - String commandName - ) { - this.serverUUID = serverUUID; - this.commandName = commandName; - } - - @Override - protected boolean shouldBeExecuted() { - return commandName.length() <= 20; - } - - @Override - protected void performOperations() { - execute(DataStoreQueries.storeUsedCommandInformation(serverUUID, commandName)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/GeoInfoStoreTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/GeoInfoStoreTransaction.java deleted file mode 100644 index ac5392f91..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/GeoInfoStoreTransaction.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.db.access.queries.DataStoreQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; - -import java.net.InetAddress; -import java.security.NoSuchAlgorithmException; -import java.util.UUID; -import java.util.function.UnaryOperator; - -/** - * Transaction to update Geo information of a player in the database. - * - * @author Rsl1122 - */ -public class GeoInfoStoreTransaction extends Transaction { - - private static boolean hasFailed = false; - - private final UUID playerUUID; - private InetAddress ip; - private long time; - private UnaryOperator geolocationFunction; - - private GeoInfo geoInfo; - - public GeoInfoStoreTransaction( - UUID playerUUID, - InetAddress ip, - long time, - UnaryOperator geolocationFunction - ) { - this.playerUUID = playerUUID; - this.ip = ip; - this.time = time; - this.geolocationFunction = geolocationFunction; - } - - public GeoInfoStoreTransaction(UUID playerUUID, GeoInfo geoInfo) { - this.playerUUID = playerUUID; - this.geoInfo = geoInfo; - } - - @Override - protected boolean shouldBeExecuted() { - return !hasFailed; - } - - public static void setAsFailed() { - hasFailed = true; - } - - private GeoInfo createGeoInfo() throws NoSuchAlgorithmException { - String country = geolocationFunction.apply(ip.getHostAddress()); - return new GeoInfo(ip, country, time); - } - - @Override - protected void performOperations() { - try { - if (geoInfo == null) geoInfo = createGeoInfo(); - - execute(DataStoreQueries.storeGeoInfo(playerUUID, geoInfo)); - } catch (NoSuchAlgorithmException noSHA256Available) { - // SHA256 not available. - setAsFailed(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/KickStoreTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/KickStoreTransaction.java deleted file mode 100644 index ee9ae7ce2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/KickStoreTransaction.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.UsersTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; - -/** - * Transaction to store information in the database when a player is kicked from the server. - * - * @author Rsl1122 - */ -public class KickStoreTransaction extends Transaction { - - private final UUID playerUUID; - - public KickStoreTransaction(UUID playerUUID) { - this.playerUUID = playerUUID; - } - - @Override - protected void performOperations() { - String sql = "UPDATE " + UsersTable.TABLE_NAME + " SET " - + UsersTable.TIMES_KICKED + "=" + UsersTable.TIMES_KICKED + "+ 1" + - WHERE + UsersTable.USER_UUID + "=?"; - - execute(new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - }); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/NicknameStoreTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/NicknameStoreTransaction.java deleted file mode 100644 index 41e3d6a85..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/NicknameStoreTransaction.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.db.access.queries.DataStoreQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; - -import java.util.UUID; -import java.util.function.BiPredicate; - -/** - * Transaction to store player's nickname information in the database. - * - * @author Rsl1122 - */ -public class NicknameStoreTransaction extends Transaction { - - private final UUID playerUUID; - private final Nickname nickname; - private final BiPredicate isNicknameCachedCheck; - - public NicknameStoreTransaction(UUID playerUUID, Nickname nickname, BiPredicate isNicknameCachedCheck) { - this.playerUUID = playerUUID; - this.nickname = nickname; - this.isNicknameCachedCheck = isNicknameCachedCheck; - } - - @Override - protected boolean shouldBeExecuted() { - return !isNicknameCachedCheck.test(playerUUID, nickname.getName()); - } - - @Override - protected void performOperations() { - execute(DataStoreQueries.storePlayerNickname(playerUUID, nickname)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/OperatorStatusTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/OperatorStatusTransaction.java deleted file mode 100644 index 458fb5305..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/OperatorStatusTransaction.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.parsing.Update; -import com.djrapitops.plan.db.sql.tables.UserInfoTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -/** - * Transaction to update a player's operator status. - * - * @author Rsl1122 - */ -public class OperatorStatusTransaction extends Transaction { - - private UUID playerUUID; - private boolean operatorStatus; - - public OperatorStatusTransaction(UUID playerUUID, boolean operatorStatus) { - this.playerUUID = playerUUID; - this.operatorStatus = operatorStatus; - } - - @Override - protected void performOperations() { - execute(updateOperatorStatus()); - } - - private Executable updateOperatorStatus() { - String sql = Update.values(UserInfoTable.TABLE_NAME, UserInfoTable.OP) - .where(UserInfoTable.USER_UUID + "=?") - .toString(); - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, operatorStatus); - statement.setString(2, playerUUID.toString()); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PingStoreTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PingStoreTransaction.java deleted file mode 100644 index 4bb4b2ce4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PingStoreTransaction.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.data.store.objects.DateObj; -import com.djrapitops.plan.db.access.queries.DataStoreQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.utilities.analysis.Median; -import com.google.common.annotations.VisibleForTesting; - -import java.util.List; -import java.util.OptionalInt; -import java.util.UUID; -import java.util.stream.Collectors; - -/** - * Transaction to store player's Ping value on a server. - * - * @author Rsl1122 - */ -public class PingStoreTransaction extends Transaction { - - private final UUID playerUUID; - private final UUID serverUUID; - private final List> pingList; - - private OptionalInt max; - - public PingStoreTransaction(UUID playerUUID, UUID serverUUID, List> pingList) { - this.playerUUID = playerUUID; - this.serverUUID = serverUUID; - this.pingList = pingList; - } - - @Override - protected boolean shouldBeExecuted() { - max = getMax(); - return max.isPresent(); - } - - @Override - protected void performOperations() { - Ping ping = calculateAggregatePing(); - execute(DataStoreQueries.storePing(playerUUID, serverUUID, ping)); - } - - private Ping calculateAggregatePing() { - long lastDate = pingList.get(pingList.size() - 1).getDate(); - - int minValue = getMinValue(); - int meanValue = getMeanValue(); - int maxValue = max.getAsInt(); - - return new Ping(lastDate, serverUUID, minValue, maxValue, meanValue); - } - - private int getMinValue() { - return pingList.stream() - .mapToInt(DateObj::getValue) - .filter(i -> i > 0 && i < 4000) - .min().orElse(-1); - } - - private OptionalInt getMax() { - return pingList.stream() - .mapToInt(DateObj::getValue) - .filter(i -> i > 0 && i < 4000) - .max(); - } - - @VisibleForTesting - int getMeanValue() { - return (int) Median.forList(pingList.stream().map(DateObj::getValue).collect(Collectors.toList())).calculate(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PlayerRegisterTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PlayerRegisterTransaction.java deleted file mode 100644 index 320e7da61..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PlayerRegisterTransaction.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.db.access.queries.DataStoreQueries; -import com.djrapitops.plan.db.access.queries.PlayerFetchQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; - -import java.util.UUID; -import java.util.function.LongSupplier; - -/** - * Transaction for registering player's BaseUser to the database. - * - * @author Rsl1122 - */ -public class PlayerRegisterTransaction extends Transaction { - - protected final UUID playerUUID; - protected final LongSupplier registered; - private final String playerName; - - public PlayerRegisterTransaction(UUID playerUUID, LongSupplier registered, String playerName) { - this.playerUUID = playerUUID; - this.registered = registered; - this.playerName = playerName; - } - - @Override - protected boolean shouldBeExecuted() { - return playerUUID != null && playerName != null; - } - - @Override - protected void performOperations() { - if (!query(PlayerFetchQueries.isPlayerRegistered(playerUUID))) { - execute(DataStoreQueries.registerBaseUser(playerUUID, registered.getAsLong(), playerName)); - } - execute(DataStoreQueries.updatePlayerName(playerUUID, playerName)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PlayerServerRegisterTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PlayerServerRegisterTransaction.java deleted file mode 100644 index dc4af70e0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/PlayerServerRegisterTransaction.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.db.access.queries.DataStoreQueries; -import com.djrapitops.plan.db.access.queries.PlayerFetchQueries; - -import java.util.UUID; -import java.util.function.LongSupplier; - -/** - * Transaction for registering player's BaseUser and UserInfo to the database. - * - * @author Rsl1122 - */ -public class PlayerServerRegisterTransaction extends PlayerRegisterTransaction { - - private final UUID serverUUID; - - public PlayerServerRegisterTransaction(UUID playerUUID, LongSupplier registered, String playerName, UUID serverUUID) { - super(playerUUID, registered, playerName); - this.serverUUID = serverUUID; - } - - @Override - protected void performOperations() { - super.performOperations(); - if (!query(PlayerFetchQueries.isPlayerRegisteredOnServer(playerUUID, serverUUID))) { - execute(DataStoreQueries.registerUserInfo(playerUUID, registered.getAsLong(), serverUUID)); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/ServerShutdownTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/ServerShutdownTransaction.java deleted file mode 100644 index 21cf21b87..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/ServerShutdownTransaction.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.db.access.queries.LargeStoreQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; - -import java.util.Collection; - -/** - * Transaction to store sessions on server shutdown. - * - * @author Rsl1122 - */ -public class ServerShutdownTransaction extends Transaction { - - private final Collection unsavedSessions; - - public ServerShutdownTransaction(Collection unsavedSessions) { - this.unsavedSessions = unsavedSessions; - } - - @Override - protected void performOperations() { - execute(LargeStoreQueries.storeAllSessionsWithKillAndWorldData(unsavedSessions)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/SessionEndTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/SessionEndTransaction.java deleted file mode 100644 index 5101e74c3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/SessionEndTransaction.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.db.access.queries.DataStoreQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; - -/** - * Transaction for storing a session after a session has ended. - * - * @author Rsl1122 - */ -public class SessionEndTransaction extends Transaction { - - private final Session session; - - public SessionEndTransaction(Session session) { - this.session = session; - } - - @Override - protected void performOperations() { - execute(DataStoreQueries.storeSession(session)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/TPSStoreTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/TPSStoreTransaction.java deleted file mode 100644 index 2b4b1852a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/TPSStoreTransaction.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.builders.TPSBuilder; -import com.djrapitops.plan.db.access.queries.DataStoreQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; - -import java.util.List; -import java.util.UUID; - -/** - * Transaction to store server's TPS data. - * - * @author Rsl1122 - */ -public class TPSStoreTransaction extends Transaction { - - private final UUID serverUUID; - private final List tpsList; - - public TPSStoreTransaction(UUID serverUUID, List tpsList) { - this.serverUUID = serverUUID; - this.tpsList = tpsList; - } - - @Override - protected void performOperations() { - TPS tps = calculateTPS(); - execute(DataStoreQueries.storeTPS(serverUUID, tps)); - } - - private TPS calculateTPS() { - long lastDate = tpsList.get(tpsList.size() - 1).getDate(); - double averageTPS = tpsList.stream().mapToDouble(TPS::getTicksPerSecond).average().orElse(0); - int peakPlayersOnline = tpsList.stream().mapToInt(TPS::getPlayers).max().orElse(0); - double averageCPUUsage = tpsList.stream().mapToDouble(TPS::getCPUUsage).average().orElse(0); - long averageUsedMemory = (long) tpsList.stream().mapToLong(TPS::getUsedMemory).average().orElse(0); - int averageEntityCount = (int) tpsList.stream().mapToInt(TPS::getEntityCount).average().orElse(0); - int averageChunksLoaded = (int) tpsList.stream().mapToInt(TPS::getChunksLoaded).average().orElse(0); - long freeDiskSpace = (long) tpsList.stream().mapToLong(TPS::getFreeDiskSpace).average().orElse(0); - - return TPSBuilder.get() - .date(lastDate) - .tps(averageTPS) - .playersOnline(peakPlayersOnline) - .usedCPU(averageCPUUsage) - .usedMemory(averageUsedMemory) - .entities(averageEntityCount) - .chunksLoaded(averageChunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/WorldNameStoreTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/WorldNameStoreTransaction.java deleted file mode 100644 index 1f8ca3596..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/events/WorldNameStoreTransaction.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.events; - -import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement; -import com.djrapitops.plan.db.access.queries.DataStoreQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.WorldTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -/** - * Transaction to store world name after an event. - * - * @author Rsl1122 - */ -public class WorldNameStoreTransaction extends Transaction { - - private final UUID serverUUID; - private final String worldName; - - public WorldNameStoreTransaction(UUID serverUUID, String worldName) { - this.serverUUID = serverUUID; - this.worldName = worldName; - } - - @Override - protected boolean shouldBeExecuted() { - return doesWorldNameNotExist(); - } - - private boolean doesWorldNameNotExist() { - String sql = "SELECT COUNT(1) as c FROM " + WorldTable.TABLE_NAME + - " WHERE " + WorldTable.NAME + "=?" + - " AND " + WorldTable.SERVER_UUID + "=?"; - return !query(new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, worldName); - statement.setString(2, serverUUID.toString()); - } - }); - } - - @Override - protected void performOperations() { - execute(DataStoreQueries.insertWorldName(serverUUID, worldName)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/CreateIndexTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/CreateIndexTransaction.java deleted file mode 100644 index 4df3079d9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/CreateIndexTransaction.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.init; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.access.queries.schema.MySQLSchemaQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.*; -import org.apache.commons.text.TextStringBuilder; - -/** - * Transaction that creates the database index if it has not yet been created. - * - * @author Rsl1122 - */ -public class CreateIndexTransaction extends Transaction { - - @Override - protected void performOperations() { - createIndex(UsersTable.TABLE_NAME, "plan_users_uuid_index", - UsersTable.USER_UUID - ); - createIndex(UserInfoTable.TABLE_NAME, "plan_user_info_uuid_index", - UserInfoTable.USER_UUID, - UserInfoTable.SERVER_UUID - ); - createIndex(SessionsTable.TABLE_NAME, "plan_sessions_uuid_index", - SessionsTable.USER_UUID, - SessionsTable.SERVER_UUID - ); - createIndex(SessionsTable.TABLE_NAME, "plan_sessions_date_index", - SessionsTable.SESSION_START - ); - createIndex(WorldTimesTable.TABLE_NAME, "plan_world_times_uuid_index", - WorldTimesTable.USER_UUID, - WorldTimesTable.SERVER_UUID - ); - createIndex(KillsTable.TABLE_NAME, "plan_kills_uuid_index", - KillsTable.KILLER_UUID, - KillsTable.VICTIM_UUID, - KillsTable.SERVER_UUID - ); - createIndex(KillsTable.TABLE_NAME, "plan_kills_date_index", - KillsTable.DATE - ); - createIndex(PingTable.TABLE_NAME, "plan_ping_uuid_index", - PingTable.USER_UUID, - PingTable.SERVER_UUID - ); - createIndex(PingTable.TABLE_NAME, "plan_ping_date_index", - PingTable.DATE - ); - createIndex(TPSTable.TABLE_NAME, "plan_tps_date_index", - TPSTable.DATE - ); - } - - private void createIndex(String tableName, String indexName, String... indexedColumns) { - if (indexedColumns.length == 0) { - throw new IllegalArgumentException("Can not create index without columns"); - } - - boolean isMySQL = dbType == DBType.MYSQL; - if (isMySQL) { - boolean indexExists = query(MySQLSchemaQueries.doesIndexExist(indexName, tableName)); - if (indexExists) return; - } - - TextStringBuilder sql = new TextStringBuilder("CREATE INDEX "); - if (!isMySQL) { - sql.append("IF NOT EXISTS "); - } - sql.append(indexName).append(" ON ").append(tableName); - - sql.append(" ("); - sql.appendWithSeparators(indexedColumns, ","); - sql.append(")"); - - execute(sql.toString()); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/CreateTablesTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/CreateTablesTransaction.java deleted file mode 100644 index 35fd01ee1..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/CreateTablesTransaction.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.init; - -import com.djrapitops.plan.db.sql.tables.*; - -/** - * Transaction that creates the table schema of Plan database. - * - * @author Rsl1122 - */ -public class CreateTablesTransaction extends OperationCriticalTransaction { - - @Override - protected void performOperations() { - // DBType is required for SQL parsing, as MySQL and SQLite primary key format differs. - - // Create statements are run in a specific order as some tables have foreign keys, - // or had at some point in the past. - execute(ServerTable.createTableSQL(dbType)); - execute(UsersTable.createTableSQL(dbType)); - execute(UserInfoTable.createTableSQL(dbType)); - execute(GeoInfoTable.createTableSQL(dbType)); - execute(NicknamesTable.createTableSQL(dbType)); - execute(SessionsTable.createTableSQL(dbType)); - execute(KillsTable.createTableSQL(dbType)); - execute(PingTable.createTableSQL(dbType)); - execute(CommandUseTable.createTableSQL(dbType)); - execute(TPSTable.createTableSQL(dbType)); - execute(WorldTable.createTableSQL(dbType)); - execute(WorldTimesTable.createTableSQL(dbType)); - execute(SecurityTable.createTableSQL(dbType)); - execute(SettingsTable.createTableSQL(dbType)); - - // DataExtension tables - execute(ExtensionIconTable.createTableSQL(dbType)); - execute(ExtensionPluginTable.createTableSQL(dbType)); - execute(ExtensionTabTable.createTableSQL(dbType)); - execute(ExtensionProviderTable.createTableSQL(dbType)); - execute(ExtensionPlayerValueTable.createTableSQL(dbType)); - execute(ExtensionServerValueTable.createTableSQL(dbType)); - execute(ExtensionTableProviderTable.createTableSQL(dbType)); - execute(ExtensionPlayerTableValueTable.createTableSQL(dbType)); - execute(ExtensionServerTableValueTable.createTableSQL(dbType)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/OperationCriticalTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/OperationCriticalTransaction.java deleted file mode 100644 index 08a8e7219..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/OperationCriticalTransaction.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.init; - -import com.djrapitops.plan.api.exceptions.database.FatalDBException; -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.transactions.Transaction; - -/** - * Transaction that is required to be executed before a database is operable. - *

- * If this transaction fails the database failed to open. - * - * @author Rsl1122 - */ -public abstract class OperationCriticalTransaction extends Transaction { - - @Override - public void executeTransaction(SQLDB db) { - super.executeTransaction(db); - if (!success) { - throw new FatalDBException(getClass().getSimpleName() + " failed to execute and database can not be opened."); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/RemoveDuplicateUserInfoTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/RemoveDuplicateUserInfoTransaction.java deleted file mode 100644 index 213be15dc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/RemoveDuplicateUserInfoTransaction.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.init; - -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.UserInfoTable; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Transaction for removing duplicate data in plan_user_info. - *

- * https://github.com/plan-player-analytics/Plan/issues/956 - * https://github.com/plan-player-analytics/Plan/issues/967 - * - * @author Rsl1122 - */ -public class RemoveDuplicateUserInfoTransaction extends Transaction { - - private static final String COLUMN_ID = UserInfoTable.TABLE_NAME + '.' + UserInfoTable.ID; - private static final String STATEMENT_SELECT_DUPLICATE_IDS = - SELECT + "MIN(" + COLUMN_ID + ") as id" + FROM + UserInfoTable.TABLE_NAME + - GROUP_BY + UserInfoTable.USER_UUID + ", " + UserInfoTable.SERVER_UUID; - - @Override - protected void performOperations() { - execute( - "DELETE" + FROM + UserInfoTable.TABLE_NAME + - WHERE + COLUMN_ID + - // Nested query here is required because MySQL limits update statements with nested queries: - // The nested query creates a temporary table that bypasses the same table query-update limit. - // Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception. - " NOT IN (" + SELECT + "id" + FROM + '(' + STATEMENT_SELECT_DUPLICATE_IDS + ") as ids)" - ); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/RemoveOldSampledDataTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/RemoveOldSampledDataTransaction.java deleted file mode 100644 index c86739439..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/transactions/init/RemoveOldSampledDataTransaction.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.access.transactions.init; - -import com.djrapitops.plan.data.store.objects.DateObj; -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.queries.objects.TPSQueries; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.PingTable; -import com.djrapitops.plan.db.sql.tables.TPSTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Optional; -import java.util.UUID; - -/** - * Transaction for cleaning up old data from the database. - * - * @author Rsl1122 - */ -public class RemoveOldSampledDataTransaction extends Transaction { - - private final UUID serverUUID; - private final long deleteTPSOlderThanMs; - private final long deletePingOlderThanMs; - - public RemoveOldSampledDataTransaction( - UUID serverUUID, - long deleteTPSOlderThanMs, - long deletePingOlderThanMs - ) { - this.serverUUID = serverUUID; - this.deleteTPSOlderThanMs = deleteTPSOlderThanMs; - this.deletePingOlderThanMs = deletePingOlderThanMs; - } - - @Override - protected void performOperations() { - Optional allTimePeak = query(TPSQueries.fetchAllTimePeakPlayerCount(serverUUID)).map(DateObj::getValue); - - execute(cleanTPSTable(allTimePeak.orElse(-1))); - execute(cleanPingTable()); - } - - private Executable cleanTPSTable(int allTimePlayerPeak) { - String sql = "DELETE FROM " + TPSTable.TABLE_NAME + - " WHERE (" + TPSTable.DATE + ". - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement; -import com.djrapitops.plan.db.sql.tables.SessionsTable; - -import java.sql.PreparedStatement; - -/** - * Patch that resets AFK time of sessions with afk time of length of the session to 0. - *

- * This is a bug remedy patch that attempts to turn "bad" afk data to good. - * In 4.5.2 there was a bug that caused some config setting defaults not being copied, along those - * AFKThreshold setting, which lead to AFK threshold being read as 0. - * This in turn lead to full sessions being regarded as having been AFK. - * - * @author Rsl1122 - */ -public class BadAFKThresholdValuePatch extends Patch { - - @Override - public boolean hasBeenApplied() { - return !containsSessionsWithFullAFK(); - } - - private boolean containsSessionsWithFullAFK() { - // where |afk - session_length| < 5 - String sql = "SELECT COUNT(1) as found FROM " + SessionsTable.TABLE_NAME + - " WHERE ABS(" + - SessionsTable.AFK_TIME + - " - (" + SessionsTable.SESSION_END + "-" + SessionsTable.SESSION_START + - ")) < 5 AND " + SessionsTable.AFK_TIME + "!=0"; - return query(new HasMoreThanZeroQueryStatement(sql, "found") { - @Override - public void prepare(PreparedStatement statement) { - /* Nothing to prepare */ - } - }); - } - - @Override - protected void applyPatch() { - // where |afk - session_length| < 5 - String sql = "UPDATE " + SessionsTable.TABLE_NAME + " SET " + SessionsTable.AFK_TIME + "=0 WHERE ABS(" + - SessionsTable.AFK_TIME + - " - (" + SessionsTable.SESSION_END + "-" + SessionsTable.SESSION_START + - ")) < 5 AND " + SessionsTable.AFK_TIME + "!=0"; - execute(sql); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/DeleteIPHashesPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/DeleteIPHashesPatch.java deleted file mode 100644 index b449a317f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/DeleteIPHashesPatch.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement; -import com.djrapitops.plan.db.sql.tables.GeoInfoTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Patch for removing ip_hash values from plan_ips table. - *

- * The patch is a response to a concern: - * "Hashed IP addresses are pseudonymised not anonymised and can be easily decoded using a rainbow table". - * - * @author Rsl1122 - */ -public class DeleteIPHashesPatch extends Patch { - - private static final String IP_HASH = "ip_hash"; - - private boolean hasNoHashColumn; - - @Override - public boolean hasBeenApplied() { - hasNoHashColumn = !hasColumn(GeoInfoTable.TABLE_NAME, IP_HASH); - - String sql = SELECT + "COUNT(1) as c" + FROM + GeoInfoTable.TABLE_NAME + - WHERE + IP_HASH + IS_NOT_NULL; - - return hasNoHashColumn || !query(new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) { - /* No variables needed */ - } - }); - } - - @Override - protected void applyPatch() { - if (hasNoHashColumn) { - return; - } - - String sql = "UPDATE " + GeoInfoTable.TABLE_NAME + " SET ip_hash=?" + WHERE + IP_HASH + IS_NOT_NULL; - execute(new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setNull(1, Types.VARCHAR); - } - }); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/DiskUsagePatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/DiskUsagePatch.java deleted file mode 100644 index 3493c3893..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/DiskUsagePatch.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.sql.tables.TPSTable; - -public class DiskUsagePatch extends Patch { - - @Override - public boolean hasBeenApplied() { - return hasColumn(TPSTable.TABLE_NAME, TPSTable.FREE_DISK); - } - - @Override - protected void applyPatch() { - addColumn(TPSTable.TABLE_NAME, - TPSTable.FREE_DISK + " bigint NOT NULL DEFAULT -1" - ); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/ExtensionShowInPlayersTablePatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/ExtensionShowInPlayersTablePatch.java deleted file mode 100644 index 66c12e74a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/ExtensionShowInPlayersTablePatch.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.sql.parsing.Sql; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -/** - * Patch to add 'show_in_players_table' to 'plan_extension_providers' - * - * @author Rsl1122 - */ -public class ExtensionShowInPlayersTablePatch extends Patch { - - @Override - public boolean hasBeenApplied() { - return hasColumn(ExtensionProviderTable.TABLE_NAME, ExtensionProviderTable.SHOW_IN_PLAYERS_TABLE); - } - - @Override - protected void applyPatch() { - addColumn(ExtensionProviderTable.TABLE_NAME, ExtensionProviderTable.SHOW_IN_PLAYERS_TABLE + ' ' + Sql.BOOL + " NOT NULL DEFAULT 0"); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/GeoInfoLastUsedPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/GeoInfoLastUsedPatch.java deleted file mode 100644 index 010d3d1ca..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/GeoInfoLastUsedPatch.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.sql.tables.GeoInfoTable; - -public class GeoInfoLastUsedPatch extends Patch { - - @Override - public boolean hasBeenApplied() { - return hasColumn(GeoInfoTable.TABLE_NAME, GeoInfoTable.LAST_USED); - } - - @Override - protected void applyPatch() { - addColumn(GeoInfoTable.TABLE_NAME, - GeoInfoTable.LAST_USED + " bigint NOT NULL DEFAULT 0" - ); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/GeoInfoOptimizationPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/GeoInfoOptimizationPatch.java deleted file mode 100644 index 38438a4b3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/GeoInfoOptimizationPatch.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.sql.tables.GeoInfoTable; - -public class GeoInfoOptimizationPatch extends Patch { - - private String tempTableName; - private String tableName; - - public GeoInfoOptimizationPatch() { - tableName = GeoInfoTable.TABLE_NAME; - tempTableName = "temp_ips"; - } - - @Override - public boolean hasBeenApplied() { - return hasColumn(tableName, GeoInfoTable.ID) - && hasColumn(tableName, GeoInfoTable.USER_UUID) - && !hasColumn(tableName, "user_id") - && !hasTable(tempTableName); // If this table exists the patch has failed to finish. - } - - @Override - protected void applyPatch() { - tempOldTable(); - execute(GeoInfoTable.createTableSQL(dbType)); - - execute("INSERT INTO " + tableName + " (" + - GeoInfoTable.USER_UUID + ", " + - GeoInfoTable.IP + ", " + - GeoInfoTable.LAST_USED + ", " + - GeoInfoTable.GEOLOCATION + - ") SELECT " + - "(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " + - GeoInfoTable.IP + ", " + - GeoInfoTable.LAST_USED + ", " + - GeoInfoTable.GEOLOCATION + - " FROM " + tempTableName - ); - - dropTable(tempTableName); - } - - private void tempOldTable() { - if (!hasTable(tempTableName)) { - renameTable(tableName, tempTableName); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/IPAnonPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/IPAnonPatch.java deleted file mode 100644 index bc4c1be10..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/IPAnonPatch.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.db.access.ExecBatchStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.access.queries.objects.GeoInfoQueries; -import com.djrapitops.plan.db.sql.tables.GeoInfoTable; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -public class IPAnonPatch extends Patch { - - private String tableName; - private String tempTableName; - - public IPAnonPatch() { - tableName = GeoInfoTable.TABLE_NAME; - tempTableName = "plan_ips_temp"; - } - - @Override - public boolean hasBeenApplied() { - return !containsUnAnonymizedIPs() && !hasTable(tempTableName); - } - - private Boolean containsUnAnonymizedIPs() { - String sql = "SELECT * FROM " + tableName + - " WHERE " + GeoInfoTable.IP + " NOT LIKE ? LIMIT 1"; - - return query(new QueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, "%x%"); - } - - @Override - public Boolean processResults(ResultSet set) throws SQLException { - return set.next(); - } - }); - } - - @Override - protected void applyPatch() { - Map> allGeoInfo = query(GeoInfoQueries.fetchAllGeoInformation()); - anonymizeIPs(allGeoInfo); - groupHashedIPs(); - } - - private void anonymizeIPs(Map> allGeoInfo) { - String sql = "UPDATE " + GeoInfoTable.TABLE_NAME + " SET " + - GeoInfoTable.IP + "=? " + - "WHERE " + GeoInfoTable.IP + "=?"; - - execute(new ExecBatchStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (List geoInfos : allGeoInfo.values()) { - for (GeoInfo geoInfo : geoInfos) { - addToBatch(statement, geoInfo); - } - } - } - - private void addToBatch(PreparedStatement statement, GeoInfo geoInfo) throws SQLException { - try { - String oldIP = geoInfo.getIp(); - if (oldIP.endsWith(".xx.xx") || oldIP.endsWith("xx..")) { - return; - } - GeoInfo updatedInfo = new GeoInfo( - InetAddress.getByName(oldIP), - geoInfo.getGeolocation(), - geoInfo.getDate() - ); - statement.setString(1, updatedInfo.getIp()); - statement.setString(2, geoInfo.getIp()); - statement.addBatch(); - } catch (UnknownHostException ignore) { - // This ip is completely unusable. - } - } - }); - } - - private void groupHashedIPs() { - if (!hasTable(tempTableName)) { - tempOldTable(); - } - execute(GeoInfoTable.createTableSQL(dbType)); - - String userIdColumn = "user_id"; - boolean hasUserIdColumn = hasColumn(tempTableName, userIdColumn); - String identifiers = hasUserIdColumn ? userIdColumn : "id, uuid"; - - execute("INSERT INTO plan_ips (" + - identifiers + ", ip, geolocation, last_used" + - ") SELECT " + - identifiers + ", ip, geolocation, MAX(last_used) FROM plan_ips_temp GROUP BY ip, " + - (hasUserIdColumn ? userIdColumn : "uuid") + - ", geolocation, id"); - dropTable(tempTableName); - } - - private void tempOldTable() { - if (!hasTable(tempTableName)) { - renameTable(tableName, tempTableName); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/KillsOptimizationPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/KillsOptimizationPatch.java deleted file mode 100644 index 4a1461136..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/KillsOptimizationPatch.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.sql.tables.KillsTable; - -public class KillsOptimizationPatch extends Patch { - - private String tempTableName; - private String tableName; - - public KillsOptimizationPatch() { - tableName = KillsTable.TABLE_NAME; - tempTableName = "temp_kills"; - } - - @Override - public boolean hasBeenApplied() { - return hasColumn(tableName, KillsTable.VICTIM_UUID) - && hasColumn(tableName, KillsTable.KILLER_UUID) - && hasColumn(tableName, KillsTable.SERVER_UUID) - && !hasColumn(tableName, "killer_id") - && !hasColumn(tableName, "victim_id") - && !hasColumn(tableName, "server_id") - && !hasTable(tempTableName); // If this table exists the patch has failed to finish. - } - - @Override - protected void applyPatch() { - try { - if (hasTable(tempTableName) && hasColumn(tempTableName, KillsTable.VICTIM_UUID)) { - // In this case a patch has made a table with almost correct schema to a temporary table. - renameTable(tempTableName, tableName); - return; - } else if (hasColumn(tableName, KillsTable.VICTIM_UUID)) { - // In this case a patch has made a table with almost correct schema, but something is not right. - return; - } - - tempOldTable(); - execute(KillsTable.createTableSQL(dbType)); - - execute("INSERT INTO " + tableName + " (" + - KillsTable.VICTIM_UUID + ", " + - KillsTable.KILLER_UUID + ", " + - KillsTable.SERVER_UUID + ", " + - KillsTable.DATE + ", " + - KillsTable.WEAPON + ", " + - KillsTable.SESSION_ID + - ") SELECT " + - "(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".victim_id LIMIT 1), " + - "(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".killer_id LIMIT 1), " + - "(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " + - KillsTable.DATE + ", " + - KillsTable.WEAPON + ", " + - KillsTable.SESSION_ID + - " FROM " + tempTableName - ); - - dropTable(tempTableName); - } catch (Exception e) { - throw new DBOpException(KillsOptimizationPatch.class.getSimpleName() + " failed.", e); - } - } - - private void tempOldTable() { - if (!hasTable(tempTableName)) { - renameTable(tableName, tempTableName); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/KillsServerIDPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/KillsServerIDPatch.java deleted file mode 100644 index 239777464..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/KillsServerIDPatch.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.access.ExecBatchStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.access.queries.schema.SessionIDServerIDRelationQuery; -import com.djrapitops.plan.db.sql.tables.KillsTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Map; - -public class KillsServerIDPatch extends Patch { - - @Override - public boolean hasBeenApplied() { - String tableName = KillsTable.TABLE_NAME; - String columnName = "server_id"; - - // KillsOptimizationPatch makes this patch incompatible with newer patch versions. - return hasColumn(tableName, KillsTable.SERVER_UUID) - || (hasColumn(tableName, columnName) && allValuesHaveServerID(tableName, columnName)); - } - - private Boolean allValuesHaveServerID(String tableName, String columnName) { - String sql = "SELECT * FROM " + tableName + " WHERE " + columnName + "=? LIMIT 1"; - return query(new QueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setInt(1, 0); - } - - @Override - public Boolean processResults(ResultSet set) throws SQLException { - return !set.next(); - } - }); - } - - @Override - protected void applyPatch() { - if (hasColumn(KillsTable.TABLE_NAME, KillsTable.SERVER_UUID)) { - return; - } - - addColumn(KillsTable.TABLE_NAME, "server_id integer NOT NULL DEFAULT 0"); - - Map sessionIDServerIDRelation = query(new SessionIDServerIDRelationQuery()); - - String sql = "UPDATE " + KillsTable.TABLE_NAME + " SET server_id=? WHERE " + KillsTable.SESSION_ID + "=?"; - - execute(new ExecBatchStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (Map.Entry entry : sessionIDServerIDRelation.entrySet()) { - Integer sessionID = entry.getKey(); - Integer serverID = entry.getValue(); - statement.setInt(1, serverID); - statement.setInt(2, sessionID); - statement.addBatch(); - } - } - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/NicknameLastSeenPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/NicknameLastSeenPatch.java deleted file mode 100644 index c676bdde0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/NicknameLastSeenPatch.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.db.access.ExecBatchStatement; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.sql.parsing.Select; -import com.djrapitops.plan.db.sql.tables.NicknamesTable; -import com.djrapitops.plan.db.sql.tables.ServerTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -public class NicknameLastSeenPatch extends Patch { - - @Override - public boolean hasBeenApplied() { - return hasColumn(NicknamesTable.TABLE_NAME, NicknamesTable.LAST_USED); - } - - @Override - protected void applyPatch() { - addColumn(NicknamesTable.TABLE_NAME, - NicknamesTable.LAST_USED + " bigint NOT NULL DEFAULT '0'" - ); - - if (hasColumn(NicknamesTable.TABLE_NAME, NicknamesTable.USER_UUID)) { - // NicknamesOptimizationPatch makes this patch incompatible with newer patch versions. - return; - } - - // Create table if has failed already - executeSwallowingExceptions("CREATE TABLE IF NOT EXISTS plan_actions " + - "(action_id integer, date bigint, server_id integer, user_id integer, additional_info varchar(1))"); - - Map serverUUIDsByID = getServerUUIDsByID(); - Map serverIDsByUUID = new HashMap<>(); - for (Map.Entry entry : serverUUIDsByID.entrySet()) { - serverIDsByUUID.put(entry.getValue(), entry.getKey()); - } - - Map> nicknames = getNicknamesByUserID(serverUUIDsByID); - updateLastUsed(serverIDsByUUID, nicknames); - - executeSwallowingExceptions("DROP TABLE plan_actions"); - } - - private Map getServerUUIDsByID() { - String sql = Select.from(ServerTable.TABLE_NAME, - ServerTable.SERVER_ID, ServerTable.SERVER_UUID) - .toString(); - - return query(new QueryAllStatement>(sql) { - @Override - public Map processResults(ResultSet set) throws SQLException { - Map uuids = new HashMap<>(); - while (set.next()) { - int id = set.getInt(ServerTable.SERVER_ID); - uuids.put(id, UUID.fromString(set.getString(ServerTable.SERVER_UUID))); - } - return uuids; - } - }); - } - - private Map> getNicknamesByUserID(Map serverUUIDsByID) { - String fetchSQL = "SELECT * FROM plan_actions WHERE action_id=3 ORDER BY date DESC"; - return query(new QueryAllStatement>>(fetchSQL, 10000) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> map = new HashMap<>(); - - while (set.next()) { - long date = set.getLong("date"); - int userID = set.getInt("user_id"); - int serverID = set.getInt("server_id"); - UUID serverUUID = serverUUIDsByID.get(serverID); - Nickname nick = new Nickname(set.getString("additional_info"), date, serverUUID); - Set nicknames1 = map.getOrDefault(userID, new HashSet<>()); - if (serverUUID == null || nicknames1.contains(nick)) { - continue; - } - nicknames1.add(nick); - map.put(userID, nicknames1); - } - - return map; - } - }); - } - - private void updateLastUsed(Map serverIDsByUUID, Map> nicknames) { - String updateSQL = "UPDATE " + NicknamesTable.TABLE_NAME + " SET " + NicknamesTable.LAST_USED + "=?" + - " WHERE " + NicknamesTable.NICKNAME + "=?" + - " AND user_id=?" + - " AND server_id=?"; - - execute(new ExecBatchStatement(updateSQL) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (Map.Entry> entry : nicknames.entrySet()) { - Integer userId = entry.getKey(); - Set nicks = entry.getValue(); - for (Nickname nick : nicks) { - Integer serverID = serverIDsByUUID.get(nick.getServerUUID()); - statement.setLong(1, nick.getDate()); - statement.setString(2, nick.getName()); - statement.setInt(3, userId); - statement.setInt(4, serverID); - statement.addBatch(); - } - } - } - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/NicknamesOptimizationPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/NicknamesOptimizationPatch.java deleted file mode 100644 index 3a6c38811..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/NicknamesOptimizationPatch.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.sql.tables.NicknamesTable; - -public class NicknamesOptimizationPatch extends Patch { - - private String tempTableName; - private String tableName; - - public NicknamesOptimizationPatch() { - tableName = NicknamesTable.TABLE_NAME; - tempTableName = "temp_nicknames"; - } - - @Override - public boolean hasBeenApplied() { - return hasColumn(tableName, NicknamesTable.USER_UUID) - && hasColumn(tableName, NicknamesTable.SERVER_UUID) - && !hasColumn(tableName, "user_id") - && !hasColumn(tableName, "server_id") - && !hasTable(tempTableName); // If this table exists the patch has failed to finish. - } - - @Override - protected void applyPatch() { - try { - tempOldTable(); - execute(NicknamesTable.createTableSQL(dbType)); - - execute("INSERT INTO " + tableName + " (" + - NicknamesTable.USER_UUID + ", " + - NicknamesTable.SERVER_UUID + ", " + - NicknamesTable.NICKNAME + ", " + - NicknamesTable.LAST_USED + - ") SELECT " + - "(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " + - "(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " + - NicknamesTable.NICKNAME + ", " + - NicknamesTable.LAST_USED + - " FROM " + tempTableName - ); - - dropTable(tempTableName); - } catch (Exception e) { - throw new DBOpException(NicknamesOptimizationPatch.class.getSimpleName() + " failed.", e); - } - } - - private void tempOldTable() { - if (!hasTable(tempTableName)) { - renameTable(tableName, tempTableName); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/Patch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/Patch.java deleted file mode 100644 index 0c98599d1..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/Patch.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.access.queries.schema.H2SchemaQueries; -import com.djrapitops.plan.db.access.queries.schema.MySQLSchemaQueries; -import com.djrapitops.plan.db.access.queries.schema.SQLiteSchemaQueries; -import com.djrapitops.plan.db.access.transactions.init.OperationCriticalTransaction; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.List; - -public abstract class Patch extends OperationCriticalTransaction { - - private static final String ALTER_TABLE = "ALTER TABLE "; - - public abstract boolean hasBeenApplied(); - - protected abstract void applyPatch(); - - @Override - protected boolean shouldBeExecuted() { - return !hasBeenApplied(); - } - - @Override - protected void performOperations() { - if (dbType == DBType.MYSQL) disableForeignKeyChecks(); - applyPatch(); - if (dbType == DBType.MYSQL) enableForeignKeyChecks(); - } - - private void enableForeignKeyChecks() { - execute("SET FOREIGN_KEY_CHECKS=1"); - } - - private void disableForeignKeyChecks() { - execute("SET FOREIGN_KEY_CHECKS=0"); - } - - protected boolean hasTable(String tableName) { - switch (dbType) { - case H2: - return query(H2SchemaQueries.doesTableExist(tableName)); - case SQLITE: - return query(SQLiteSchemaQueries.doesTableExist(tableName)); - case MYSQL: - return query(MySQLSchemaQueries.doesTableExist(tableName)); - default: - throw new IllegalStateException("Unsupported Database Type: " + dbType.getName()); - } - } - - protected boolean hasColumn(String tableName, String columnName) { - switch (dbType) { - case H2: - return query(H2SchemaQueries.doesColumnExist(tableName, columnName)); - case MYSQL: - return query(MySQLSchemaQueries.doesColumnExist(tableName, columnName)); - case SQLITE: - return query(SQLiteSchemaQueries.doesColumnExist(tableName, columnName)); - default: - throw new IllegalStateException("Unsupported Database Type: " + dbType.getName()); - } - } - - protected void addColumn(String tableName, String columnInfo) { - execute(ALTER_TABLE + tableName + " ADD " + (dbType.supportsMySQLQueries() ? "" : "COLUMN ") + columnInfo); - } - - protected void dropTable(String name) { - execute("DROP TABLE IF EXISTS " + name); - } - - protected void renameTable(String from, String to) { - execute(getRenameTableSQL(from, to)); - } - - private String getRenameTableSQL(String from, String to) { - switch (dbType) { - case SQLITE: - case H2: - return ALTER_TABLE + from + " RENAME TO " + to; - case MYSQL: - return "RENAME TABLE " + from + " TO " + to; - default: - throw new IllegalArgumentException("DBType: " + dbType.getName() + " does not have rename table sql"); - } - } - - protected void dropForeignKeys(String referencedTable) { - if (dbType != DBType.MYSQL) { - return; - } - - List constraints = query(MySQLSchemaQueries.foreignKeyConstraintsOf(referencedTable)); - - for (MySQLSchemaQueries.ForeignKeyConstraint constraint : constraints) { - // Uses information from https://stackoverflow.com/a/34574758 - execute(ALTER_TABLE + constraint.getTable() + - " DROP FOREIGN KEY " + constraint.getConstraintName()); - } - } - - protected void ensureNoForeignKeyConstraints(String table) { - if (dbType != DBType.MYSQL) { - return; - } - - List constraints = query(MySQLSchemaQueries.foreignKeyConstraintsOf(table)); - - Verify.isTrue(constraints.isEmpty(), () -> new DBOpException("Table '" + table + "' has constraints '" + constraints + "'")); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/PingOptimizationPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/PingOptimizationPatch.java deleted file mode 100644 index 2688aa071..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/PingOptimizationPatch.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.sql.tables.PingTable; - -public class PingOptimizationPatch extends Patch { - - private String tempTableName; - private String tableName; - - public PingOptimizationPatch() { - tableName = PingTable.TABLE_NAME; - tempTableName = "temp_ping"; - } - - @Override - public boolean hasBeenApplied() { - return hasColumn(tableName, PingTable.USER_UUID) - && hasColumn(tableName, PingTable.SERVER_UUID) - && !hasColumn(tableName, "user_id") - && !hasColumn(tableName, "server_id") - && !hasTable(tempTableName); // If this table exists the patch has failed to finish. - } - - @Override - protected void applyPatch() { - try { - tempOldTable(); - execute(PingTable.createTableSQL(dbType)); - - execute("INSERT INTO " + tableName + " (" + - PingTable.USER_UUID + ", " + - PingTable.SERVER_UUID + ", " + - PingTable.ID + ", " + - PingTable.MIN_PING + ", " + - PingTable.MAX_PING + ", " + - PingTable.AVG_PING + ", " + - PingTable.DATE + - ") SELECT " + - "(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " + - "(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " + - PingTable.ID + ", " + - PingTable.MIN_PING + ", " + - PingTable.MAX_PING + ", " + - PingTable.AVG_PING + ", " + - PingTable.DATE + - " FROM " + tempTableName - ); - - dropTable(tempTableName); - } catch (Exception e) { - throw new DBOpException(PingOptimizationPatch.class.getSimpleName() + " failed.", e); - } - } - - private void tempOldTable() { - if (!hasTable(tempTableName)) { - renameTable(tableName, tempTableName); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/SessionAFKTimePatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/SessionAFKTimePatch.java deleted file mode 100644 index 38c8a7f5b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/SessionAFKTimePatch.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.sql.tables.SessionsTable; - -public class SessionAFKTimePatch extends Patch { - - @Override - public boolean hasBeenApplied() { - return hasColumn(SessionsTable.TABLE_NAME, SessionsTable.AFK_TIME); - } - - @Override - protected void applyPatch() { - addColumn(SessionsTable.TABLE_NAME, - SessionsTable.AFK_TIME + " bigint NOT NULL DEFAULT 0" - ); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/SessionsOptimizationPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/SessionsOptimizationPatch.java deleted file mode 100644 index ec73e7740..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/SessionsOptimizationPatch.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.sql.tables.SessionsTable; - -public class SessionsOptimizationPatch extends Patch { - - private String tempTableName; - private String tableName; - - public SessionsOptimizationPatch() { - tableName = SessionsTable.TABLE_NAME; - tempTableName = "temp_sessions"; - } - - @Override - public boolean hasBeenApplied() { - return hasColumn(tableName, SessionsTable.USER_UUID) - && hasColumn(tableName, SessionsTable.SERVER_UUID) - && !hasColumn(tableName, "user_id") - && !hasColumn(tableName, "server_id") - && !hasTable(tempTableName); // If this table exists the patch has failed to finish. - } - - @Override - protected void applyPatch() { - try { - dropForeignKeys(tableName); - ensureNoForeignKeyConstraints(tableName); - - tempOldTable(); - - execute(SessionsTable.createTableSQL(dbType)); - - execute("INSERT INTO " + tableName + " (" + - SessionsTable.USER_UUID + ", " + - SessionsTable.SERVER_UUID + ", " + - SessionsTable.ID + ", " + - SessionsTable.SESSION_START + ", " + - SessionsTable.SESSION_END + ", " + - SessionsTable.MOB_KILLS + ", " + - SessionsTable.DEATHS + ", " + - SessionsTable.AFK_TIME + - ") SELECT " + - "(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " + - "(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " + - SessionsTable.ID + ", " + - SessionsTable.SESSION_START + ", " + - SessionsTable.SESSION_END + ", " + - SessionsTable.MOB_KILLS + ", " + - SessionsTable.DEATHS + ", " + - SessionsTable.AFK_TIME + - " FROM " + tempTableName - ); - - dropTable(tempTableName); - } catch (Exception e) { - throw new DBOpException(SessionsOptimizationPatch.class.getSimpleName() + " failed.", e); - } - } - - private void tempOldTable() { - if (!hasTable(tempTableName)) { - renameTable(tableName, tempTableName); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/TransferTableRemovalPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/TransferTableRemovalPatch.java deleted file mode 100644 index c4d8b9002..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/TransferTableRemovalPatch.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -public class TransferTableRemovalPatch extends Patch { - - @Override - public boolean hasBeenApplied() { - return !hasTable("plan_transfer"); - } - - @Override - protected void applyPatch() { - dropTable("plan_transfer"); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/UserInfoOptimizationPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/UserInfoOptimizationPatch.java deleted file mode 100644 index 129675d57..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/UserInfoOptimizationPatch.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.sql.tables.UserInfoTable; - -public class UserInfoOptimizationPatch extends Patch { - - private String tempTableName; - private String tableName; - - public UserInfoOptimizationPatch() { - tableName = UserInfoTable.TABLE_NAME; - tempTableName = "temp_user_info"; - } - - @Override - public boolean hasBeenApplied() { - return hasColumn(tableName, UserInfoTable.USER_UUID) - && hasColumn(tableName, UserInfoTable.SERVER_UUID) - && !hasColumn(tableName, "user_id") - && !hasColumn(tableName, "server_id") - && !hasTable(tempTableName); // If this table exists the patch has failed to finish. - } - - @Override - protected void applyPatch() { - try { - tempOldTable(); - execute(UserInfoTable.createTableSQL(dbType)); - - execute("INSERT INTO " + tableName + " (" + - UserInfoTable.USER_UUID + ", " + - UserInfoTable.SERVER_UUID + ", " + - UserInfoTable.REGISTERED + ", " + - UserInfoTable.BANNED + ", " + - UserInfoTable.OP + - ") SELECT " + - "(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " + - "(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " + - UserInfoTable.REGISTERED + ", " + - UserInfoTable.BANNED + ", " + - UserInfoTable.OP + - " FROM " + tempTableName - ); - - dropTable(tempTableName); - } catch (Exception e) { - throw new DBOpException(UserInfoOptimizationPatch.class.getSimpleName() + " failed.", e); - } - } - - private void tempOldTable() { - if (!hasTable(tempTableName)) { - renameTable(tableName, tempTableName); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/Version10Patch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/Version10Patch.java deleted file mode 100644 index 4d24ed7e8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/Version10Patch.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plan.system.info.server.Server; - -import java.util.Optional; - -import static com.djrapitops.plan.db.sql.parsing.Sql.FROM; - -public class Version10Patch extends Patch { - - private Integer serverID; - - @Override - public boolean hasBeenApplied() { - return !hasTable("plan_gamemodetimes"); - } - - @Override - protected void applyPatch() { - Optional server = query(ServerQueries.fetchServerMatchingIdentifier(getServerUUID())); - serverID = server.map(Server::getId) - .orElseThrow(() -> new IllegalStateException("Server UUID was not registered, try rebooting the plugin.")); - - alterTablesToV10(); - } - - public void alterTablesToV10() { - copyCommandUsage(); - - copyTPS(); - - dropTable(UserInfoTable.TABLE_NAME); - copyUsers(); - - dropTable(GeoInfoTable.TABLE_NAME); - execute(GeoInfoTable.createTableSQL(dbType)); - dropTable(WorldTimesTable.TABLE_NAME); - dropTable(WorldTable.TABLE_NAME); - execute(WorldTable.createTableSQL(dbType)); - execute(WorldTimesTable.createTableSQL(dbType)); - - dropTable("plan_gamemodetimes"); - dropTable("temp_nicks"); - dropTable("temp_kills"); - dropTable("temp_users"); - } - - private void copyUsers() { - String tempTableName = "temp_users"; - renameTable(UsersTable.TABLE_NAME, tempTableName); - - String tempNickTableName = "temp_nicks"; - renameTable(NicknamesTable.TABLE_NAME, tempNickTableName); - - String tempKillsTableName = "temp_kills"; - renameTable(KillsTable.TABLE_NAME, tempKillsTableName); - - execute(UsersTable.createTableSQL(dbType)); - execute(NicknamesTable.createTableSQL(dbType)); - dropTable(SessionsTable.TABLE_NAME); - execute(SessionsTable.createTableSQL(dbType)); - execute(KillsTable.createTableSQL(dbType)); - - execute(UserInfoTable.createTableSQL(dbType)); - - String statement = "INSERT INTO plan_users " + - "(id, uuid, registered, name)" + - " SELECT id, uuid, registered, name" + - FROM + tempTableName; - execute(statement); - statement = "INSERT INTO plan_user_info " + - "(user_id, registered, opped, banned, server_id)" + - " SELECT id, registered, opped, banned, '" + serverID + "'" + - FROM + tempTableName; - execute(statement); - statement = "INSERT INTO plan_nicknames " + - "(user_id, nickname, server_id)" + - " SELECT user_id, nickname, '" + serverID + "'" + - FROM + tempNickTableName; - execute(statement); - statement = "INSERT INTO plan_kills " + - "(killer_id, victim_id, weapon, date, session_id)" + - " SELECT killer_id, victim_id, weapon, date, '0'" + - FROM + tempKillsTableName; - execute(statement); - } - - private void copyCommandUsage() { - String tempTableName = "temp_cmdusg"; - - renameTable("plan_commandusages", tempTableName); - - execute(CommandUseTable.createTableSQL(dbType)); - - String statement = "INSERT INTO plan_commandusages " + - "(command, times_used, server_id)" + - " SELECT command, times_used, '" + serverID + "'" + - FROM + tempTableName; - execute(statement); - - dropTable(tempTableName); - } - - private void copyTPS() { - String tempTableName = "temp_tps"; - - renameTable(TPSTable.TABLE_NAME, tempTableName); - - execute(TPSTable.createTableSQL(dbType)); - - String statement = "INSERT INTO plan_tps " + - "(date, tps, players_online, cpu_usage, ram_usage, entities, chunks_loaded, server_id)" + - " SELECT date, tps, players_online, cpu_usage, ram_usage, entities, chunks_loaded, '" + serverID + "'" + - FROM + tempTableName; - execute(statement); - - dropTable(tempTableName); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/VersionTableRemovalPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/VersionTableRemovalPatch.java deleted file mode 100644 index 9ec07d43f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/VersionTableRemovalPatch.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -public class VersionTableRemovalPatch extends Patch { - - @Override - public boolean hasBeenApplied() { - return !hasTable("plan_version"); - } - - @Override - protected void applyPatch() { - dropTable("plan_version"); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldTimesOptimizationPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldTimesOptimizationPatch.java deleted file mode 100644 index 0d0cbfc43..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldTimesOptimizationPatch.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.sql.tables.WorldTimesTable; - -public class WorldTimesOptimizationPatch extends Patch { - - private String tempTableName; - private String tableName; - - public WorldTimesOptimizationPatch() { - tableName = WorldTimesTable.TABLE_NAME; - tempTableName = "temp_world_times"; - } - - @Override - public boolean hasBeenApplied() { - return hasColumn(tableName, WorldTimesTable.ID) - && hasColumn(tableName, WorldTimesTable.USER_UUID) - && hasColumn(tableName, WorldTimesTable.SERVER_UUID) - && !hasColumn(tableName, "user_id") - && !hasColumn(tableName, "server_id") - && !hasTable(tempTableName); // If this table exists the patch has failed to finish. - } - - @Override - protected void applyPatch() { - try { - tempOldTable(); - execute(WorldTimesTable.createTableSQL(dbType)); - - execute("INSERT INTO " + tableName + " (" + - WorldTimesTable.USER_UUID + ", " + - WorldTimesTable.SERVER_UUID + ", " + - WorldTimesTable.ADVENTURE + ", " + - WorldTimesTable.CREATIVE + ", " + - WorldTimesTable.SURVIVAL + ", " + - WorldTimesTable.SPECTATOR + ", " + - WorldTimesTable.SESSION_ID + ", " + - WorldTimesTable.WORLD_ID + - ") SELECT " + - "(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " + - "(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " + - WorldTimesTable.ADVENTURE + ", " + - WorldTimesTable.CREATIVE + ", " + - WorldTimesTable.SURVIVAL + ", " + - WorldTimesTable.SPECTATOR + ", " + - WorldTimesTable.SESSION_ID + ", " + - WorldTimesTable.WORLD_ID + - " FROM " + tempTableName - ); - - dropTable(tempTableName); - } catch (Exception e) { - throw new DBOpException(WorldTimesOptimizationPatch.class.getSimpleName() + " failed.", e); - } - } - - private void tempOldTable() { - if (!hasTable(tempTableName)) { - renameTable(tableName, tempTableName); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldTimesSeverIDPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldTimesSeverIDPatch.java deleted file mode 100644 index d37135aad..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldTimesSeverIDPatch.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.access.ExecBatchStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.access.queries.schema.SessionIDServerIDRelationQuery; -import com.djrapitops.plan.db.sql.tables.WorldTimesTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Map; - -public class WorldTimesSeverIDPatch extends Patch { - - @Override - public boolean hasBeenApplied() { - String tableName = WorldTimesTable.TABLE_NAME; - String columnName = "server_id"; - - // WorldTimesOptimizationPatch makes this patch incompatible with newer patch versions. - return hasColumn(tableName, "server_uuid") - || hasColumn(tableName, columnName) - && allValuesHaveServerID(tableName, columnName); - } - - private Boolean allValuesHaveServerID(String tableName, String columnName) { - String sql = "SELECT * FROM " + tableName + " WHERE " + columnName + "=? LIMIT 1"; - return query(new QueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setInt(1, 0); - } - - @Override - public Boolean processResults(ResultSet set) throws SQLException { - return !set.next(); - } - }); - } - - @Override - protected void applyPatch() { - Map sessionIDServerIDRelation = query(new SessionIDServerIDRelationQuery()); - - String sql = "UPDATE " + WorldTimesTable.TABLE_NAME + " SET " + - "server_id=?" + - " WHERE " + WorldTimesTable.SESSION_ID + "=?"; - - execute(new ExecBatchStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (Map.Entry entry : sessionIDServerIDRelation.entrySet()) { - Integer sessionID = entry.getKey(); - Integer serverID = entry.getValue(); - statement.setInt(1, serverID); - statement.setInt(2, sessionID); - statement.addBatch(); - } - } - }); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldsOptimizationPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldsOptimizationPatch.java deleted file mode 100644 index 885e95d9e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldsOptimizationPatch.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.sql.tables.WorldTable; - -public class WorldsOptimizationPatch extends Patch { - - private String tempTableName; - private String tableName; - - public WorldsOptimizationPatch() { - tableName = WorldTable.TABLE_NAME; - tempTableName = "temp_worlds"; - } - - @Override - public boolean hasBeenApplied() { - return hasColumn(tableName, WorldTable.ID) - && hasColumn(tableName, WorldTable.SERVER_UUID) - && !hasColumn(tableName, "server_id") - && !hasTable(tempTableName); // If this table exists the patch has failed to finish. - } - - @Override - protected void applyPatch() { - try { - dropForeignKeys(tableName); - ensureNoForeignKeyConstraints(tableName); - - tempOldTable(); - execute(WorldTable.createTableSQL(dbType)); - - execute("INSERT INTO " + tableName + " (" + - WorldTable.ID + ", " + - WorldTable.SERVER_UUID + ", " + - WorldTable.NAME + - ") SELECT " + - WorldTable.ID + ", " + - "(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " + - WorldTable.NAME + - " FROM " + tempTableName - ); - - dropTable(tempTableName); - } catch (Exception e) { - throw new DBOpException(WorldsOptimizationPatch.class.getSimpleName() + " failed.", e); - } - } - - private void tempOldTable() { - if (!hasTable(tempTableName)) { - renameTable(tableName, tempTableName); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldsServerIDPatch.java b/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldsServerIDPatch.java deleted file mode 100644 index 21d40c13e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/patches/WorldsServerIDPatch.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.patches; - -import com.djrapitops.plan.db.access.ExecBatchStatement; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.access.queries.LargeStoreQueries; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.sql.tables.SessionsTable; -import com.djrapitops.plan.db.sql.tables.WorldTable; -import com.djrapitops.plan.db.sql.tables.WorldTimesTable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -public class WorldsServerIDPatch extends Patch { - - @Override - public boolean hasBeenApplied() { - String tableName = WorldTable.TABLE_NAME; - String columnName = "server_id"; - - // WorldsOptimizationPatch makes this patch incompatible with newer patch versions. - return hasColumn(tableName, "server_uuid") - || hasColumn(tableName, columnName) - && allValuesHaveServerID(tableName, columnName); - } - - private Boolean allValuesHaveServerID(String tableName, String columnName) { - String sql = "SELECT *" + FROM + tableName + WHERE + columnName + "=? LIMIT 1"; - return query(new QueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setInt(1, 0); - } - - @Override - public Boolean processResults(ResultSet set) throws SQLException { - return !set.next(); - } - }); - } - - @Override - protected void applyPatch() { - Collection serverUUIDs = query(ServerQueries.fetchPlanServerInformation()).keySet(); - - Map> worldsPerServer = new HashMap<>(); - for (UUID serverUUID : serverUUIDs) { - worldsPerServer.put(serverUUID, getWorldNamesOld(serverUUID)); - } - - execute(LargeStoreQueries.storeAllWorldNames(worldsPerServer)); - - updateWorldTimesTableWorldIDs(); - executeSwallowingExceptions("DELETE FROM " + WorldTable.TABLE_NAME + " WHERE server_id=0"); - } - - private Set getWorldNamesOld(UUID serverUUID) { - String worldIDColumn = WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.WORLD_ID; - String worldSessionIDColumn = WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SESSION_ID; - String sessionIDColumn = SessionsTable.TABLE_NAME + "." + SessionsTable.ID; - String sessionServerUUIDColumn = SessionsTable.TABLE_NAME + "." + SessionsTable.SERVER_UUID; - - String sql = "SELECT DISTINCT " + - WorldTable.NAME + FROM + - WorldTable.TABLE_NAME + - " INNER JOIN " + WorldTimesTable.TABLE_NAME + " on " + worldIDColumn + "=" + WorldTable.TABLE_NAME + "." + WorldTable.ID + - " INNER JOIN " + SessionsTable.TABLE_NAME + " on " + worldSessionIDColumn + "=" + sessionIDColumn + - WHERE + sessionServerUUIDColumn + "=?"; - - return query(new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Set processResults(ResultSet set) throws SQLException { - Set worldNames = new HashSet<>(); - while (set.next()) { - worldNames.add(set.getString(WorldTable.NAME)); - } - return worldNames; - } - }); - } - - private void updateWorldTimesTableWorldIDs() { - List worldObjects = getWorldObjects(); - Map> oldToNewMap = - worldObjects.stream() - .filter(worldObj -> worldObj.serverId == 0) - .collect(Collectors.toMap( - Function.identity(), - oldWorld -> worldObjects.stream() - .filter(worldObj -> worldObj.serverId != 0) - .filter(worldObj -> worldObj.equals(oldWorld)) - .collect(Collectors.toList() - ))); - - String sql = "UPDATE " + WorldTimesTable.TABLE_NAME + " SET " + - WorldTimesTable.WORLD_ID + "=?" + - WHERE + WorldTimesTable.WORLD_ID + "=?" + - AND + "server_id=?"; - execute(new ExecBatchStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - for (Map.Entry> entry : oldToNewMap.entrySet()) { - WorldObj old = entry.getKey(); - for (WorldObj newWorld : entry.getValue()) { - statement.setInt(1, newWorld.id); - statement.setInt(2, old.id); - statement.setInt(3, newWorld.serverId); - statement.addBatch(); - } - } - } - }); - } - - public List getWorldObjects() { - String sql = "SELECT * FROM " + WorldTable.TABLE_NAME; - return query(new QueryAllStatement>(sql, 100) { - @Override - public List processResults(ResultSet set) throws SQLException { - List objects = new ArrayList<>(); - while (set.next()) { - int worldID = set.getInt(WorldTable.ID); - int serverID = set.getInt("server_id"); - String worldName = set.getString(WorldTable.NAME); - objects.add(new WorldObj(worldID, serverID, worldName)); - } - return objects; - } - }); - } -} - -class WorldObj { - final int id; - final int serverId; - final String name; - - public WorldObj(int id, int serverId, String name) { - this.id = id; - this.serverId = serverId; - this.name = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - WorldObj worldObj = (WorldObj) o; - return Objects.equals(name, worldObj.name); - } - - @Override - public int hashCode() { - return Objects.hashCode(name); - } - - @Override - public String toString() { - return "{" + - "id=" + id + - ", serverId=" + serverId + - ", name='" + name + '\'' + - '}'; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/CreateTableParser.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/CreateTableParser.java deleted file mode 100644 index a9f72ac3f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/CreateTableParser.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.parsing; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plugin.utilities.Verify; - -/** - * SqlParser Class for parsing table creation, removal and modification statements. - * - * @author Rsl1122 - */ -public class CreateTableParser { - - private final DBType dbType; - - private final StringBuilder columns; - private final StringBuilder keyConstraints; - - private StringBuilder columnBuilder; - private int columnCount = 0; - private int constraintCount = 0; - - private CreateTableParser(DBType dbType, String tableName) { - this.dbType = dbType; - columns = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " ("); - keyConstraints = new StringBuilder(); - } - - public static CreateTableParser create(String tableName, DBType type) { - return new CreateTableParser(type, tableName); - } - - private void finalizeColumn() { - if (columnBuilder != null) { - if (columnCount > 0) { - columns.append(", "); - } - columns.append(columnBuilder.toString()); - columnCount++; - columnBuilder = null; - } - } - - public CreateTableParser column(String column, String type) { - finalizeColumn(); - columnBuilder = new StringBuilder(); - columnBuilder.append(column).append(" ").append(type); - return this; - } - - public CreateTableParser primaryKey() { - String currentColumn = columnBuilder.substring(0, columnBuilder.indexOf(" ")); - if (dbType.supportsMySQLQueries()) { - notNull(); - columnBuilder.append(" AUTO_INCREMENT"); - primaryKey(currentColumn); - } else { - columnBuilder.append(" PRIMARY KEY"); - } - return this; - } - - public CreateTableParser notNull() { - columnBuilder.append(" NOT NULL"); - return this; - } - - public CreateTableParser unique() { - columnBuilder.append(" UNIQUE"); - return this; - } - - public CreateTableParser defaultValue(boolean value) { - return defaultValue(value ? "1" : "0"); - } - - public CreateTableParser defaultValue(String value) { - columnBuilder.append(" DEFAULT ").append(value); - return this; - } - - public CreateTableParser foreignKey(String column, String referencedTable, String referencedColumn) { - finalizeColumn(); - if (constraintCount > 0) { - keyConstraints.append(", "); - } - keyConstraints.append("FOREIGN KEY(") - .append(column) - .append(") REFERENCES ") - .append(referencedTable) - .append("(") - .append(referencedColumn) - .append(")"); - constraintCount++; - return this; - } - - private void primaryKey(String column) { - finalizeColumn(); - if (constraintCount > 0) { - keyConstraints.append(", "); - } - keyConstraints.append("PRIMARY KEY (").append(column).append(")"); - constraintCount++; - } - - public String build() { - return toString(); - } - - @Override - public String toString() { - finalizeColumn(); - - Verify.isTrue(columnCount > 0, () -> new IllegalStateException("No columns specified for statement '" + columns.toString() + "..'")); - if (constraintCount > 0) { - return columns.toString() + ", " + keyConstraints.toString() + ')'; - } else { - return columns.toString() + ')'; - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Insert.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Insert.java deleted file mode 100644 index f8e45b59e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Insert.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.parsing; - -public class Insert extends SqlParser { - - public Insert(String table) { - super("INSERT INTO " + table); - addSpace(); - } - - public static String values(String table, String... columns) { - Insert parser = new Insert(table); - parser.append("("); - int size = columns.length; - for (int i = 0; i < size; i++) { - if (size > 1 && i > 0) { - parser.append(", "); - } - parser.append(columns[i]); - } - parser.append(") VALUES ("); - for (int i = 0; i < size; i++) { - if (size > 1 && i > 0) { - parser.append(", "); - } - parser.append("?"); - } - parser.append(")"); - return parser.toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Select.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Select.java deleted file mode 100644 index 15988c29f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Select.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.parsing; - -public class Select extends WhereParser { - - public Select(String start) { - super(start); - } - - public static Select from(String table, String... columns) { - Select parser = new Select("SELECT "); - int size = columns.length; - for (int i = 0; i < size; i++) { - if (size > 1 && i > 0) { - parser.append(", "); - } - parser.append(columns[i]); - } - - parser.append(" FROM ").append(table); - return parser; - } - - public static Select all(String table) { - return new Select("SELECT * FROM " + table); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Sql.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Sql.java deleted file mode 100644 index fcd5dd44b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Sql.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.parsing; - -public class Sql { - public static final String INT = "integer"; - public static final String DOUBLE = "double"; - public static final String LONG = "bigint"; - public static final String BOOL = "boolean"; - - public static final String SELECT = "SELECT "; - public static final String DISTINCT = "DISTINCT "; - public static final String FROM = " FROM "; - public static final String WHERE = " WHERE "; - public static final String GROUP_BY = " GROUP BY "; - public static final String ORDER_BY = " ORDER BY "; - public static final String INNER_JOIN = " INNER JOIN "; - public static final String LEFT_JOIN = " LEFT JOIN "; - public static final String AND = " AND "; - public static final String OR = " OR "; - public static final String IS_NULL = " IS NULL"; - public static final String IS_NOT_NULL = " IS NOT NULL"; - - private Sql() { - throw new IllegalStateException("Variable Class"); - } - - public static String varchar(int length) { - return "varchar(" + length + ")"; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/SqlParser.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/SqlParser.java deleted file mode 100644 index 0c467b203..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/SqlParser.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.parsing; - -/** - * Class for parsing different SQL strings. - * - * @author Rsl1122 - */ -public class SqlParser { - - private final StringBuilder s; - - public SqlParser() { - s = new StringBuilder(); - } - - public SqlParser(String start) { - s = new StringBuilder(start); - } - - public SqlParser addSpace() { - s.append(" "); - return this; - } - - public SqlParser append(String string) { - s.append(string); - return this; - } - - @Override - public String toString() { - return s.toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Update.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Update.java deleted file mode 100644 index affea8122..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Update.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.parsing; - -/** - * @author Fuzzlemann - */ -public class Update extends WhereParser { - - public Update(String table) { - super("UPDATE " + table + " SET"); - addSpace(); - } - - public static Update values(String table, String... values) { - Update parser = new Update(table); - - int size = values.length; - for (int i = 0; i < size; i++) { - if (size > 1 && i > 0) { - parser.append(", "); - } - parser.append(values[i] + "=?"); - } - - return parser; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/WhereParser.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/WhereParser.java deleted file mode 100644 index 5b35e937b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/WhereParser.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.parsing; - -/** - * @author Fuzzlemann - */ -public abstract class WhereParser extends SqlParser { - - private int conditions = 0; - - public WhereParser() { - super(); - } - - public WhereParser(String start) { - super(start); - } - - public WhereParser where(String... conditions) { - append(" WHERE "); - for (String condition : conditions) { - if (this.conditions > 0) { - append(" AND "); - } - append("(").append(condition).append(")"); - this.conditions++; - } - - return this; - } - - public WhereParser and(String condition) { - append(" AND "); - append("(").append(condition).append(")"); - this.conditions++; - return this; - } - - public WhereParser or(String condition) { - append(" OR "); - append("(").append(condition).append(")"); - this.conditions++; - return this; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/CommandUseTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/CommandUseTable.java deleted file mode 100644 index 69c8dd60e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/CommandUseTable.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_commandusages'. - * - * Patches affecting this table: - * {@link com.djrapitops.plan.db.patches.Version10Patch} - * - * @author Rsl1122 - */ -public class CommandUseTable { - - public static final String TABLE_NAME = "plan_commandusages"; - - public static final String ID = "id"; - public static final String SERVER_ID = "server_id"; - public static final String COMMAND = "command"; - public static final String TIMES_USED = "times_used"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" - + COMMAND + ", " - + TIMES_USED + ", " - + SERVER_ID - + ") VALUES (?, ?, " + ServerTable.STATEMENT_SELECT_SERVER_ID + ")"; - - public static final String UPDATE_STATEMENT = "UPDATE " + CommandUseTable.TABLE_NAME + " SET " - + CommandUseTable.TIMES_USED + "=" + CommandUseTable.TIMES_USED + "+ 1" + - " WHERE " + CommandUseTable.SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID + - " AND " + CommandUseTable.COMMAND + "=?"; - - private CommandUseTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(COMMAND, Sql.varchar(20)).notNull() - .column(TIMES_USED, Sql.INT).notNull() - .column(SERVER_ID, Sql.INT).notNull() - .foreignKey(SERVER_ID, ServerTable.TABLE_NAME, ServerTable.SERVER_ID) - .toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionIconTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionIconTable.java deleted file mode 100644 index 3cb91e5fa..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionIconTable.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import org.apache.commons.lang3.StringUtils; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Table information about 'plan_extension_icons'. - * - * @author Rsl1122 - */ -public class ExtensionIconTable { - - public static final String TABLE_NAME = "plan_extension_icons"; - - public static final String ID = "id"; - public static final String ICON_NAME = "name"; - public static final String FAMILY = "family"; - public static final String COLOR = "color"; - - public static final String STATEMENT_SELECT_ICON_ID = "(" + SELECT + ID + - FROM + TABLE_NAME + - WHERE + ICON_NAME + "=?" + - AND + FAMILY + "=?" + - AND + COLOR + "=?)"; - - public static void set3IconValuesToStatement(PreparedStatement statement, Icon icon) throws SQLException { - set3IconValuesToStatement(statement, 1, icon); - } - - public static void set3IconValuesToStatement(PreparedStatement statement, int parameterIndex, Icon icon) throws SQLException { - if (icon != null) { - statement.setString(parameterIndex, StringUtils.truncate(icon.getName(), 50)); - statement.setString(parameterIndex + 1, icon.getFamily().name()); - statement.setString(parameterIndex + 2, icon.getColor().name()); - } else { - statement.setNull(parameterIndex, Types.VARCHAR); - statement.setNull(parameterIndex + 1, Types.VARCHAR); - statement.setNull(parameterIndex + 2, Types.VARCHAR); - } - } - - private ExtensionIconTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, INT).primaryKey() - .column(ICON_NAME, Sql.varchar(50)).notNull().defaultValue("'question'") - .column(FAMILY, Sql.varchar(15)).notNull().defaultValue("'" + Family.SOLID.name() + "'") - .column(COLOR, Sql.varchar(25)).notNull().defaultValue("'" + Color.NONE.name() + "'") - .build(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPlayerTableValueTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPlayerTableValueTable.java deleted file mode 100644 index eb7f4c041..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPlayerTableValueTable.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -import static com.djrapitops.plan.db.sql.parsing.Sql.INT; - -/** - * Table information about 'plan_extension_user_table_values'. - * - * @author Rsl1122 - */ -public class ExtensionPlayerTableValueTable { - - public static final String TABLE_NAME = "plan_extension_user_table_values"; - - public static final String ID = "id"; - public static final String TABLE_ID = "table_id"; - public static final String USER_UUID = "uuid"; - - // All values can be null - public static final String VALUE_1 = "col_1_value"; - public static final String VALUE_2 = "col_2_value"; - public static final String VALUE_3 = "col_3_value"; - public static final String VALUE_4 = "col_4_value"; - - private ExtensionPlayerTableValueTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, INT).primaryKey() - .column(USER_UUID, Sql.varchar(36)).notNull() - .column(VALUE_1, Sql.varchar(50)) - .column(VALUE_2, Sql.varchar(50)) - .column(VALUE_3, Sql.varchar(50)) - .column(VALUE_4, Sql.varchar(50)) - .column(TABLE_ID, INT).notNull() - .foreignKey(TABLE_ID, ExtensionTableProviderTable.TABLE_NAME, ExtensionPluginTable.ID) - .build(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPlayerValueTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPlayerValueTable.java deleted file mode 100644 index 8d46cf3c8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPlayerValueTable.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_extension_user_values'. - * - * @author Rsl1122 - */ -public class ExtensionPlayerValueTable { - - public static final String TABLE_NAME = "plan_extension_user_values"; - - public static final String ID = "id"; - public static final String PROVIDER_ID = "provider_id"; - public static final String USER_UUID = "uuid"; - - public static final String BOOLEAN_VALUE = "boolean_value"; - public static final String DOUBLE_VALUE = "double_value"; - public static final String PERCENTAGE_VALUE = "percentage_value"; - public static final String LONG_VALUE = "long_value"; - public static final String STRING_VALUE = "string_value"; - public static final String GROUP_VALUE = "group_value"; - - private ExtensionPlayerValueTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(BOOLEAN_VALUE, Sql.BOOL) - .column(DOUBLE_VALUE, Sql.DOUBLE) - .column(PERCENTAGE_VALUE, Sql.DOUBLE) - .column(LONG_VALUE, Sql.LONG) - .column(STRING_VALUE, Sql.varchar(50)) - .column(GROUP_VALUE, Sql.varchar(50)) - .column(USER_UUID, Sql.varchar(36)).notNull() - .column(PROVIDER_ID, Sql.INT).notNull() - .foreignKey(PROVIDER_ID, ExtensionProviderTable.TABLE_NAME, ExtensionProviderTable.ID) - .build(); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPluginTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPluginTable.java deleted file mode 100644 index 539ca76f1..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionPluginTable.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Table information about 'plan_extension_plugins'. - * - * @author Rsl1122 - */ -public class ExtensionPluginTable { - - public static final String TABLE_NAME = "plan_extension_plugins"; - - public static final String ID = "id"; - public static final String PLUGIN_NAME = "name"; - public static final String LAST_UPDATED = "last_updated"; - public static final String SERVER_UUID = "server_uuid"; - public static final String ICON_ID = "icon_id"; - - public static final String STATEMENT_SELECT_PLUGIN_ID = "(" + SELECT + ID + - FROM + TABLE_NAME + - WHERE + PLUGIN_NAME + "=?" + - AND + SERVER_UUID + "=?)"; - - public static void set2PluginValuesToStatement(PreparedStatement statement, int parameterIndex, String pluginName, UUID serverUUID) throws SQLException { - statement.setString(parameterIndex, pluginName); - statement.setString(parameterIndex + 1, serverUUID.toString()); - } - - private ExtensionPluginTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, INT).primaryKey() - .column(PLUGIN_NAME, Sql.varchar(50)).notNull() - .column(LAST_UPDATED, LONG).notNull() - .column(SERVER_UUID, Sql.varchar(36)).notNull() - .column(ICON_ID, INT).notNull() - .foreignKey(ICON_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID) - .build(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionProviderTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionProviderTable.java deleted file mode 100644 index 140863c49..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionProviderTable.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Table information about 'plan_extension_providers'. - * - * @author Rsl1122 - */ -public class ExtensionProviderTable { - - public static final String TABLE_NAME = "plan_extension_providers"; - - public static final String ID = "id"; - public static final String PROVIDER_NAME = "name"; - public static final String TEXT = "text"; - public static final String DESCRIPTION = "description"; // Can be null - public static final String PRIORITY = "priority"; - public static final String GROUPABLE = "groupable"; // default false - public static final String CONDITION = "condition_name"; // Can be null, related to @Conditional - public static final String PLUGIN_ID = "plugin_id"; - public static final String ICON_ID = "icon_id"; - public static final String TAB_ID = "tab_id"; // Can be null, related to @Tab - public static final String SHOW_IN_PLAYERS_TABLE = "show_in_players_table"; // default false - - public static final String HIDDEN = "hidden"; // default false, related to @BooleanProvider - public static final String PROVIDED_CONDITION = "provided_condition"; // Can be null, related to @BooleanProvider - public static final String FORMAT_TYPE = "format_type"; // Can be null, related to @NumberProvider - public static final String IS_PLAYER_NAME = "player_name"; // default false, related to @StringProvider - - public static final String STATEMENT_SELECT_PROVIDER_ID = "(" + SELECT + ID + FROM + TABLE_NAME + - WHERE + PROVIDER_NAME + "=?" + - AND + PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")"; - - public static void set3PluginValuesToStatement(PreparedStatement statement, int parameterIndex, String providerName, String pluginName, UUID serverUUID) throws SQLException { - statement.setString(parameterIndex, providerName); - ExtensionPluginTable.set2PluginValuesToStatement(statement, parameterIndex + 1, pluginName, serverUUID); - } - - private ExtensionProviderTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, INT).primaryKey() - .column(PROVIDER_NAME, Sql.varchar(50)).notNull() - .column(TEXT, Sql.varchar(50)).notNull() - .column(DESCRIPTION, Sql.varchar(150)) - .column(PRIORITY, INT).notNull().defaultValue("0") - .column(SHOW_IN_PLAYERS_TABLE, BOOL).notNull().defaultValue(false) - .column(GROUPABLE, BOOL).notNull().defaultValue(false) - .column(CONDITION, Sql.varchar(54)) // 50 + 4 for "not_" - .column(PROVIDED_CONDITION, Sql.varchar(50)) - .column(FORMAT_TYPE, Sql.varchar(25)) - .column(HIDDEN, BOOL).notNull().defaultValue(false) - .column(IS_PLAYER_NAME, BOOL).notNull().defaultValue(false) - .column(PLUGIN_ID, INT).notNull() - .column(ICON_ID, INT).notNull() - .column(TAB_ID, INT) - .foreignKey(PLUGIN_ID, ExtensionPluginTable.TABLE_NAME, ExtensionPluginTable.ID) - .foreignKey(ICON_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID) - .foreignKey(TAB_ID, ExtensionTabTable.TABLE_NAME, ExtensionTabTable.ID) - .build(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionServerTableValueTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionServerTableValueTable.java deleted file mode 100644 index 8d28a4817..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionServerTableValueTable.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -import static com.djrapitops.plan.db.sql.parsing.Sql.INT; - -/** - * Table information about 'plan_extension_server_table_values'. - * - * @author Rsl1122 - */ -public class ExtensionServerTableValueTable { - - public static final String TABLE_NAME = "plan_extension_server_table_values"; - - public static final String ID = "id"; - public static final String TABLE_ID = "table_id"; - public static final String SERVER_UUID = "uuid"; - - // All values can be null - public static final String VALUE_1 = "col_1_value"; - public static final String VALUE_2 = "col_2_value"; - public static final String VALUE_3 = "col_3_value"; - public static final String VALUE_4 = "col_4_value"; - public static final String VALUE_5 = "col_5_value"; - - private ExtensionServerTableValueTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, INT).primaryKey() - .column(SERVER_UUID, Sql.varchar(36)).notNull() - .column(VALUE_1, Sql.varchar(50)) - .column(VALUE_2, Sql.varchar(50)) - .column(VALUE_3, Sql.varchar(50)) - .column(VALUE_4, Sql.varchar(50)) - .column(VALUE_5, Sql.varchar(50)) - .column(TABLE_ID, INT).notNull() - .foreignKey(TABLE_ID, ExtensionTableProviderTable.TABLE_NAME, ExtensionPluginTable.ID) - .build(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionServerValueTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionServerValueTable.java deleted file mode 100644 index 45f6db092..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionServerValueTable.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_extension_server_values'. - * - * @author Rsl1122 - */ -public class ExtensionServerValueTable { - - public static final String TABLE_NAME = "plan_extension_server_values"; - - public static final String ID = "id"; - public static final String PROVIDER_ID = "provider_id"; - // Server UUID can be figured out by limiting by Providers. - - public static final String BOOLEAN_VALUE = "boolean_value"; - public static final String DOUBLE_VALUE = "double_value"; - public static final String PERCENTAGE_VALUE = "percentage_value"; - public static final String LONG_VALUE = "long_value"; - public static final String STRING_VALUE = "string_value"; - public static final String GROUP_VALUE = "group_value"; - - private ExtensionServerValueTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(BOOLEAN_VALUE, Sql.BOOL) - .column(DOUBLE_VALUE, Sql.DOUBLE) - .column(PERCENTAGE_VALUE, Sql.DOUBLE) - .column(LONG_VALUE, Sql.LONG) - .column(STRING_VALUE, Sql.varchar(50)) - .column(GROUP_VALUE, Sql.varchar(50)) - .column(PROVIDER_ID, Sql.INT).notNull() - .foreignKey(PROVIDER_ID, ExtensionProviderTable.TABLE_NAME, ExtensionProviderTable.ID) - .build(); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionTabTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionTabTable.java deleted file mode 100644 index 04496cd1e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionTabTable.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; -import com.djrapitops.plan.extension.ElementOrder; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Table information about 'plan_extension_tabs'. - * - * @author Rsl1122 - */ -public class ExtensionTabTable { - - public static final String TABLE_NAME = "plan_extension_tabs"; - - public static final String ID = "id"; - public static final String TAB_NAME = "name"; - public static final String ELEMENT_ORDER = "element_order"; - public static final String TAB_PRIORITY = "tab_priority"; - public static final String PLUGIN_ID = "plugin_id"; - public static final String ICON_ID = "icon_id"; - - public static final String STATEMENT_SELECT_TAB_ID = "(" + SELECT + ID + - FROM + TABLE_NAME + - WHERE + TAB_NAME + "=?" + - AND + PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")"; - - public static void set3TabValuesToStatement(PreparedStatement statement, int parameterIndex, String tabName, String pluginName, UUID serverUUID) throws SQLException { - statement.setString(parameterIndex, tabName); - ExtensionPluginTable.set2PluginValuesToStatement(statement, parameterIndex + 1, pluginName, serverUUID); - } - - private ExtensionTabTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, INT).primaryKey() - .column(TAB_NAME, Sql.varchar(50)).notNull() - .column(ELEMENT_ORDER, Sql.varchar(100)).notNull().defaultValue("'" + ElementOrder.serialize(ElementOrder.values()) + "'") - .column(TAB_PRIORITY, INT).notNull() - .column(PLUGIN_ID, INT).notNull() - .column(ICON_ID, INT).notNull() - .foreignKey(PLUGIN_ID, ExtensionPluginTable.TABLE_NAME, ExtensionPluginTable.ID) - .foreignKey(ICON_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID) - .build(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionTableProviderTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionTableProviderTable.java deleted file mode 100644 index 99ae732e4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ExtensionTableProviderTable.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; -import com.djrapitops.plan.extension.icon.Color; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Table information about 'plan_extension_tables'. - * - * @author Rsl1122 - */ -public class ExtensionTableProviderTable { - - public static final String TABLE_NAME = "plan_extension_tables"; - - public static final String ID = "id"; - public static final String PROVIDER_NAME = "name"; - public static final String COLOR = "color"; - public static final String CONDITION = "condition_name"; // Can be null, related to @Conditional - public static final String PLUGIN_ID = "plugin_id"; - public static final String TAB_ID = "tab_id"; // Can be null, related to @Tab - - // All columns can be null - public static final String COL_1 = "col_1_name"; - public static final String COL_2 = "col_2_name"; - public static final String COL_3 = "col_3_name"; - public static final String COL_4 = "col_4_name"; - public static final String COL_5 = "col_5_name"; - - // All icons can be null - public static final String ICON_1_ID = "icon_1_id"; - public static final String ICON_2_ID = "icon_2_id"; - public static final String ICON_3_ID = "icon_3_id"; - public static final String ICON_4_ID = "icon_4_id"; - public static final String ICON_5_ID = "icon_5_id"; - - public static final String STATEMENT_SELECT_TABLE_ID = "(" + SELECT + ID + FROM + TABLE_NAME + - WHERE + PROVIDER_NAME + "=?" + - AND + PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")"; - - private ExtensionTableProviderTable() { - /* Static information class */ - } - - public static void set3PluginValuesToStatement(PreparedStatement statement, int parameterIndex, String providerName, String pluginName, UUID serverUUID) throws SQLException { - statement.setString(parameterIndex, providerName); - ExtensionPluginTable.set2PluginValuesToStatement(statement, parameterIndex + 1, pluginName, serverUUID); - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, INT).primaryKey() - .column(PROVIDER_NAME, Sql.varchar(50)).notNull() - .column(COLOR, Sql.varchar(25)).notNull().defaultValue("'" + Color.NONE.name() + "'") - .column(CONDITION, Sql.varchar(54)) // 50 + 4 for "not_" - .column(COL_1, Sql.varchar(50)) - .column(COL_2, Sql.varchar(50)) - .column(COL_3, Sql.varchar(50)) - .column(COL_4, Sql.varchar(50)) - .column(COL_5, Sql.varchar(50)) - .column(PLUGIN_ID, INT).notNull() - .column(ICON_1_ID, INT) - .column(ICON_2_ID, INT) - .column(ICON_3_ID, INT) - .column(ICON_4_ID, INT) - .column(ICON_5_ID, INT) - .column(TAB_ID, INT) - .foreignKey(PLUGIN_ID, ExtensionPluginTable.TABLE_NAME, ExtensionPluginTable.ID) - .foreignKey(ICON_1_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID) - .foreignKey(ICON_2_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID) - .foreignKey(ICON_3_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID) - .foreignKey(ICON_4_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID) - .foreignKey(ICON_5_ID, ExtensionIconTable.TABLE_NAME, ExtensionIconTable.ID) - .foreignKey(TAB_ID, ExtensionTabTable.TABLE_NAME, ExtensionTabTable.ID) - .build(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/GeoInfoTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/GeoInfoTable.java deleted file mode 100644 index 850fc4b64..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/GeoInfoTable.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.patches.*; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_ips'. - *

- * Patches related to this table: - * {@link Version10Patch} - * {@link GeoInfoLastUsedPatch} - * {@link IPAnonPatch} - * {@link GeoInfoOptimizationPatch} - * {@link DeleteIPHashesPatch} - * - * @author Rsl1122 - */ -public class GeoInfoTable { - - public static final String TABLE_NAME = "plan_ips"; - - public static final String ID = "id"; - public static final String USER_UUID = "uuid"; - public static final String IP = "ip"; - public static final String GEOLOCATION = "geolocation"; - public static final String LAST_USED = "last_used"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" - + USER_UUID + ", " - + IP + ", " - + GEOLOCATION + ", " - + LAST_USED - + ") VALUES (?, ?, ?, ?)"; - - public static final String UPDATE_STATEMENT = "UPDATE " + TABLE_NAME + " SET " - + LAST_USED + "=?" + - " WHERE " + USER_UUID + "=?" + - " AND " + GEOLOCATION + "=?"; - - private GeoInfoTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(USER_UUID, Sql.varchar(36)).notNull() - .column(IP, Sql.varchar(39)).notNull() - .column(GEOLOCATION, Sql.varchar(50)).notNull() - .column(LAST_USED, Sql.LONG).notNull().defaultValue("0") - .toString(); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/KillsTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/KillsTable.java deleted file mode 100644 index d790eb589..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/KillsTable.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.patches.KillsOptimizationPatch; -import com.djrapitops.plan.db.patches.KillsServerIDPatch; -import com.djrapitops.plan.db.patches.Version10Patch; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -/** - * Table information about 'plan_kills'. - *

- * Patches related to this table: - * {@link Version10Patch} - * {@link KillsServerIDPatch} - * {@link KillsOptimizationPatch} - * - * @author Rsl1122 - */ -public class KillsTable { - - public static final String TABLE_NAME = "plan_kills"; - - public static final String ID = "id"; - public static final String KILLER_UUID = "killer_uuid"; - public static final String VICTIM_UUID = "victim_uuid"; - public static final String SERVER_UUID = "server_uuid"; - public static final String SESSION_ID = "session_id"; - public static final String WEAPON = "weapon"; - public static final String DATE = "date"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" - + SESSION_ID + ", " - + KILLER_UUID + ", " - + VICTIM_UUID + ", " - + SERVER_UUID + ", " - + DATE + ", " - + WEAPON - + ") VALUES (" + SessionsTable.SELECT_SESSION_ID_STATEMENT + ", ?, ?, ?, ?, ?)"; - - private KillsTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(KILLER_UUID, Sql.varchar(36)).notNull() - .column(VICTIM_UUID, Sql.varchar(36)).notNull() - .column(SERVER_UUID, Sql.varchar(36)).notNull() - .column(WEAPON, Sql.varchar(30)).notNull() - .column(DATE, Sql.LONG).notNull() - .column(SESSION_ID, Sql.INT).notNull() - .foreignKey(SESSION_ID, SessionsTable.TABLE_NAME, SessionsTable.ID) - .toString(); - } - - public static void addSessionKillsToBatch(PreparedStatement statement, Session session) throws SQLException { - UUID uuid = session.getUnsafe(SessionKeys.UUID); - UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID); - - for (PlayerKill kill : session.getPlayerKills()) { - // Session ID select statement parameters - statement.setString(1, uuid.toString()); - statement.setString(2, serverUUID.toString()); - statement.setLong(3, session.getUnsafe(SessionKeys.START)); - statement.setLong(4, session.getUnsafe(SessionKeys.END)); - - // Kill data - statement.setString(5, uuid.toString()); - statement.setString(6, kill.getVictim().toString()); - statement.setString(7, serverUUID.toString()); - statement.setLong(8, kill.getDate()); - statement.setString(9, kill.getWeapon()); - statement.addBatch(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/NicknamesTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/NicknamesTable.java deleted file mode 100644 index 91a7e8cfe..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/NicknamesTable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.patches.NicknameLastSeenPatch; -import com.djrapitops.plan.db.patches.NicknamesOptimizationPatch; -import com.djrapitops.plan.db.patches.Version10Patch; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_nicknames'. - *

- * Patches related to this table: - * {@link Version10Patch} - * {@link NicknameLastSeenPatch} - * {@link NicknamesOptimizationPatch} - * - * @author Rsl1122 - */ -public class NicknamesTable { - - public static final String TABLE_NAME = "plan_nicknames"; - - public static final String ID = "id"; - public static final String USER_UUID = "uuid"; - public static final String SERVER_UUID = "server_uuid"; - public static final String NICKNAME = "nickname"; - public static final String LAST_USED = "last_used"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" + - USER_UUID + ", " + - SERVER_UUID + ", " + - NICKNAME + ", " + - LAST_USED + - ") VALUES (?, ?, ?, ?)"; - - public static final String UPDATE_STATEMENT = "UPDATE " + TABLE_NAME + " SET " + LAST_USED + "=?" + - " WHERE " + NICKNAME + "=?" + - " AND " + USER_UUID + "=?" + - " AND " + SERVER_UUID + "=?"; - - private NicknamesTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(USER_UUID, Sql.varchar(36)).notNull() - .column(NICKNAME, Sql.varchar(75)).notNull() - .column(SERVER_UUID, Sql.varchar(36)).notNull() - .column(LAST_USED, Sql.LONG).notNull() - .toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/PingTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/PingTable.java deleted file mode 100644 index fbd37adaf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/PingTable.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.patches.PingOptimizationPatch; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_ping'. - *

- * Patches related to this table: - * {@link PingOptimizationPatch} - * - * @author Rsl1122 - */ -public class PingTable { - - public static final String TABLE_NAME = "plan_ping"; - - public static final String ID = "id"; - public static final String USER_UUID = "uuid"; - public static final String SERVER_UUID = "server_uuid"; - public static final String DATE = "date"; - public static final String MAX_PING = "max_ping"; - public static final String AVG_PING = "avg_ping"; - public static final String MIN_PING = "min_ping"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" + - USER_UUID + ", " + - SERVER_UUID + ", " + - DATE + ", " + - MIN_PING + ", " + - MAX_PING + ", " + - AVG_PING + - ") VALUES (?, ?, ?, ?, ?, ?)"; - - private PingTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(USER_UUID, Sql.varchar(36)).notNull() - .column(SERVER_UUID, Sql.varchar(36)).notNull() - .column(DATE, Sql.LONG).notNull() - .column(MAX_PING, Sql.INT).notNull() - .column(MIN_PING, Sql.INT).notNull() - .column(AVG_PING, Sql.DOUBLE).notNull() - .toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SecurityTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SecurityTable.java deleted file mode 100644 index ff43fac70..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SecurityTable.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Insert; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_security' - * - * @author Rsl1122 - */ -public class SecurityTable { - - public static final String TABLE_NAME = "plan_security"; - - public static final String USERNAME = "username"; - public static final String SALT_PASSWORD_HASH = "salted_pass_hash"; - public static final String PERMISSION_LEVEL = "permission_level"; - - public static final String INSERT_STATEMENT = Insert.values(TABLE_NAME, USERNAME, SALT_PASSWORD_HASH, PERMISSION_LEVEL); - - private SecurityTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(USERNAME, Sql.varchar(100)).notNull().unique() - .column(SALT_PASSWORD_HASH, Sql.varchar(100)).notNull().unique() - .column(PERMISSION_LEVEL, Sql.INT).notNull() - .toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ServerTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ServerTable.java deleted file mode 100644 index a9a774842..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/ServerTable.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Insert; -import com.djrapitops.plan.db.sql.parsing.Sql; -import com.djrapitops.plan.db.sql.parsing.Update; -import com.djrapitops.plan.system.info.server.Server; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Table information about 'plan_servers'. - * - * @author Rsl1122 - * @see Server - */ -public class ServerTable { - - public static final String TABLE_NAME = "plan_servers"; - - public static final String SERVER_ID = "id"; - public static final String SERVER_UUID = "uuid"; - public static final String NAME = "name"; - public static final String WEB_ADDRESS = "web_address"; - public static final String INSTALLED = "is_installed"; - public static final String MAX_PLAYERS = "max_players"; - - public static final String INSERT_STATEMENT = Insert.values(TABLE_NAME, - SERVER_UUID, NAME, - WEB_ADDRESS, INSTALLED, MAX_PLAYERS); - - public static final String UPDATE_STATEMENT = Update.values(TABLE_NAME, - SERVER_UUID, - NAME, - WEB_ADDRESS, - INSTALLED, - MAX_PLAYERS) - .where(SERVER_UUID + "=?") - .toString(); - - public static final String STATEMENT_SELECT_SERVER_ID = - "(" + SELECT + TABLE_NAME + "." + SERVER_ID + - FROM + TABLE_NAME + - WHERE + TABLE_NAME + "." + SERVER_UUID + "=?" + - " LIMIT 1)"; - - private ServerTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(SERVER_ID, Sql.INT).primaryKey() - .column(SERVER_UUID, Sql.varchar(36)).notNull().unique() - .column(NAME, Sql.varchar(100)) - .column(WEB_ADDRESS, Sql.varchar(100)) - .column(INSTALLED, Sql.BOOL).notNull().defaultValue(true) - .column(MAX_PLAYERS, Sql.INT).notNull().defaultValue("-1") - .toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SessionsTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SessionsTable.java deleted file mode 100644 index 0fc827d3b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SessionsTable.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.patches.SessionAFKTimePatch; -import com.djrapitops.plan.db.patches.SessionsOptimizationPatch; -import com.djrapitops.plan.db.patches.Version10Patch; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Table information about 'plan_sessions'. - *

- * Patches related to this table: - * {@link Version10Patch} - * {@link SessionAFKTimePatch} - * {@link SessionsOptimizationPatch} - * - * @author Rsl1122 - */ -public class SessionsTable { - - public static final String TABLE_NAME = "plan_sessions"; - - public static final String ID = "id"; - public static final String USER_UUID = "uuid"; - public static final String SERVER_UUID = "server_uuid"; - public static final String SESSION_START = "session_start"; - public static final String SESSION_END = "session_end"; - public static final String MOB_KILLS = "mob_kills"; - public static final String DEATHS = "deaths"; - public static final String AFK_TIME = "afk_time"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" - + USER_UUID + ", " - + SESSION_START + ", " - + SESSION_END + ", " - + DEATHS + ", " - + MOB_KILLS + ", " - + AFK_TIME + ", " - + SERVER_UUID - + ") VALUES (?, ?, ?, ?, ?, ?, ?)"; - - public static final String SELECT_SESSION_ID_STATEMENT = "(SELECT " + TABLE_NAME + "." + ID + FROM + TABLE_NAME + - WHERE + TABLE_NAME + "." + USER_UUID + "=?" + - AND + TABLE_NAME + "." + SERVER_UUID + "=?" + - AND + SESSION_START + "=?" + - AND + SESSION_END + "=? LIMIT 1)"; - - private SessionsTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(USER_UUID, Sql.varchar(36)).notNull() - .column(SERVER_UUID, Sql.varchar(36)).notNull() - .column(SESSION_START, Sql.LONG).notNull() - .column(SESSION_END, Sql.LONG).notNull() - .column(MOB_KILLS, Sql.INT).notNull() - .column(DEATHS, Sql.INT).notNull() - .column(AFK_TIME, Sql.LONG).notNull() - .toString(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SettingsTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SettingsTable.java deleted file mode 100644 index de5b3355f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SettingsTable.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_settings'. - * - * @author Rsl1122 - */ -public class SettingsTable { - - public static final String TABLE_NAME = "plan_settings"; - - public static final String ID = "id"; - public static final String SERVER_UUID = "server_uuid"; - public static final String UPDATED = "updated"; - public static final String CONFIG_CONTENT = "content"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" + - SERVER_UUID + ", " + - UPDATED + ", " + - CONFIG_CONTENT + ") VALUES (?,?,?)"; - public static final String UPDATE_STATEMENT = "UPDATE " + TABLE_NAME + " SET " + - CONFIG_CONTENT + "=?," + - UPDATED + "=? WHERE " + - SERVER_UUID + "=? AND " + - CONFIG_CONTENT + "!=?"; - - private SettingsTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(SERVER_UUID, Sql.varchar(39)).notNull().unique() - .column(UPDATED, Sql.LONG).notNull() - .column(CONFIG_CONTENT, "TEXT").notNull() - .toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/TPSTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/TPSTable.java deleted file mode 100644 index ae82eec2c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/TPSTable.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_tps'. - * - * @author Rsl1122 - */ -public class TPSTable { - - public static final String TABLE_NAME = "plan_tps"; - - public static final String SERVER_ID = "server_id"; - public static final String DATE = "date"; - public static final String TPS = "tps"; - public static final String PLAYERS_ONLINE = "players_online"; - public static final String CPU_USAGE = "cpu_usage"; - public static final String RAM_USAGE = "ram_usage"; - public static final String ENTITIES = "entities"; - public static final String CHUNKS = "chunks_loaded"; - public static final String FREE_DISK = "free_disk_space"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" - + SERVER_ID + ", " - + DATE + ", " - + TPS + ", " - + PLAYERS_ONLINE + ", " - + CPU_USAGE + ", " - + RAM_USAGE + ", " - + ENTITIES + ", " - + CHUNKS + ", " - + FREE_DISK - + ") VALUES (" - + ServerTable.STATEMENT_SELECT_SERVER_ID + ", " - + "?, ?, ?, ?, ?, ?, ?, ?)"; - - private TPSTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(SERVER_ID, Sql.INT).notNull() - .column(DATE, Sql.LONG).notNull() - .column(TPS, Sql.DOUBLE).notNull() - .column(PLAYERS_ONLINE, Sql.INT).notNull() - .column(CPU_USAGE, Sql.DOUBLE).notNull() - .column(RAM_USAGE, Sql.LONG).notNull() - .column(ENTITIES, Sql.INT).notNull() - .column(CHUNKS, Sql.INT).notNull() - .column(FREE_DISK, Sql.LONG).notNull() - .foreignKey(SERVER_ID, ServerTable.TABLE_NAME, ServerTable.SERVER_ID) - .toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/UserInfoTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/UserInfoTable.java deleted file mode 100644 index 2b6e7e24d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/UserInfoTable.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.patches.UserInfoOptimizationPatch; -import com.djrapitops.plan.db.patches.Version10Patch; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_user_info'. - *

- * Patches related to this table: - * {@link Version10Patch} - * {@link UserInfoOptimizationPatch} - * - * @author Rsl1122 - */ -public class UserInfoTable { - - public static final String TABLE_NAME = "plan_user_info"; - - public static final String ID = "id"; - public static final String USER_UUID = "uuid"; - public static final String SERVER_UUID = "server_uuid"; - public static final String REGISTERED = "registered"; - public static final String OP = "opped"; - public static final String BANNED = "banned"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" + - USER_UUID + ", " + - REGISTERED + ", " + - SERVER_UUID + ", " + - BANNED + ", " + - OP + - ") VALUES (?, ?, ?, ?, ?)"; - - private UserInfoTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(USER_UUID, Sql.varchar(36)).notNull() - .column(SERVER_UUID, Sql.varchar(36)).notNull() - .column(REGISTERED, Sql.LONG).notNull() - .column(OP, Sql.BOOL).notNull().defaultValue(false) - .column(BANNED, Sql.BOOL).notNull().defaultValue(false) - .toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/UsersTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/UsersTable.java deleted file mode 100644 index bf1df723e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/UsersTable.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Insert; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_users'. - * - * This table is used to store Player information that applies to all servers. - * - * Patches that apply to this table: - * {@link com.djrapitops.plan.db.patches.Version10Patch} - * - * @author Rsl1122 - */ -public class UsersTable { - - public static final String TABLE_NAME = "plan_users"; - - public static final String ID = "id"; - public static final String USER_UUID = "uuid"; - public static final String REGISTERED = "registered"; - public static final String USER_NAME = "name"; - public static final String TIMES_KICKED = "times_kicked"; - - public static final String INSERT_STATEMENT = Insert.values(TABLE_NAME, USER_UUID, USER_NAME, REGISTERED, TIMES_KICKED); - - private UsersTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(USER_UUID, Sql.varchar(36)).notNull().unique() - .column(REGISTERED, Sql.LONG).notNull() - .column(USER_NAME, Sql.varchar(16)).notNull() - .column(TIMES_KICKED, Sql.INT).notNull().defaultValue("0") - .toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTable.java deleted file mode 100644 index 9b5b8ff94..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTable.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.patches.Version10Patch; -import com.djrapitops.plan.db.patches.WorldsOptimizationPatch; -import com.djrapitops.plan.db.patches.WorldsServerIDPatch; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -/** - * Table information about 'plan_worlds'. - *

- * Patches related to this table: - * {@link Version10Patch} - * {@link WorldsServerIDPatch} - * {@link WorldsOptimizationPatch} - * - * @author Rsl1122 - */ -public class WorldTable { - - public static final String TABLE_NAME = "plan_worlds"; - - public static final String ID = "id"; - public static final String SERVER_UUID = "server_uuid"; - public static final String NAME = "world_name"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" - + NAME + ", " - + SERVER_UUID - + ") VALUES (?, ?)"; - - public static final String SELECT_WORLD_ID_STATEMENT = "(SELECT " + TABLE_NAME + "." + ID + " FROM " + TABLE_NAME + - " WHERE (" + NAME + "=?)" + - " AND (" + TABLE_NAME + "." + SERVER_UUID + "=?)" + - " LIMIT 1)"; - - private WorldTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(NAME, Sql.varchar(100)).notNull() - .column(SERVER_UUID, Sql.varchar(36)).notNull() - .toString(); - } -} - diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTimesTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTimesTable.java deleted file mode 100644 index 3422d4524..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTimesTable.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.sql.tables; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.time.GMTimes; -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.patches.Version10Patch; -import com.djrapitops.plan.db.patches.WorldTimesOptimizationPatch; -import com.djrapitops.plan.db.patches.WorldTimesSeverIDPatch; -import com.djrapitops.plan.db.patches.WorldsServerIDPatch; -import com.djrapitops.plan.db.sql.parsing.CreateTableParser; -import com.djrapitops.plan.db.sql.parsing.Sql; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Map; -import java.util.UUID; - -/** - * Information about database table 'plan_world_times'. - *

- * Patches related to this table: - * {@link Version10Patch} - * {@link WorldTimesSeverIDPatch} - * {@link WorldsServerIDPatch} - * {@link WorldTimesOptimizationPatch} - * - * @author Rsl1122 - */ -public class WorldTimesTable { - - public static final String TABLE_NAME = "plan_world_times"; - - public static final String ID = "id"; - public static final String USER_UUID = "uuid"; - public static final String SERVER_UUID = "server_uuid"; - public static final String SESSION_ID = "session_id"; - public static final String WORLD_ID = "world_id"; - public static final String SURVIVAL = "survival_time"; - public static final String CREATIVE = "creative_time"; - public static final String ADVENTURE = "adventure_time"; - public static final String SPECTATOR = "spectator_time"; - - public static final String INSERT_STATEMENT = "INSERT INTO " + WorldTimesTable.TABLE_NAME + " (" + - WorldTimesTable.SESSION_ID + ", " + - WorldTimesTable.WORLD_ID + ", " + - WorldTimesTable.USER_UUID + ", " + - WorldTimesTable.SERVER_UUID + ", " + - WorldTimesTable.SURVIVAL + ", " + - WorldTimesTable.CREATIVE + ", " + - WorldTimesTable.ADVENTURE + ", " + - WorldTimesTable.SPECTATOR + - ") VALUES ( " + - SessionsTable.SELECT_SESSION_ID_STATEMENT + ", " + - WorldTable.SELECT_WORLD_ID_STATEMENT + ", " + - "?, ?, ?, ?, ?, ?)"; - - private WorldTimesTable() { - /* Static information class */ - } - - public static String createTableSQL(DBType dbType) { - return CreateTableParser.create(TABLE_NAME, dbType) - .column(ID, Sql.INT).primaryKey() - .column(USER_UUID, Sql.varchar(36)).notNull() - .column(WORLD_ID, Sql.INT).notNull() - .column(SERVER_UUID, Sql.varchar(36)).notNull() - .column(SESSION_ID, Sql.INT).notNull() - .column(SURVIVAL, Sql.LONG).notNull().defaultValue("0") - .column(CREATIVE, Sql.LONG).notNull().defaultValue("0") - .column(ADVENTURE, Sql.LONG).notNull().defaultValue("0") - .column(SPECTATOR, Sql.LONG).notNull().defaultValue("0") - .foreignKey(WORLD_ID, WorldTable.TABLE_NAME, WorldTable.ID) - .foreignKey(SESSION_ID, SessionsTable.TABLE_NAME, SessionsTable.ID) - .toString(); - } - - public static void addSessionWorldTimesToBatch(PreparedStatement statement, Session session, String[] gms) throws SQLException { - UUID uuid = session.getUnsafe(SessionKeys.UUID); - UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID); - Map worldTimes = session.getUnsafe(SessionKeys.WORLD_TIMES).getWorldTimes(); - for (Map.Entry worldTimesEntry : worldTimes.entrySet()) { - String worldName = worldTimesEntry.getKey(); - GMTimes gmTimes = worldTimesEntry.getValue(); - - // Session ID select statement - statement.setString(1, uuid.toString()); - statement.setString(2, serverUUID.toString()); - statement.setLong(3, session.getUnsafe(SessionKeys.START)); - statement.setLong(4, session.getUnsafe(SessionKeys.END)); - - // World ID select statement - statement.setString(5, worldName); - statement.setString(6, serverUUID.toString()); - - statement.setString(7, uuid.toString()); - statement.setString(8, serverUUID.toString()); - statement.setLong(9, gmTimes.getTime(gms[0])); - statement.setLong(10, gmTimes.getTime(gms[1])); - statement.setLong(11, gmTimes.getTime(gms[2])); - statement.setLong(12, gmTimes.getTime(gms[3])); - statement.addBatch(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/tasks/DBCleanTask.java b/Plan/common/src/main/java/com/djrapitops/plan/db/tasks/DBCleanTask.java deleted file mode 100644 index b9cb96298..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/tasks/DBCleanTask.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.tasks; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.access.transactions.commands.RemovePlayerTransaction; -import com.djrapitops.plan.db.access.transactions.init.RemoveDuplicateUserInfoTransaction; -import com.djrapitops.plan.db.access.transactions.init.RemoveOldSampledDataTransaction; -import com.djrapitops.plan.db.sql.tables.SessionsTable; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveUnsatisfiedConditionalPlayerResultsTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveUnsatisfiedConditionalServerResultsTransaction; -import com.djrapitops.plan.query.QueryServiceImplementation; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.AbsRunnable; -import com.google.common.annotations.VisibleForTesting; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * Task for cleaning the active database. - * - * @author Rsl1122 - */ -@Singleton -public class DBCleanTask extends AbsRunnable { - - private final Locale locale; - private final DBSystem dbSystem; - private final PlanConfig config; - private final QueryServiceImplementation queryService; - private final ServerInfo serverInfo; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - @Inject - public DBCleanTask( - PlanConfig config, - Locale locale, - DBSystem dbSystem, - QueryServiceImplementation queryService, - ServerInfo serverInfo, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.locale = locale; - - this.dbSystem = dbSystem; - this.config = config; - this.queryService = queryService; - this.serverInfo = serverInfo; - this.logger = logger; - this.errorHandler = errorHandler; - } - - @Override - public void run() { - Database database = dbSystem.getDatabase(); - try { - if (database.getState() != Database.State.CLOSED) { - database.executeTransaction(new RemoveOldSampledDataTransaction( - serverInfo.getServerUUID(), - config.get(TimeSettings.DELETE_TPS_DATA_AFTER), - config.get(TimeSettings.DELETE_PING_DATA_AFTER) - )); - database.executeTransaction(new RemoveDuplicateUserInfoTransaction()); - database.executeTransaction(new RemoveUnsatisfiedConditionalPlayerResultsTransaction()); - database.executeTransaction(new RemoveUnsatisfiedConditionalServerResultsTransaction()); - int removed = cleanOldPlayers(database); - if (removed > 0) { - logger.info(locale.getString(PluginLang.DB_NOTIFY_CLEAN, removed)); - } - } - } catch (DBOpException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - cancel(); - } - } - - @VisibleForTesting - public int cleanOldPlayers(Database database) { - long now = System.currentTimeMillis(); - long keepActiveAfter = now - config.get(TimeSettings.DELETE_INACTIVE_PLAYERS_AFTER); - - List inactivePlayers = database.query(fetchInactivePlayerUUIDs(keepActiveAfter)); - for (UUID playerUUID : inactivePlayers) { - queryService.playerRemoved(playerUUID); - database.executeTransaction(new RemovePlayerTransaction(playerUUID)); - } - return inactivePlayers.size(); - } - - private Query> fetchInactivePlayerUUIDs(long keepActiveAfter) { - String sql = "SELECT uuid, last_seen FROM (SELECT" + - " MAX(" + SessionsTable.SESSION_END + ") as last_seen, " + SessionsTable.USER_UUID + - " FROM " + SessionsTable.TABLE_NAME + - " GROUP BY " + SessionsTable.USER_UUID + ") as q1" + - " WHERE last_seen < ?"; - return new QueryStatement>(sql, 20000) { - - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, keepActiveAfter); - } - - @Override - public List processResults(ResultSet set) throws SQLException { - List inactiveUUIDs = new ArrayList<>(); - while (set.next()) { - inactiveUUIDs.add(UUID.fromString(set.getString("uuid"))); - } - return inactiveUUIDs; - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/tasks/KeepAliveTask.java b/Plan/common/src/main/java/com/djrapitops/plan/db/tasks/KeepAliveTask.java deleted file mode 100644 index d7da6e779..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/tasks/KeepAliveTask.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.db.tasks; - -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.AbsRunnable; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * The task which handles the upkeep of the {@code Connection} - * - * @author Fuzzlemann - */ -public class KeepAliveTask extends AbsRunnable { - private Connection connection; - private final IReconnect iReconnect; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - public KeepAliveTask(Connection connection, IReconnect iReconnect, PluginLogger logger, ErrorHandler errorHandler) { - this.connection = connection; - this.iReconnect = iReconnect; - this.logger = logger; - this.errorHandler = errorHandler; - } - - @Override - public void run() { - Statement statement = null; - ResultSet resultSet = null; - try { - if (connection != null && !connection.isClosed()) { - statement = connection.createStatement(); - resultSet = statement.executeQuery("/* ping */ SELECT 1"); - } - } catch (SQLException e) { - logger.debug("Something went wrong during SQL Connection upkeep task."); - try { - connection = iReconnect.reconnect(); - } catch (SQLException e1) { - errorHandler.log(L.ERROR, this.getClass(), e1); - logger.error("SQL connection maintaining task had to be closed due to exception."); - this.cancel(); - } - } finally { - MiscUtils.close(statement, resultSet); - } - } - - public interface IReconnect { - Connection reconnect() throws SQLException; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionServerMethodCallerTask.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionServerMethodCallerTask.java deleted file mode 100644 index 3c48094cb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionServerMethodCallerTask.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -import com.djrapitops.plugin.task.AbsRunnable; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Task for updating {@link DataExtension} server values periodically. - * - * @author Rsl1122 - */ -@Singleton -public class ExtensionServerMethodCallerTask extends AbsRunnable { - - private final ExtensionServiceImplementation extensionServiceImplementation; - - @Inject - public ExtensionServerMethodCallerTask(ExtensionServiceImplementation extensionServiceImplementation) { - this.extensionServiceImplementation = extensionServiceImplementation; - } - - @Override - public void run() { - extensionServiceImplementation.updateServerValues(CallEvents.SERVER_PERIODICAL); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionServiceImplementation.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionServiceImplementation.java deleted file mode 100644 index 0b2ed0ec5..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/ExtensionServiceImplementation.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension; - -import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException; -import com.djrapitops.plan.data.plugin.PluginsConfigSection; -import com.djrapitops.plan.extension.implementation.CallerImplementation; -import com.djrapitops.plan.extension.implementation.DataProviderExtractor; -import com.djrapitops.plan.extension.implementation.ExtensionRegister; -import com.djrapitops.plan.extension.implementation.providers.gathering.ProviderValueGatherer; -import com.djrapitops.plan.system.DebugChannels; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -/** - * Implementation for {@link ExtensionService}. - * - * @author Rsl1122 - */ -@Singleton -public class ExtensionServiceImplementation implements ExtensionService { - - private final PlanConfig config; - private final DBSystem dbSystem; - private final ServerInfo serverInfo; - private final Processing processing; - private final ExtensionRegister extensionRegister; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - private final Map extensionGatherers; - - @Inject - public ExtensionServiceImplementation( - PlanConfig config, - DBSystem dbSystem, - ServerInfo serverInfo, - Processing processing, - ExtensionRegister extensionRegister, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.config = config; - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.processing = processing; - this.extensionRegister = extensionRegister; - this.logger = logger; - this.errorHandler = errorHandler; - - extensionGatherers = new HashMap<>(); - - ExtensionService.ExtensionServiceHolder.set(this); - } - - public void register() { - try { - extensionRegister.registerBuiltInExtensions(); - if (Check.isBukkitAvailable()) extensionRegister.registerBukkitExtensions(); - if (Check.isBungeeAvailable()) extensionRegister.registerBungeeExtensions(); - } catch (IllegalStateException failedToRegisterOne) { - logger.warn("One or more extensions failed to register:"); - errorHandler.log(L.WARN, this.getClass(), failedToRegisterOne); - } - } - - @Override - public Optional register(DataExtension extension) { - DataProviderExtractor extractor = new DataProviderExtractor(extension); - String pluginName = extractor.getPluginName(); - - if (shouldNotAllowRegistration(pluginName)) return Optional.empty(); - - for (String warning : extractor.getWarnings()) { - logger.warn("DataExtension API implementation mistake for " + pluginName + ": " + warning); - } - - ProviderValueGatherer gatherer = new ProviderValueGatherer(extension, extractor, dbSystem, serverInfo); - gatherer.storeExtensionInformation(); - extensionGatherers.put(pluginName, gatherer); - - processing.submitNonCritical(() -> updateServerValues(gatherer, CallEvents.SERVER_EXTENSION_REGISTER)); - - logger.info("Registered extension: " + pluginName); - return Optional.of(new CallerImplementation(gatherer, this, processing)); - } - - @Override - public void unregister(DataExtension extension) { - DataProviderExtractor extractor = new DataProviderExtractor(extension); - String pluginName = extractor.getPluginName(); - if (extensionGatherers.remove(pluginName) != null) { - logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, pluginName + " extension unregistered."); - } - } - - private boolean shouldNotAllowRegistration(String pluginName) { - PluginsConfigSection pluginsConfig = config.getPluginsConfigSection(); - - if (!pluginsConfig.hasSection(pluginName)) { - try { - pluginsConfig.createSection(pluginName); - } catch (IOException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - logger.warn("Could not register DataExtension for " + pluginName + " due to " + e.toString()); - return true; - } - } - - if (!pluginsConfig.isEnabled(pluginName)) { - logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, pluginName + " extension disabled in the config."); - return true; - } - return false; // Should register. - } - - public void updatePlayerValues(UUID playerUUID, String playerName, CallEvents event) { - for (ProviderValueGatherer gatherer : extensionGatherers.values()) { - updatePlayerValues(gatherer, playerUUID, playerName, event); - } - } - - public void updatePlayerValues(ProviderValueGatherer gatherer, UUID playerUUID, String playerName, CallEvents event) { - if (!gatherer.canCallEvent(event)) { - return; - } - try { - logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, "Gathering values for: " + playerName); - - gatherer.updateValues(playerUUID, playerName); - - logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, "Gathering completed: " + playerName); - } catch (DataExtensionMethodCallException methodCallFailed) { - logFailure(playerName, methodCallFailed); - gatherer.disableMethodFromUse(methodCallFailed.getMethod()); - // Try again - updatePlayerValues(gatherer, playerUUID, playerName, event); - } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError unexpectedError) { - logger.warn("Encountered unexpected error with " + gatherer.getPluginName() + " Extension (please report this): " + unexpectedError + - " (but failed safely) when updating value for '" + playerName + - "', stack trace to follow:"); - errorHandler.log(L.WARN, gatherer.getClass(), unexpectedError); - } - } - - private void logFailure(String playerName, DataExtensionMethodCallException methodCallFailed) { - Throwable cause = methodCallFailed.getCause(); - String causeName = cause.getClass().getSimpleName(); - logger.warn("Encountered " + causeName + " with " + methodCallFailed.getPluginName() + " Extension (please report this)" + - " (failed safely) when updating value for '" + playerName + - "', the method was disabled temporarily (won't be called until next Plan reload)" + - ", stack trace to follow:"); - errorHandler.log(L.WARN, getClass(), cause); - } - - public void updateServerValues(CallEvents event) { - for (ProviderValueGatherer gatherer : extensionGatherers.values()) { - updateServerValues(gatherer, event); - } - } - - public void updateServerValues(ProviderValueGatherer gatherer, CallEvents event) { - if (!gatherer.canCallEvent(event)) { - return; - } - try { - logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, "Gathering values for server"); - - gatherer.updateValues(); - - logger.getDebugLogger().logOn(DebugChannels.DATA_EXTENSIONS, "Gathering completed for server"); - } catch (DataExtensionMethodCallException methodCallFailed) { - logFailure("server", methodCallFailed); - gatherer.disableMethodFromUse(methodCallFailed.getMethod()); - // Try again - updateServerValues(gatherer, event); - } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError unexpectedError) { - logger.warn("Encountered unexpected error with " + gatherer.getPluginName() + " Extension (please report this): " + unexpectedError + - " (failed safely) when updating value for server, stack trace to follow:"); - errorHandler.log(L.WARN, gatherer.getClass(), unexpectedError); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/CallerImplementation.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/CallerImplementation.java deleted file mode 100644 index fa05d4516..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/CallerImplementation.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation; - -import com.djrapitops.plan.extension.CallEvents; -import com.djrapitops.plan.extension.Caller; -import com.djrapitops.plan.extension.ExtensionServiceImplementation; -import com.djrapitops.plan.extension.implementation.providers.gathering.ProviderValueGatherer; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.UUID; - -/** - * Implementation for {@link Caller} interface. - * - * @author Rsl1122 - */ -public class CallerImplementation implements Caller { - - private final ProviderValueGatherer gatherer; - private final ExtensionServiceImplementation extensionServiceImplementation; - private final Processing processing; - - public CallerImplementation( - ProviderValueGatherer gatherer, - ExtensionServiceImplementation extensionServiceImplementation, - Processing processing - ) { - this.gatherer = gatherer; - this.extensionServiceImplementation = extensionServiceImplementation; - this.processing = processing; - } - - @Override - public void updatePlayerData(UUID playerUUID, String playerName) { - Verify.nullCheck(playerUUID, () -> new IllegalArgumentException("'playerUUID' can not be null!")); - Verify.nullCheck(playerName, () -> new IllegalArgumentException("'playerName' can not be null!")); - processing.submitNonCritical(() -> extensionServiceImplementation.updatePlayerValues(gatherer, playerUUID, playerName, CallEvents.MANUAL)); - } - - @Override - public void updateServerData() { - processing.submitNonCritical(() -> extensionServiceImplementation.updateServerValues(gatherer, CallEvents.MANUAL)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/DataProviderExtractor.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/DataProviderExtractor.java deleted file mode 100644 index d3aa47fa2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/DataProviderExtractor.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation; - -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.annotation.*; -import com.djrapitops.plan.extension.extractor.ExtensionExtractor; -import com.djrapitops.plan.extension.extractor.MethodAnnotations; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.providers.*; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * Extracts objects that can be used to obtain data to store in the database. - *

- * Goal of this class is to abstract away DataExtension API annotations so that they will not be needed outside when calling methods. - * - * @author Rsl1122 - */ -public class DataProviderExtractor { - - private ExtensionExtractor extensionExtractor; - private DataProviders dataProviders; - - /** - * Create a DataProviderExtractor. - * - * @param extension DataExtension to extract information from. - * @throws IllegalArgumentException If something is badly wrong with the specified extension class annotations. - */ - public DataProviderExtractor(DataExtension extension) { - extensionExtractor = new ExtensionExtractor(extension); - - extensionExtractor.extractAnnotationInformation(); - - dataProviders = new DataProviders(); - extractAllDataProviders(); - } - - public String getPluginName() { - return extensionExtractor.getPluginInfo().name(); - } - - public Icon getPluginIcon() { - PluginInfo pluginInfo = extensionExtractor.getPluginInfo(); - return new Icon(pluginInfo.iconFamily(), pluginInfo.iconName(), pluginInfo.color()); - } - - public Collection getPluginTabs() { - Map tabInformation = extensionExtractor.getTabInformation() - .stream().collect(Collectors.toMap(TabInfo::tab, Function.identity(), (one, two) -> one)); - - Map order = getTabOrder().map(this::orderToMap).orElse(new HashMap<>()); - - // Extracts PluginTabs - return extensionExtractor.getMethodAnnotations().getAnnotations(Tab.class).stream() - .map(Tab::value) - .distinct() - .map(tabName -> { - Optional tabInfo = Optional.ofNullable(tabInformation.get(tabName)); - return new TabInformation( - tabName, - tabInfo.map(info -> new Icon(info.iconFamily(), info.iconName(), Color.NONE)).orElse(null), - tabInfo.map(TabInfo::elementOrder).orElse(null), - order.getOrDefault(tabName, 100) - ); - }).collect(Collectors.toList()); - } - - private Map orderToMap(String[] order) { - Map map = new HashMap<>(); - for (int i = 0; i < order.length; i++) { - map.put(order[i], i); - } - return map; - } - - public Optional getTabOrder() { - return extensionExtractor.getTabOrder().map(TabOrder::value); - } - - public Collection getInvalidatedMethods() { - return extensionExtractor.getInvalidateMethodAnnotations().stream() - .map(InvalidateMethod::value) - .collect(Collectors.toSet()); - } - - public DataProviders getDataProviders() { - return dataProviders; - } - - private void extractAllDataProviders() { - PluginInfo pluginInfo = extensionExtractor.getPluginInfo(); - - MethodAnnotations methodAnnotations = extensionExtractor.getMethodAnnotations(); - Map tabs = methodAnnotations.getMethodAnnotations(Tab.class); - Map conditions = methodAnnotations.getMethodAnnotations(Conditional.class); - - extractDataProviders(pluginInfo, tabs, conditions, BooleanProvider.class, BooleanDataProvider::placeToDataProviders); - extractDataProviders(pluginInfo, tabs, conditions, DoubleProvider.class, DoubleDataProvider::placeToDataProviders); - extractDataProviders(pluginInfo, tabs, conditions, PercentageProvider.class, PercentageDataProvider::placeToDataProviders); - extractDataProviders(pluginInfo, tabs, conditions, NumberProvider.class, NumberDataProvider::placeToDataProviders); - extractDataProviders(pluginInfo, tabs, conditions, StringProvider.class, StringDataProvider::placeToDataProviders); - extractDataProviders(pluginInfo, tabs, conditions, TableProvider.class, TableDataProvider::placeToDataProviders); - } - - private void extractDataProviders(PluginInfo pluginInfo, Map tabs, Map conditions, Class ofKind, DataProviderFactory factory) { - for (Map.Entry entry : extensionExtractor.getMethodAnnotations().getMethodAnnotations(ofKind).entrySet()) { - Method method = entry.getKey(); - T annotation = entry.getValue(); - Optional conditional = Optional.ofNullable(conditions.get(method)); - Optional tab = Optional.ofNullable(tabs.get(method)); - - factory.placeToDataProviders( - dataProviders, method, annotation, - conditional.orElse(null), - tab.map(Tab::value).orElse(null), - pluginInfo.name() - ); - } - } - - public Collection getWarnings() { - return extensionExtractor.getWarnings(); - } - - /** - * Functional interface for defining a method that places required DataProvider to DataProviders. - * - * @param Type of the annotation on the method that is going to be extracted. - */ - interface DataProviderFactory { - void placeToDataProviders( - DataProviders dataProviders, - Method method, T annotation, Conditional condition, String tab, String pluginName - ); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/MethodType.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/MethodType.java deleted file mode 100644 index 2faef55b6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/MethodType.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation; - -import com.djrapitops.plan.extension.Group; - -import java.lang.reflect.Method; -import java.util.UUID; - -/** - * Utility enum for determining what kind of parameters a provider method used. - *

- * This also allows figuring out where to save method results. - * - * @author Rsl1122 - */ -public enum MethodType { - - PLAYER_UUID, - PLAYER_NAME, - GROUP, - SERVER; - - public static MethodType forMethod(Method method) { - int parameterCount = method.getParameterCount(); - if (parameterCount == 0) { - return SERVER; - } - - Class[] parameterTypes = method.getParameterTypes(); - Class firstParameter = parameterTypes[0]; - - if (UUID.class.equals(firstParameter)) { - return PLAYER_UUID; - } else if (String.class.equals(firstParameter)) { - return PLAYER_NAME; - } else if (Group.class.equals(firstParameter)) { - return GROUP; - } - - throw new IllegalArgumentException(method.getDeclaringClass() + " method " + method.getName() + " had invalid parameters."); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/ProviderInformation.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/ProviderInformation.java deleted file mode 100644 index a06b625cd..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/ProviderInformation.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation; - -import com.djrapitops.plan.extension.annotation.Conditional; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.results.ExtensionDescriptive; -import org.apache.commons.lang3.StringUtils; - -import java.util.Objects; -import java.util.Optional; - -/** - * Represents the annotation information provided on a method. - * - * @author Rsl1122 - */ -public class ProviderInformation extends ExtensionDescriptive { - - private final String pluginName; - private final boolean showInPlayersTable; - private final String tab; // can be null - private final Conditional condition; // can be null - - public ProviderInformation( - String pluginName, String name, String text, String description, Icon icon, int priority, boolean showInPlayersTable, String tab, Conditional condition - ) { - super(name, text, description, icon, priority); - this.pluginName = pluginName; - this.showInPlayersTable = showInPlayersTable; - this.tab = tab; - this.condition = condition; - } - - public String getPluginName() { - return StringUtils.truncate(pluginName, 50); - } - - public boolean isShownInPlayersTable() { - return showInPlayersTable; - } - - public Optional getTab() { - return tab == null || tab.isEmpty() - ? Optional.empty() - : Optional.of(StringUtils.truncate(tab, 50)); - } - - public Optional getCondition() { - if (condition == null || condition.value().isEmpty()) { - return Optional.empty(); - } else if (condition.negated()) { - return Optional.of("not_" + getTruncatedConditionName()); - } else { - return Optional.of(getTruncatedConditionName()); - } - } - - private String getTruncatedConditionName() { - return StringUtils.truncate(condition.value(), 50); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ProviderInformation)) return false; - if (!super.equals(o)) return false; - ProviderInformation that = (ProviderInformation) o; - return pluginName.equals(that.pluginName) && - Objects.equals(tab, that.tab) && - Objects.equals(condition, that.condition); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), pluginName, tab, condition); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/TabInformation.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/TabInformation.java deleted file mode 100644 index 222ce3038..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/TabInformation.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation; - -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plugin.utilities.ArrayUtil; -import org.apache.commons.lang3.StringUtils; - -import java.util.Arrays; -import java.util.Optional; - -/** - * Represents a tab of {@link com.djrapitops.plan.extension.DataExtension} defined by {@link com.djrapitops.plan.extension.annotation.Tab} and - * {@link com.djrapitops.plan.extension.annotation.TabInfo} annotations. - * - * @author Rsl1122 - */ -public class TabInformation { - - private final String tabName; - private final Icon icon; // can be null - private ElementOrder[] elementOrder; // can be null / miss values - private int tabPriority; - - public TabInformation(String tabName, Icon icon, ElementOrder[] elementOrder, int tabPriority) { - this.tabName = tabName; - this.icon = icon; - this.elementOrder = elementOrder; - this.tabPriority = tabPriority; - } - - public String getTabName() { - return StringUtils.truncate(tabName, 50); - } - - public static Icon defaultIcon() { - return new Icon(Family.SOLID, "circle", Color.NONE); - } - - public Icon getTabIcon() { - return icon != null ? icon : defaultIcon(); - } - - public int getTabPriority() { - return tabPriority; - } - - public Optional getTabElementOrder() { - if (elementOrder == null) { - return Optional.empty(); - } - - ElementOrder[] possibleValues = ElementOrder.values(); - if (elementOrder.length < possibleValues.length) { - addMissingElements(possibleValues); - } - - return Optional.of(elementOrder); - } - - private void addMissingElements(ElementOrder[] possibleValues) { - for (ElementOrder possibleValue : possibleValues) { - if (Arrays.binarySearch(elementOrder, possibleValue) < 0) { - elementOrder = ArrayUtil.merge(elementOrder, new ElementOrder[]{possibleValue}); - } - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/BooleanDataProvider.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/BooleanDataProvider.java deleted file mode 100644 index 332c735b0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/BooleanDataProvider.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers; - -import com.djrapitops.plan.extension.annotation.BooleanProvider; -import com.djrapitops.plan.extension.annotation.Conditional; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import org.apache.commons.lang3.StringUtils; - -import java.lang.reflect.Method; -import java.util.Optional; - -/** - * Represents a DataExtension API method annotated with {@link BooleanProvider} annotation. - *

- * Used to obtain data to place in the database. - * - * @author Rsl1122 - */ -public class BooleanDataProvider extends DataProvider { - - private final String providedCondition; - private final boolean hidden; - - private BooleanDataProvider(ProviderInformation providerInformation, MethodWrapper method, String providedCondition, boolean hidden) { - super(providerInformation, method); - - this.providedCondition = providedCondition; - this.hidden = hidden; - } - - public static void placeToDataProviders( - DataProviders dataProviders, Method method, BooleanProvider annotation, - Conditional condition, String tab, String pluginName - ) { - MethodWrapper methodWrapper = new MethodWrapper<>(method, Boolean.class); - Icon providerIcon = new Icon(annotation.iconFamily(), annotation.iconName(), annotation.iconColor()); - - ProviderInformation providerInformation = new ProviderInformation( - pluginName, method.getName(), annotation.text(), annotation.description(), providerIcon, annotation.priority(), annotation.showInPlayerTable(), tab, condition - ); - - dataProviders.put(new BooleanDataProvider(providerInformation, methodWrapper, annotation.conditionName(), annotation.hidden())); - } - - public static Optional getProvidedCondition(DataProvider provider) { - if (provider instanceof BooleanDataProvider) { - return ((BooleanDataProvider) provider).getProvidedCondition(); - } - return Optional.empty(); - } - - public Optional getProvidedCondition() { - return providedCondition == null || providedCondition.isEmpty() ? Optional.empty() : Optional.of(StringUtils.truncate(providedCondition, 50)); - } - - public static boolean isHidden(DataProvider provider) { - return provider instanceof BooleanDataProvider && ((BooleanDataProvider) provider).isHidden(); - } - - public boolean isHidden() { - return hidden; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DataProvider.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DataProvider.java deleted file mode 100644 index 8e3bf1b62..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DataProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers; - -import com.djrapitops.plan.extension.implementation.ProviderInformation; - -/** - * Abstract representation of all values a Provider annotation provides. - * - * @author Rsl1122 - */ -public abstract class DataProvider { - - private final ProviderInformation providerInformation; - private final MethodWrapper method; - - public DataProvider(ProviderInformation providerInformation, MethodWrapper method) { - this.providerInformation = providerInformation; - this.method = method; - } - - public MethodWrapper getMethod() { - return method; - } - - public ProviderInformation getProviderInformation() { - return providerInformation; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DataProviders.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DataProviders.java deleted file mode 100644 index b2343bdb3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DataProviders.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers; - -import com.djrapitops.plan.extension.implementation.MethodType; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * Group class for handling multiple different types of {@link DataProvider}s. - * - * @author Rsl1122 - */ -public class DataProviders { - - private Map>> byMethodType; - - public DataProviders() { - byMethodType = new EnumMap<>(MethodType.class); - } - - public void put(DataProvider provider) { - MethodWrapper method = provider.getMethod(); - - MethodType methodType = method.getMethodType(); - Class resultType = method.getResultType(); - - Map> byParameterType = byMethodType.getOrDefault(methodType, new HashMap<>()); - List dataProviders = byParameterType.getOrDefault(resultType, new ArrayList<>()); - - dataProviders.add(provider); - - byParameterType.put(resultType, dataProviders); - byMethodType.put(methodType, byParameterType); - } - - public List> getPlayerMethodsByType(Class returnType) { - Map> providersAcceptingUUID = byMethodType.getOrDefault(MethodType.PLAYER_UUID, new HashMap<>()); - Map> providersAcceptingName = byMethodType.getOrDefault(MethodType.PLAYER_NAME, new HashMap<>()); - - List> byReturnType = new ArrayList<>(); - for (DataProvider dataProvider : providersAcceptingUUID.getOrDefault(returnType, Collections.emptyList())) { - byReturnType.add((DataProvider) dataProvider); - } - for (DataProvider dataProvider : providersAcceptingName.getOrDefault(returnType, Collections.emptyList())) { - byReturnType.add((DataProvider) dataProvider); - } - return byReturnType; - } - - public List> getServerMethodsByType(Class returnType) { - List> byReturnType = new ArrayList<>(); - for (DataProvider dataProvider : byMethodType.getOrDefault(MethodType.SERVER, new HashMap<>()).getOrDefault(returnType, Collections.emptyList())) { - byReturnType.add((DataProvider) dataProvider); - } - return byReturnType; - } - - public List> getGroupMethodsByType(Class returnType) { - List> byReturnType = new ArrayList<>(); - for (DataProvider dataProvider : byMethodType.getOrDefault(MethodType.GROUP, new HashMap<>()).getOrDefault(returnType, Collections.emptyList())) { - byReturnType.add((DataProvider) dataProvider); - } - return byReturnType; - } - - public void removeProviderWithMethod(MethodWrapper toRemove) { - MethodType methodType = toRemove.getMethodType(); - Map> byResultType = byMethodType.getOrDefault(methodType, Collections.emptyMap()); - if (byResultType.isEmpty()) { - return; - } - - Class resultType = toRemove.getResultType(); - List providers = byResultType.getOrDefault(resultType, Collections.emptyList()); - if (providers.isEmpty()) { - return; - } - - byResultType.put(resultType, providers.stream() - .filter(provider -> !provider.getMethod().equals(toRemove)) - .collect(Collectors.toList()) - ); - byMethodType.put(methodType, byResultType); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DoubleDataProvider.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DoubleDataProvider.java deleted file mode 100644 index ac467983e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/DoubleDataProvider.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers; - -import com.djrapitops.plan.extension.annotation.Conditional; -import com.djrapitops.plan.extension.annotation.DoubleProvider; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.ProviderInformation; - -import java.lang.reflect.Method; - -/** - * Represents a DataExtension API method annotated with {@link DoubleProvider} annotation. - *

- * Used to obtain data to place in the database. - * - * @author Rsl1122 - */ -public class DoubleDataProvider extends DataProvider { - - private DoubleDataProvider(ProviderInformation providerInformation, MethodWrapper methodWrapper) { - super(providerInformation, methodWrapper); - } - - public static void placeToDataProviders( - DataProviders dataProviders, Method method, DoubleProvider annotation, - Conditional condition, String tab, String pluginName - ) { - MethodWrapper methodWrapper = new MethodWrapper<>(method, Double.class); - Icon providerIcon = new Icon(annotation.iconFamily(), annotation.iconName(), annotation.iconColor()); - - ProviderInformation providerInformation = new ProviderInformation( - pluginName, method.getName(), annotation.text(), annotation.description(), providerIcon, annotation.priority(), annotation.showInPlayerTable(), tab, condition - ); - - dataProviders.put(new DoubleDataProvider(providerInformation, methodWrapper)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/MethodWrapper.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/MethodWrapper.java deleted file mode 100644 index 6c2547ce5..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/MethodWrapper.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers; - -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.Group; -import com.djrapitops.plan.extension.NotReadyException; -import com.djrapitops.plan.extension.implementation.MethodType; - -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Objects; -import java.util.UUID; - -/** - * Wrap a Method so that it is easier to call. - * - * @author Rsl1122 - */ -public class MethodWrapper implements Serializable { - - private final Method method; - private final Class resultType; - private MethodType methodType; - - public MethodWrapper(Method method, Class resultType) { - this.method = method; - this.resultType = resultType; - methodType = MethodType.forMethod(this.method); - } - - public T callMethod(DataExtension extension, UUID playerUUID, String playerName) { - if (methodType != MethodType.PLAYER_NAME && methodType != MethodType.PLAYER_UUID) { - throw new IllegalStateException(method.getDeclaringClass() + " method " + method.getName() + " is not GROUP method."); - } - return callMethod(extension, playerUUID, playerName, null); - } - - public T callMethod(DataExtension extension, Group group) { - if (methodType != MethodType.GROUP) { - throw new IllegalStateException(method.getDeclaringClass() + " method " + method.getName() + " is not GROUP method."); - } - return callMethod(extension, null, null, group); - } - - public T callMethod(DataExtension extension) { - if (methodType != MethodType.SERVER) { - throw new IllegalStateException(method.getDeclaringClass() + " method " + method.getName() + " is not SERVER method."); - } - return callMethod(extension, null, null, null); - } - - public T callMethod(DataExtension extension, UUID playerUUID, String playerName, Group group) { - try { - switch (methodType) { - case SERVER: - return resultType.cast(method.invoke(extension)); - case PLAYER_UUID: - return resultType.cast(method.invoke(extension, playerUUID)); - case PLAYER_NAME: - return resultType.cast(method.invoke(extension, playerName)); - case GROUP: - return resultType.cast(method.invoke(extension, group)); - default: - throw new IllegalArgumentException(method.getDeclaringClass() + " method " + method.getName() + " had invalid parameters."); - } - } catch (InvocationTargetException notReadyToBeCalled) { - if (notReadyToBeCalled.getCause() != null && notReadyToBeCalled.getCause() instanceof NotReadyException) { - return null; // Data or API not available to make the call. - } else { - throw new IllegalArgumentException(method.getDeclaringClass() + " method " + method.getName() + " could not be called: " + notReadyToBeCalled.getMessage(), notReadyToBeCalled); - } - } catch (IllegalAccessException e) { - throw new IllegalArgumentException(method.getDeclaringClass() + " method " + method.getName() + " could not be called: " + e.getMessage(), e); - } - } - - public String getMethodName() { - return method.getName(); - } - - public MethodType getMethodType() { - return methodType; - } - - public Class getResultType() { - return resultType; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof MethodWrapper)) return false; - MethodWrapper that = (MethodWrapper) o; - return method.equals(that.method) && - resultType.equals(that.resultType) && - methodType == that.methodType; - } - - @Override - public int hashCode() { - return Objects.hash(method, resultType, methodType); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/NumberDataProvider.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/NumberDataProvider.java deleted file mode 100644 index c1c41eac0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/NumberDataProvider.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers; - -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.extension.annotation.Conditional; -import com.djrapitops.plan.extension.annotation.NumberProvider; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.ProviderInformation; - -import java.lang.reflect.Method; - -/** - * Represents a DataExtension API method annotated with {@link NumberProvider} annotation. - *

- * Used to obtain data to place in the database. - * - * @author Rsl1122 - */ -public class NumberDataProvider extends DataProvider { - - private final FormatType formatType; - - private NumberDataProvider(ProviderInformation providerInformation, MethodWrapper methodWrapper, FormatType formatType) { - super(providerInformation, methodWrapper); - this.formatType = formatType; - } - - public static void placeToDataProviders( - DataProviders dataProviders, Method method, NumberProvider annotation, - Conditional condition, String tab, String pluginName - ) { - MethodWrapper methodWrapper = new MethodWrapper<>(method, Long.class); - Icon providerIcon = new Icon(annotation.iconFamily(), annotation.iconName(), annotation.iconColor()); - - ProviderInformation providerInformation = new ProviderInformation( - pluginName, method.getName(), annotation.text(), annotation.description(), providerIcon, annotation.priority(), annotation.showInPlayerTable(), tab, condition - ); - - dataProviders.put(new NumberDataProvider(providerInformation, methodWrapper, annotation.format())); - } - - public static FormatType getFormatType(DataProvider provider) { - if (provider instanceof NumberDataProvider) { - return ((NumberDataProvider) provider).getFormatType(); - } - return FormatType.NONE; - } - - public FormatType getFormatType() { - return formatType; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/PercentageDataProvider.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/PercentageDataProvider.java deleted file mode 100644 index 6c07db992..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/PercentageDataProvider.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers; - -import com.djrapitops.plan.extension.annotation.Conditional; -import com.djrapitops.plan.extension.annotation.PercentageProvider; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.ProviderInformation; - -import java.lang.reflect.Method; - -/** - * Represents a DataExtension API method annotated with {@link PercentageProvider} annotation. - *

- * Used to obtain data to place in the database. - * - * @author Rsl1122 - */ -public class PercentageDataProvider extends DataProvider { - - private PercentageDataProvider(ProviderInformation providerInformation, MethodWrapper methodWrapper) { - super(providerInformation, methodWrapper); - } - - public static void placeToDataProviders( - DataProviders dataProviders, Method method, PercentageProvider annotation, - Conditional condition, String tab, String pluginName - ) { - MethodWrapper methodWrapper = new MethodWrapper<>(method, Double.class); - Icon providerIcon = new Icon(annotation.iconFamily(), annotation.iconName(), annotation.iconColor()); - - ProviderInformation providerInformation = new ProviderInformation( - pluginName, method.getName(), annotation.text(), annotation.description(), providerIcon, annotation.priority(), annotation.showInPlayerTable(), tab, condition - ); - - dataProviders.put(new PercentageDataProvider(providerInformation, methodWrapper)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/StringDataProvider.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/StringDataProvider.java deleted file mode 100644 index f6293ab96..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/StringDataProvider.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers; - -import com.djrapitops.plan.extension.annotation.Conditional; -import com.djrapitops.plan.extension.annotation.StringProvider; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.ProviderInformation; - -import java.lang.reflect.Method; - -/** - * Represents a DataExtension API method annotated with {@link StringProvider} annotation. - *

- * Used to obtain data to place in the database. - * - * @author Rsl1122 - */ -public class StringDataProvider extends DataProvider { - - private final boolean playerName; - - private StringDataProvider(ProviderInformation providerInformation, MethodWrapper methodWrapper, boolean playerName) { - super(providerInformation, methodWrapper); - this.playerName = playerName; - } - - public static void placeToDataProviders( - DataProviders dataProviders, Method method, StringProvider annotation, - Conditional condition, String tab, String pluginName - ) { - MethodWrapper methodWrapper = new MethodWrapper<>(method, String.class); - Icon providerIcon = new Icon(annotation.iconFamily(), annotation.iconName(), annotation.iconColor()); - - ProviderInformation providerInformation = new ProviderInformation( - pluginName, method.getName(), annotation.text(), annotation.description(), providerIcon, annotation.priority(), annotation.showInPlayerTable(), tab, condition - ); - - boolean playerName = annotation.playerName(); - - dataProviders.put(new StringDataProvider(providerInformation, methodWrapper, playerName)); - } - - public static boolean isPlayerName(DataProvider provider) { - if (provider instanceof StringDataProvider) { - return ((StringDataProvider) provider).isPlayerName(); - } - return false; - } - - public boolean isPlayerName() { - return playerName; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/TableDataProvider.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/TableDataProvider.java deleted file mode 100644 index 16600ca9e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/TableDataProvider.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers; - -import com.djrapitops.plan.extension.annotation.Conditional; -import com.djrapitops.plan.extension.annotation.TableProvider; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.table.Table; - -import java.lang.reflect.Method; - -/** - * Represents a DataExtension API method annotated with {@link com.djrapitops.plan.extension.annotation.TableProvider} annotation. - *

- * Used to obtain data to place in the database. - *

- * Please note that not all {@link ProviderInformation} is present. - * - * @author Rsl1122 - */ -public class TableDataProvider extends DataProvider { - - private final Color tableColor; - - private TableDataProvider(ProviderInformation providerInformation, MethodWrapper
methodWrapper, Color tableColor) { - super(providerInformation, methodWrapper); - - this.tableColor = tableColor; - } - - public static void placeToDataProviders( - DataProviders dataProviders, Method method, TableProvider annotation, - Conditional condition, String tab, String pluginName - ) { - MethodWrapper
methodWrapper = new MethodWrapper<>(method, Table.class); - - ProviderInformation providerInformation = new ProviderInformation( - pluginName, method.getName(), null, null, null, 0, false, tab, condition - ); - - dataProviders.put(new TableDataProvider(providerInformation, methodWrapper, annotation.tableColor())); - } - - public static Color getTableColor(DataProvider
provider) { - if (provider instanceof TableDataProvider) { - return ((TableDataProvider) provider).getTableColor(); - } - return Color.NONE; - } - - public Color getTableColor() { - return tableColor; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/BooleanProviderValueGatherer.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/BooleanProviderValueGatherer.java deleted file mode 100644 index be1112abf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/BooleanProviderValueGatherer.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers.gathering; - -import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.implementation.providers.BooleanDataProvider; -import com.djrapitops.plan.extension.implementation.providers.DataProvider; -import com.djrapitops.plan.extension.implementation.providers.DataProviders; -import com.djrapitops.plan.extension.implementation.providers.MethodWrapper; -import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIconTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.providers.StoreBooleanProviderTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerBooleanResultTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerBooleanResultTransaction; - -import java.util.*; -import java.util.concurrent.Callable; -import java.util.function.BiFunction; -import java.util.function.Function; - -/** - * Gathers BooleanProvider method data. - * - * @author Rsl1122 - */ -class BooleanProviderValueGatherer { - - private final String pluginName; - private final DataExtension extension; - private final UUID serverUUID; - - private final Database database; - private final DataProviders dataProviders; - - BooleanProviderValueGatherer( - String pluginName, DataExtension extension, - UUID serverUUID, Database database, - DataProviders dataProviders - ) { - this.pluginName = pluginName; - this.extension = extension; - this.serverUUID = serverUUID; - this.database = database; - this.dataProviders = dataProviders; - } - - Conditions gatherBooleanDataOfPlayer(UUID playerUUID, String playerName) { - Conditions conditions = new Conditions(); - - List> unsatisifiedProviders = new ArrayList<>(dataProviders.getPlayerMethodsByType(Boolean.class)); - Set> satisfied; - - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable> methodCaller = method -> () -> method.callMethod(extension, playerUUID, playerName); - BiFunction, Boolean, Transaction> storeTrancationCreator = (method, result) -> new StorePlayerBooleanResultTransaction(pluginName, serverUUID, method.getMethodName(), playerUUID, result); - - do { - // Loop through all unsatisfied providers to see if more conditions are satisfied - satisfied = attemptToSatisfyMoreConditionsAndStoreResults(methodCaller, storeTrancationCreator, conditions, unsatisifiedProviders); - // Remove now satisfied Providers so that they are not called again - unsatisifiedProviders.removeAll(satisfied); - // If no new conditions could be satisfied, stop looping. - } while (!satisfied.isEmpty()); - - return conditions; - } - - Conditions gatherBooleanDataOfServer() { - Conditions conditions = new Conditions(); - - List> unsatisifiedProviders = new ArrayList<>(dataProviders.getServerMethodsByType(Boolean.class)); - Set> satisfied; - - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable> methodCaller = method -> () -> method.callMethod(extension); - BiFunction, Boolean, Transaction> storeTransactionCreator = (method, result) -> new StoreServerBooleanResultTransaction(pluginName, serverUUID, method.getMethodName(), result); - - do { - // Loop through all unsatisfied providers to see if more conditions are satisfied - satisfied = attemptToSatisfyMoreConditionsAndStoreResults(methodCaller, storeTransactionCreator, conditions, unsatisifiedProviders); - // Remove now satisfied Providers so that they are not called again - unsatisifiedProviders.removeAll(satisfied); - // If no new conditions could be satisfied, stop looping. - } while (!satisfied.isEmpty()); - - return conditions; - } - - private Set> attemptToSatisfyMoreConditionsAndStoreResults( - Function, Callable> methodCaller, - BiFunction, Boolean, Transaction> storeTransactionCreator, - Conditions conditions, List> unsatisifiedProviders - ) { - Set> satisfied = new HashSet<>(); - for (DataProvider booleanProvider : unsatisifiedProviders) { - ProviderInformation providerInformation = booleanProvider.getProviderInformation(); - - Optional condition = providerInformation.getCondition(); - if (condition.isPresent() && conditions.isNotFulfilled(condition.get())) { - // Condition required by the BooleanProvider is not satisfied - continue; - } - - Optional providedCondition = BooleanDataProvider.getProvidedCondition(booleanProvider); - boolean hidden = BooleanDataProvider.isHidden(booleanProvider); - - MethodWrapper method = booleanProvider.getMethod(); - Boolean result = getMethodResult(methodCaller.apply(method), method); - if (result == null) { - // Error during method call - satisfied.add(booleanProvider); // Prevents further attempts to call this provider for this player. - continue; - } - - if (providedCondition.isPresent()) { - if (result) { - // The condition was fulfilled (true) for this player. - conditions.conditionFulfilled(providedCondition.get()); - } else { - // The negated condition was fulfilled (false) for this player. - conditions.conditionFulfilled("not_" + providedCondition.get()); - } - } - - satisfied.add(booleanProvider); // Prevents further attempts to call this provider for this player. - database.executeTransaction(new StoreIconTransaction(providerInformation.getIcon())); - database.executeTransaction(new StoreBooleanProviderTransaction(booleanProvider, providedCondition.orElse(null), hidden, serverUUID)); - database.executeTransaction(storeTransactionCreator.apply(method, result)); - } - return satisfied; - } - - private T getMethodResult(Callable callable, MethodWrapper method) { - try { - return callable.call(); - } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) { - throw new DataExtensionMethodCallException(e, pluginName, method); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/Conditions.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/Conditions.java deleted file mode 100644 index 2f8e6ccdf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/Conditions.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers.gathering; - -import java.util.HashSet; -import java.util.Set; - -/** - * Utility object for managing conditions. - * - * @author Rsl1122 - */ -public class Conditions { - - private final Set fulfilledConditions; - - public Conditions() { - this.fulfilledConditions = new HashSet<>(); - } - - public boolean isNotFulfilled(String condition) { - return !fulfilledConditions.contains(condition); - } - - public void conditionFulfilled(String condition) { - fulfilledConditions.add(condition); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/DoubleAndPercentageProviderValueGatherer.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/DoubleAndPercentageProviderValueGatherer.java deleted file mode 100644 index b1d9a73d8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/DoubleAndPercentageProviderValueGatherer.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers.gathering; - -import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.implementation.providers.DataProvider; -import com.djrapitops.plan.extension.implementation.providers.DataProviders; -import com.djrapitops.plan.extension.implementation.providers.MethodWrapper; -import com.djrapitops.plan.extension.implementation.providers.PercentageDataProvider; -import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIconTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.providers.StoreDoubleProviderTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerDoubleResultTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerPercentageResultTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerDoubleResultTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerPercentageResultTransaction; - -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.function.BiFunction; -import java.util.function.Function; - -/** - * Gathers DoubleProvider and PercentageProvider method data. - * - * @author Rsl1122 - */ -class DoubleAndPercentageProviderValueGatherer { - - private final String pluginName; - private final DataExtension extension; - private final UUID serverUUID; - - private final Database database; - private final DataProviders dataProviders; - - DoubleAndPercentageProviderValueGatherer( - String pluginName, DataExtension extension, - UUID serverUUID, Database database, - DataProviders dataProviders - ) { - this.pluginName = pluginName; - this.extension = extension; - this.serverUUID = serverUUID; - this.database = database; - this.dataProviders = dataProviders; - } - - void gatherDoubleDataOfPlayer(UUID playerUUID, String playerName, Conditions conditions) { - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable> methodCaller = method -> () -> method.callMethod(extension, playerUUID, playerName); - BiFunction, Double, Transaction> percStoreTransactionCreator = (method, result) -> new StorePlayerPercentageResultTransaction(pluginName, serverUUID, method.getMethodName(), playerUUID, result); - BiFunction, Double, Transaction> doubleStoreTransactionCreator = (method, result) -> new StorePlayerDoubleResultTransaction(pluginName, serverUUID, method.getMethodName(), playerUUID, result); - - for (DataProvider doubleProvider : dataProviders.getPlayerMethodsByType(Double.class)) { - gatherDoubleDataOfProvider(methodCaller, percStoreTransactionCreator, doubleStoreTransactionCreator, conditions, doubleProvider); - } - } - - void gatherDoubleDataOfServer(Conditions conditions) { - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable> methodCaller = method -> () -> method.callMethod(extension); - BiFunction, Double, Transaction> percStoreTransactionCreator = (method, result) -> new StoreServerPercentageResultTransaction(pluginName, serverUUID, method.getMethodName(), result); - BiFunction, Double, Transaction> doubleStoreTransactionCreator = (method, result) -> new StoreServerDoubleResultTransaction(pluginName, serverUUID, method.getMethodName(), result); - - for (DataProvider doubleProvider : dataProviders.getServerMethodsByType(Double.class)) { - gatherDoubleDataOfProvider(methodCaller, percStoreTransactionCreator, doubleStoreTransactionCreator, conditions, doubleProvider); - } - } - - private void gatherDoubleDataOfProvider( - Function, Callable> methodCaller, - BiFunction, Double, Transaction> percStoreTransactionCreator, - BiFunction, Double, Transaction> doubleStoreTransactionCreator, - Conditions conditions, DataProvider doubleProvider - - ) { - ProviderInformation providerInformation = doubleProvider.getProviderInformation(); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent() && conditions.isNotFulfilled(condition.get())) { - return; - } - - MethodWrapper method = doubleProvider.getMethod(); - Double result = getMethodResult(methodCaller.apply(method), method); - if (result == null) { - return; // Error during call - } - - database.executeTransaction(new StoreIconTransaction(providerInformation.getIcon())); - database.executeTransaction(new StoreDoubleProviderTransaction(doubleProvider, serverUUID)); - - if (doubleProvider instanceof PercentageDataProvider) { - database.executeTransaction(percStoreTransactionCreator.apply(method, result)); - } else { - database.executeTransaction(doubleStoreTransactionCreator.apply(method, result)); - } - } - - private T getMethodResult(Callable callable, MethodWrapper method) { - try { - return callable.call(); - } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) { - throw new DataExtensionMethodCallException(e, pluginName, method); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/NumberProviderValueGatherer.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/NumberProviderValueGatherer.java deleted file mode 100644 index c768146cb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/NumberProviderValueGatherer.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers.gathering; - -import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.implementation.providers.DataProvider; -import com.djrapitops.plan.extension.implementation.providers.DataProviders; -import com.djrapitops.plan.extension.implementation.providers.MethodWrapper; -import com.djrapitops.plan.extension.implementation.providers.NumberDataProvider; -import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIconTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.providers.StoreNumberProviderTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerNumberResultTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerNumberResultTransaction; - -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.function.BiFunction; -import java.util.function.Function; - -/** - * Gathers NumberProvider method data. - * - * @author Rsl1122 - */ -class NumberProviderValueGatherer { - - private final String pluginName; - private final DataExtension extension; - private final UUID serverUUID; - - private final Database database; - private final DataProviders dataProviders; - - NumberProviderValueGatherer( - String pluginName, DataExtension extension, - UUID serverUUID, Database database, - DataProviders dataProviders - ) { - this.pluginName = pluginName; - this.extension = extension; - this.serverUUID = serverUUID; - this.database = database; - this.dataProviders = dataProviders; - } - - void gatherNumberDataOfPlayer(UUID playerUUID, String playerName, Conditions conditions) { - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable> methodCaller = method -> () -> method.callMethod(extension, playerUUID, playerName); - BiFunction, Long, Transaction> storeTransactionCreator = (method, result) -> new StorePlayerNumberResultTransaction(pluginName, serverUUID, method.getMethodName(), playerUUID, result); - - for (DataProvider numberProvider : dataProviders.getPlayerMethodsByType(Long.class)) { - gatherNumberDataOfProvider(methodCaller, storeTransactionCreator, conditions, numberProvider); - } - } - - void gatherNumberDataOfServer(Conditions conditions) { - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable> methodCaller = method -> () -> method.callMethod(extension); - BiFunction, Long, Transaction> storeTransactionCreator = (method, result) -> new StoreServerNumberResultTransaction(pluginName, serverUUID, method.getMethodName(), result); - - for (DataProvider numberProvider : dataProviders.getServerMethodsByType(Long.class)) { - gatherNumberDataOfProvider(methodCaller, storeTransactionCreator, conditions, numberProvider); - } - } - - private void gatherNumberDataOfProvider( - Function, Callable> methodCaller, - BiFunction, Long, Transaction> storeTransactionCreator, - Conditions conditions, DataProvider numberProvider - ) { - ProviderInformation providerInformation = numberProvider.getProviderInformation(); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent() && conditions.isNotFulfilled(condition.get())) { - return; - } - - MethodWrapper method = numberProvider.getMethod(); - Long result = getMethodResult(methodCaller.apply(method), method); - if (result == null) { - return; // Error during call - } - - FormatType formatType = NumberDataProvider.getFormatType(numberProvider); - - database.executeTransaction(new StoreIconTransaction(providerInformation.getIcon())); - database.executeTransaction(new StoreNumberProviderTransaction(numberProvider, formatType, serverUUID)); - database.executeTransaction(storeTransactionCreator.apply(method, result)); - } - - private T getMethodResult(Callable callable, MethodWrapper method) { - try { - return callable.call(); - } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) { - throw new DataExtensionMethodCallException(e, pluginName, method); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/ProviderValueGatherer.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/ProviderValueGatherer.java deleted file mode 100644 index 45ecfc273..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/ProviderValueGatherer.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers.gathering; - -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.extension.CallEvents; -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.DataProviderExtractor; -import com.djrapitops.plan.extension.implementation.TabInformation; -import com.djrapitops.plan.extension.implementation.providers.DataProviders; -import com.djrapitops.plan.extension.implementation.providers.MethodWrapper; -import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIconTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.StorePluginTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.StoreTabInformationTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.RemoveInvalidResultsTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; - -import java.util.UUID; - -/** - * Object that can be called to place data about players to the database. - * - * @author Rsl1122 - */ -public class ProviderValueGatherer { - - private final CallEvents[] callEvents; - private final DataProviderExtractor extractor; - private final DBSystem dbSystem; - private final ServerInfo serverInfo; - - private DataProviders dataProviders; - private BooleanProviderValueGatherer booleanGatherer; - private NumberProviderValueGatherer numberGatherer; - private DoubleAndPercentageProviderValueGatherer doubleAndPercentageGatherer; - private StringProviderValueGatherer stringGatherer; - private TableProviderValueGatherer tableGatherer; - - - public ProviderValueGatherer( - DataExtension extension, - DataProviderExtractor extractor, - DBSystem dbSystem, - ServerInfo serverInfo - ) { - this.callEvents = extension.callExtensionMethodsOn(); - this.extractor = extractor; - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - - String pluginName = extractor.getPluginName(); - UUID serverUUID = serverInfo.getServerUUID(); - Database database = dbSystem.getDatabase(); - dataProviders = extractor.getDataProviders(); - booleanGatherer = new BooleanProviderValueGatherer( - pluginName, extension, serverUUID, database, dataProviders - ); - numberGatherer = new NumberProviderValueGatherer( - pluginName, extension, serverUUID, database, dataProviders - ); - doubleAndPercentageGatherer = new DoubleAndPercentageProviderValueGatherer( - pluginName, extension, serverUUID, database, dataProviders - ); - stringGatherer = new StringProviderValueGatherer( - pluginName, extension, serverUUID, database, dataProviders - ); - tableGatherer = new TableProviderValueGatherer( - pluginName, extension, serverUUID, database, dataProviders - ); - } - - public void disableMethodFromUse(MethodWrapper method) { - dataProviders.removeProviderWithMethod(method); - } - - public boolean canCallEvent(CallEvents event) { - if (event == CallEvents.MANUAL) { - return true; - } - for (CallEvents accepted : callEvents) { - if (event == accepted) { - return true; - } - } - return false; - } - - public String getPluginName() { - return extractor.getPluginName(); - } - - public void storeExtensionInformation() { - String pluginName = extractor.getPluginName(); - Icon pluginIcon = extractor.getPluginIcon(); - - long time = System.currentTimeMillis(); - UUID serverUUID = serverInfo.getServerUUID(); - - Database database = dbSystem.getDatabase(); - database.executeTransaction(new StoreIconTransaction(pluginIcon)); - database.executeTransaction(new StorePluginTransaction(pluginName, time, serverUUID, pluginIcon)); - for (TabInformation tab : extractor.getPluginTabs()) { - database.executeTransaction(new StoreIconTransaction(tab.getTabIcon())); - database.executeTransaction(new StoreTabInformationTransaction(pluginName, serverUUID, tab)); - } - - database.executeTransaction(new RemoveInvalidResultsTransaction(pluginName, serverUUID, extractor.getInvalidatedMethods())); - } - - public void updateValues(UUID playerUUID, String playerName) { - Conditions conditions = booleanGatherer.gatherBooleanDataOfPlayer(playerUUID, playerName); - numberGatherer.gatherNumberDataOfPlayer(playerUUID, playerName, conditions); - doubleAndPercentageGatherer.gatherDoubleDataOfPlayer(playerUUID, playerName, conditions); - stringGatherer.gatherStringDataOfPlayer(playerUUID, playerName, conditions); - tableGatherer.gatherTableDataOfPlayer(playerUUID, playerName, conditions); - } - - public void updateValues() { - Conditions conditions = booleanGatherer.gatherBooleanDataOfServer(); - numberGatherer.gatherNumberDataOfServer(conditions); - doubleAndPercentageGatherer.gatherDoubleDataOfServer(conditions); - stringGatherer.gatherStringDataOfServer(conditions); - tableGatherer.gatherTableDataOfServer(conditions); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/StringProviderValueGatherer.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/StringProviderValueGatherer.java deleted file mode 100644 index 74ddc6405..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/StringProviderValueGatherer.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers.gathering; - -import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.implementation.providers.DataProvider; -import com.djrapitops.plan.extension.implementation.providers.DataProviders; -import com.djrapitops.plan.extension.implementation.providers.MethodWrapper; -import com.djrapitops.plan.extension.implementation.providers.StringDataProvider; -import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIconTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.providers.StoreStringProviderTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerStringResultTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerStringResultTransaction; -import org.apache.commons.lang3.StringUtils; - -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.function.BiFunction; -import java.util.function.Function; - -/** - * Gathers StringProvider method data. - * - * @author Rsl1122 - */ -class StringProviderValueGatherer { - - private final String pluginName; - private final DataExtension extension; - private final UUID serverUUID; - - private final Database database; - private final DataProviders dataProviders; - - StringProviderValueGatherer( - String pluginName, DataExtension extension, - UUID serverUUID, Database database, - DataProviders dataProviders - ) { - this.pluginName = pluginName; - this.extension = extension; - this.serverUUID = serverUUID; - this.database = database; - this.dataProviders = dataProviders; - } - - void gatherStringDataOfPlayer(UUID playerUUID, String playerName, Conditions conditions) { - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable> methodCaller = method -> () -> method.callMethod(extension, playerUUID, playerName); - BiFunction, String, Transaction> storeTransactionCreator = (method, result) -> new StorePlayerStringResultTransaction(pluginName, serverUUID, method.getMethodName(), playerUUID, result); - - for (DataProvider stringProvider : dataProviders.getPlayerMethodsByType(String.class)) { - gatherStringDataOfProvider(methodCaller, storeTransactionCreator, conditions, stringProvider); - } - } - - void gatherStringDataOfServer(Conditions conditions) { - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable> methodCaller = method -> () -> method.callMethod(extension); - BiFunction, String, Transaction> storeTransactionCreator = (method, result) -> new StoreServerStringResultTransaction(pluginName, serverUUID, method.getMethodName(), result); - - for (DataProvider stringProvider : dataProviders.getServerMethodsByType(String.class)) { - gatherStringDataOfProvider(methodCaller, storeTransactionCreator, conditions, stringProvider); - } - } - - private void gatherStringDataOfProvider( - Function, Callable> methodCaller, - BiFunction, String, Transaction> storeTransactionCreator, - Conditions conditions, - DataProvider stringProvider - ) { - ProviderInformation providerInformation = stringProvider.getProviderInformation(); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent() && conditions.isNotFulfilled(condition.get())) { - return; - } - - MethodWrapper method = stringProvider.getMethod(); - String result = getMethodResult(methodCaller.apply(method), method); - if (result == null) { - return; // Error during call - } - - result = StringUtils.truncate(result, 50); - - database.executeTransaction(new StoreIconTransaction(providerInformation.getIcon())); - database.executeTransaction(new StoreStringProviderTransaction(stringProvider, StringDataProvider.isPlayerName(stringProvider), serverUUID)); - database.executeTransaction(storeTransactionCreator.apply(method, result)); - } - - private T getMethodResult(Callable callable, MethodWrapper method) { - try { - return callable.call(); - } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) { - throw new DataExtensionMethodCallException(e, pluginName, method); - } - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/TableProviderValueGatherer.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/TableProviderValueGatherer.java deleted file mode 100644 index f5c4349af..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/providers/gathering/TableProviderValueGatherer.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.providers.gathering; - -import com.djrapitops.plan.api.exceptions.DataExtensionMethodCallException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.implementation.providers.DataProvider; -import com.djrapitops.plan.extension.implementation.providers.DataProviders; -import com.djrapitops.plan.extension.implementation.providers.MethodWrapper; -import com.djrapitops.plan.extension.implementation.providers.TableDataProvider; -import com.djrapitops.plan.extension.implementation.storage.transactions.StoreIconTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.providers.StoreTableProviderTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StorePlayerTableResultTransaction; -import com.djrapitops.plan.extension.implementation.storage.transactions.results.StoreServerTableResultTransaction; -import com.djrapitops.plan.extension.table.Table; - -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.function.BiFunction; -import java.util.function.Function; - -/** - * Gathers TableProvider method data. - * - * @author Rsl1122 - */ -class TableProviderValueGatherer { - - private final String pluginName; - private final DataExtension extension; - private final UUID serverUUID; - - private final Database database; - private final DataProviders dataProviders; - - TableProviderValueGatherer( - String pluginName, DataExtension extension, - UUID serverUUID, Database database, - DataProviders dataProviders - ) { - this.pluginName = pluginName; - this.extension = extension; - this.serverUUID = serverUUID; - this.database = database; - this.dataProviders = dataProviders; - } - - void gatherTableDataOfPlayer(UUID playerUUID, String playerName, Conditions conditions) { - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable
> methodCaller = method -> () -> method.callMethod(extension, playerUUID, playerName); - BiFunction, Table, Transaction> storeTransactionCreator = (method, result) -> new StorePlayerTableResultTransaction(pluginName, serverUUID, method.getMethodName(), playerUUID, result); - - for (DataProvider
tableProvider : dataProviders.getPlayerMethodsByType(Table.class)) { - gatherTableDataOfProvider(methodCaller, storeTransactionCreator, conditions, tableProvider); - } - } - - void gatherTableDataOfServer(Conditions conditions) { - // Method parameters abstracted away so that same method can be used for all parameter types - // Same with Method result store transaction creation - Function, Callable
> methodCaller = method -> () -> method.callMethod(extension); - BiFunction, Table, Transaction> storeTransactionCreator = (method, result) -> new StoreServerTableResultTransaction(pluginName, serverUUID, method.getMethodName(), result); - - for (DataProvider
tableProvider : dataProviders.getServerMethodsByType(Table.class)) { - gatherTableDataOfProvider(methodCaller, storeTransactionCreator, conditions, tableProvider); - } - } - - private void gatherTableDataOfProvider( - Function, Callable
> methodCaller, - BiFunction, Table, Transaction> storeTransactionCreator, - Conditions conditions, - DataProvider
tableProvider - ) { - ProviderInformation providerInformation = tableProvider.getProviderInformation(); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent() && conditions.isNotFulfilled(condition.get())) { - return; - } - - MethodWrapper
method = tableProvider.getMethod(); - Table result = getMethodResult(methodCaller.apply(method), method); - if (result == null) { - return; // Error during call - } - - for (Icon icon : result.getIcons()) { - if (icon != null) { - database.executeTransaction(new StoreIconTransaction(icon)); - } - } - database.executeTransaction(new StoreTableProviderTransaction(serverUUID, providerInformation, TableDataProvider.getTableColor(tableProvider), result)); - database.executeTransaction(storeTransactionCreator.apply(method, result)); - } - - private T getMethodResult(Callable callable, MethodWrapper method) { - try { - return callable.call(); - } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) { - throw new DataExtensionMethodCallException(e, pluginName, method); - } - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionBooleanData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionBooleanData.java deleted file mode 100644 index ba0820410..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionBooleanData.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results; - -/** - * Represents boolean data returned by a BooleanProvider method. - * - * @author Rsl1122 - */ -public class ExtensionBooleanData implements ExtensionData { - - private ExtensionDescriptive descriptive; - private boolean value; - - public ExtensionBooleanData(ExtensionDescriptive descriptive, boolean value) { - this.descriptive = descriptive; - this.value = value; - } - - public ExtensionDescriptive getDescriptive() { - return descriptive; - } - - public String getFormattedValue() { - return value ? "Yes" : "No"; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionData.java deleted file mode 100644 index 4b7634d1b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionData.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results; - -/** - * Represents a data-point given by a Provider method of a DataExtension. - * - * @author Rsl1122 - */ -public interface ExtensionData { - - /** - * Get Descriptive information about the data point. - * - * @return a {@link ExtensionDescriptive}. - */ - ExtensionDescriptive getDescriptive(); - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionDescriptive.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionDescriptive.java deleted file mode 100644 index c04a73fdf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionDescriptive.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results; - -import com.djrapitops.plan.extension.icon.Icon; -import org.apache.commons.lang3.StringUtils; - -import java.util.Objects; -import java.util.Optional; - -/** - * Describes information about an extension value given by a Provider method. - * - * @author Rsl1122 - */ -public class ExtensionDescriptive implements Comparable { - - private final String name; - private final String text; - private final String description; // can be null - private final Icon icon; - private final int priority; - - public ExtensionDescriptive(String name, String text, String description, Icon icon, int priority) { - this.name = name; - this.text = text; - this.description = description; - this.icon = icon; - this.priority = priority; - } - - public String getName() { - return StringUtils.truncate(name, 50); - } - - public String getText() { - return StringUtils.truncate(text, 50); - } - - public Optional getDescription() { - return description == null || description.isEmpty() ? Optional.empty() : Optional.of(StringUtils.truncate(description, 150)); - } - - public Icon getIcon() { - return icon; - } - - public int getPriority() { - return priority; - } - - @Override - public int compareTo(ExtensionDescriptive other) { - return Integer.compare(other.priority, this.priority); // Higher is first - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ExtensionDescriptive)) return false; - ExtensionDescriptive that = (ExtensionDescriptive) o; - return priority == that.priority && - name.equals(that.name) && - text.equals(that.text) && - Objects.equals(description, that.description) && - icon.equals(that.icon); - } - - @Override - public int hashCode() { - return Objects.hash(name, text, description, icon, priority); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionDoubleData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionDoubleData.java deleted file mode 100644 index 81e266b9b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionDoubleData.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results; - -import com.djrapitops.plan.utilities.formatting.Formatter; - -/** - * Represents double data returned by a DoubleProvider or PercentageProvider method. - * - * @author Rsl1122 - */ -public class ExtensionDoubleData implements ExtensionData { - - private ExtensionDescriptive descriptive; - private double value; - - public ExtensionDoubleData(ExtensionDescriptive descriptive, double value) { - this.descriptive = descriptive; - this.value = value; - } - - public ExtensionDescriptive getDescriptive() { - return descriptive; - } - - public String getFormattedValue(Formatter formatter) { - return formatter.apply(value); - } - - public double getRawValue() { - return value; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionInformation.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionInformation.java deleted file mode 100644 index e93a13318..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionInformation.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results; - -import com.djrapitops.plan.extension.icon.Icon; - -/** - * Information about a DataExtension stored in the database. - * - * @author Rsl1122 - */ -public class ExtensionInformation { - - private final int id; - private final String pluginName; - private final Icon icon; - - public ExtensionInformation(int id, String pluginName, Icon icon) { - this.id = id; - this.pluginName = pluginName; - this.icon = icon; - } - - public int getId() { - return id; - } - - public String getPluginName() { - return pluginName; - } - - public Icon getIcon() { - return icon; - } - - @Override - public String toString() { - return '{' + "id=" + id + ", pluginName='" + pluginName + '\'' + '}'; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionNumberData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionNumberData.java deleted file mode 100644 index a8e784325..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionNumberData.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results; - -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.utilities.formatting.Formatter; - -/** - * Represents double data returned by a DoubleProvider or PercentageProvider method. - * - * @author Rsl1122 - */ -public class ExtensionNumberData implements ExtensionData { - - private final ExtensionDescriptive descriptive; - private final FormatType formatType; - private final long value; - - public ExtensionNumberData(ExtensionDescriptive descriptive, FormatType formatType, long value) { - this.descriptive = descriptive; - this.formatType = formatType; - this.value = value; - } - - public ExtensionDescriptive getDescriptive() { - return descriptive; - } - - public FormatType getFormatType() { - return formatType; - } - - public String getFormattedValue(Formatter formatter) { - return formatter.apply(value); - } - - public long getRawValue() { - return value; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionStringData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionStringData.java deleted file mode 100644 index c2e3274f0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionStringData.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.utilities.html.Html; - -/** - * Represents double data returned by a DoubleProvider or PercentageProvider method. - * - * @author Rsl1122 - */ -public class ExtensionStringData implements ExtensionData { - - private final ExtensionDescriptive descriptive; - private final boolean playerName; - private final String value; - - public ExtensionStringData(ExtensionDescriptive descriptive, boolean playerName, String value) { - this.descriptive = descriptive; - this.playerName = playerName; - this.value = value; - } - - public ExtensionDescriptive getDescriptive() { - return descriptive; - } - - public String getFormattedValue() { - String withColors = Html.swapColorCodesToSpan(value); - return !playerName ? withColors : Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(value), withColors); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTabData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTabData.java deleted file mode 100644 index b46624713..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTabData.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results; - -import com.djrapitops.plan.extension.implementation.TabInformation; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * Represents data on an extension tab. - * - * @author Rsl1122 - */ -public class ExtensionTabData implements Comparable { - - private final TabInformation tabInformation; // Can be null in case where no tab was defined for provider. - - private final Map booleanData; - private final Map doubleData; - private final Map percentageData; - private final Map numberData; - private final Map stringData; - - private final List tableData; - - private List order; - private List descriptives; - - // Table and Graph data will be added later. - - public ExtensionTabData(TabInformation tabInformation) { - this.tabInformation = tabInformation; - - booleanData = new HashMap<>(); - doubleData = new HashMap<>(); - percentageData = new HashMap<>(); - numberData = new HashMap<>(); - stringData = new HashMap<>(); - - tableData = new ArrayList<>(); - descriptives = new ArrayList<>(); - } - - public TabInformation getTabInformation() { - return tabInformation; - } - - public List getValueOrder() { - return order; - } - - public Optional getBoolean(String providerName) { - return Optional.ofNullable(booleanData.get(providerName)); - } - - public Optional getDouble(String providerName) { - return Optional.ofNullable(doubleData.get(providerName)); - } - - public Optional getPercentage(String providerName) { - return Optional.ofNullable(percentageData.get(providerName)); - } - - public Optional getNumber(String providerName) { - return Optional.ofNullable(numberData.get(providerName)); - } - - public Optional getString(String providerName) { - return Optional.ofNullable(stringData.get(providerName)); - } - - public List getTableData() { - return tableData; - } - - /** - * Get all Descriptives for this tabs data. - *

- * Only available after the Tab has been built. - * - * @return List of {@link ExtensionDescriptive}s. - */ - public List getDescriptives() { - return descriptives; - } - - @Override - public int compareTo(ExtensionTabData other) { - return Integer.compare(this.tabInformation.getTabPriority(), other.tabInformation.getTabPriority()); // Lower is first - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ExtensionTabData)) return false; - ExtensionTabData that = (ExtensionTabData) o; - return tabInformation.equals(that.tabInformation) && - order.equals(that.order); - } - - @Override - public int hashCode() { - return Objects.hash(tabInformation, order); - } - - public void combine(ExtensionTabData other) { - this.booleanData.putAll(other.booleanData); - this.doubleData.putAll(other.doubleData); - this.percentageData.putAll(other.percentageData); - this.numberData.putAll(other.numberData); - this.stringData.putAll(other.stringData); - - this.tableData.addAll(other.tableData); - - createOrderingList(); - } - - private void createOrderingList() { - booleanData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add); - doubleData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add); - percentageData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add); - numberData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add); - stringData.values().stream().map(ExtensionData::getDescriptive).forEach(descriptives::add); - - order = descriptives.stream().sorted() - .map(ExtensionDescriptive::getName) - .distinct()// Method names are usually different, but in case someone had same method name with different parameters. - .collect(Collectors.toList()); - } - - public static class Factory { - - private final ExtensionTabData data; - - public Factory(TabInformation tabInformation) { - data = new ExtensionTabData(tabInformation); - } - - public Factory putBooleanData(ExtensionBooleanData extensionBooleanData) { - data.booleanData.put(extensionBooleanData.getDescriptive().getName(), extensionBooleanData); - return this; - } - - public Factory putDoubleData(ExtensionDoubleData extensionDoubleData) { - data.doubleData.put(extensionDoubleData.getDescriptive().getName(), extensionDoubleData); - return this; - } - - public Factory putPercentageData(ExtensionDoubleData extensionDoubleData) { - data.percentageData.put(extensionDoubleData.getDescriptive().getName(), extensionDoubleData); - return this; - } - - public Factory putNumberData(ExtensionNumberData extensionNumberData) { - data.numberData.put(extensionNumberData.getDescriptive().getName(), extensionNumberData); - return this; - } - - public Factory putStringData(ExtensionStringData extensionStringData) { - data.stringData.put(extensionStringData.getDescriptive().getName(), extensionStringData); - return this; - } - - public Factory putTableData(ExtensionTableData extensionTableData) { - data.tableData.add(extensionTableData); - return this; - } - - public ExtensionTabData build() { - data.createOrderingList(); - Collections.sort(data.tableData); - return data; - } - } - - @Override - public String toString() { - return "ExtensionTabData{" + - "available=" + order + - '}'; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTableData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTableData.java deleted file mode 100644 index 99ce47816..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTableData.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results; - -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.table.Table; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -/** - * Represents table data from a single TableProvider. - * - * @author Rsl1122 - */ -public class ExtensionTableData implements Comparable { - - private final String providerName; - private final Table table; - private final Color tableColor; - - public ExtensionTableData(String providerName, Table table, Color tableColor) { - this.providerName = providerName; - this.table = table; - this.tableColor = tableColor; - } - - public TableContainer getHtmlTable() { - String[] columns = table.getColumns(); - Icon[] icons = table.getIcons(); - List rows = table.getRows(); - - String[] header = buildHeader(columns, icons); - - TableContainer htmlTable = new TableContainer(header); - if (rows.size() > 50) { - htmlTable.useJqueryDataTables(); // Use a jQuery data table since there are a lot of rows. - } else { - String colorName = com.djrapitops.plan.utilities.html.icon.Color.getByName(tableColor.name()).orElse(com.djrapitops.plan.utilities.html.icon.Color.NONE).getHtmlClass() - .replace("col-", ""); // TODO after PluginData deprecation, change this thing - htmlTable.setColor(colorName); - } - - for (Object[] row : rows) { - htmlTable.addRow(Arrays.stream(row).map(value -> value != null ? value.toString() : null).toArray(Serializable[]::new)); - } - - return htmlTable; - } - - private String[] buildHeader(String[] columns, Icon[] icons) { - ArrayList header = new ArrayList<>(); - - for (int i = 0; i < columns.length; i++) { - String column = columns[i]; - if (column == null) { - break; - } - header.add(com.djrapitops.plan.utilities.html.icon.Icon.fromExtensionIcon(icons[i]).toHtml() + ' ' + column); - } - - return header.toArray(new String[0]); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ExtensionTableData)) return false; - ExtensionTableData that = (ExtensionTableData) o; - return providerName.equals(that.providerName) && - tableColor == that.tableColor; - } - - @Override - public int hashCode() { - return Objects.hash(providerName, tableColor); - } - - @Override - public int compareTo(ExtensionTableData other) { - return String.CASE_INSENSITIVE_ORDER.compare(providerName, other.providerName); - } - - public boolean isWideTable() { - return table.getMaxColumnSize() > 3; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/player/ExtensionPlayerData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/player/ExtensionPlayerData.java deleted file mode 100644 index dba53f4a7..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/player/ExtensionPlayerData.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results.player; - -import com.djrapitops.plan.extension.implementation.results.ExtensionInformation; -import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; - -import java.util.*; - -/** - * Represents data of a single extension about a player. - * - * @author Rsl1122 - */ -public class ExtensionPlayerData implements Comparable { - - private final int pluginID; - - private ExtensionInformation extensionInformation; - - private List tabs; - - private ExtensionPlayerData(int pluginID) { - this.pluginID = pluginID; - - tabs = new ArrayList<>(); - } - - public int getPluginID() { - return pluginID; - } - - public ExtensionInformation getExtensionInformation() { - return extensionInformation; - } - - public boolean hasOnlyGenericTab() { - return tabs.size() == 1 && tabs.get(0).getTabInformation().getTabName().isEmpty(); - } - - public List getTabs() { - return tabs; - } - - @Override - public int compareTo(ExtensionPlayerData o) { - return String.CASE_INSENSITIVE_ORDER.compare(this.extensionInformation.getPluginName(), o.extensionInformation.getPluginName()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ExtensionPlayerData)) return false; - ExtensionPlayerData that = (ExtensionPlayerData) o; - return pluginID == that.pluginID && - extensionInformation.equals(that.extensionInformation) && - tabs.equals(that.tabs); - } - - @Override - public int hashCode() { - return Objects.hash(pluginID, extensionInformation, tabs); - } - - public static class Factory { - - private final ExtensionPlayerData data; - - public Factory(int pluginId) { - data = new ExtensionPlayerData(pluginId); - } - - public Factory setInformation(ExtensionInformation information) { - if (information.getId() != data.pluginID) { - throw new IllegalArgumentException("ID mismatch, wanted id: " + data.pluginID + " but got " + information); - } - data.extensionInformation = information; - return this; - } - - public Factory addTab(ExtensionTabData tab) { - data.tabs.add(tab); - return this; - } - - public ExtensionPlayerData build() { - Collections.sort(data.tabs); - return data; - } - - public Factory combine(Factory with) { - if (with != null) { - for (ExtensionTabData tab : with.build().getTabs()) { - Optional found = getTab(tab.getTabInformation().getTabName()); - if (found.isPresent()) { - found.get().combine(tab); - } else { - addTab(tab); - } - } - } - return this; - } - - public Optional getTab(String tabName) { - for (ExtensionTabData tab : data.tabs) { - if (tabName.equals(tab.getTabInformation().getTabName())) { - return Optional.of(tab); - } - } - return Optional.empty(); - } - - - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/server/ExtensionServerData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/server/ExtensionServerData.java deleted file mode 100644 index 80a974b8c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/server/ExtensionServerData.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.results.server; - -import com.djrapitops.plan.extension.implementation.results.ExtensionInformation; -import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; - -import java.util.*; - -/** - * Represents data of a single extension about a server. - * - * @author Rsl1122 - */ -public class ExtensionServerData implements Comparable { - - private final int pluginID; - - private ExtensionInformation extensionInformation; - - private Map tabs; - - private ExtensionServerData(int pluginID) { - this.pluginID = pluginID; - - tabs = new HashMap<>(); - } - - public int getPluginID() { - return pluginID; - } - - public ExtensionInformation getExtensionInformation() { - return extensionInformation; - } - - public boolean hasOnlyGenericTab() { - return tabs.size() == 1 && tabs.containsKey(""); - } - - public List getTabs() { - List tabList = new ArrayList<>(tabs.values()); - Collections.sort(tabList); - return tabList; - } - - @Override - public int compareTo(ExtensionServerData o) { - return String.CASE_INSENSITIVE_ORDER.compare(this.extensionInformation.getPluginName(), o.extensionInformation.getPluginName()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ExtensionServerData)) return false; - ExtensionServerData that = (ExtensionServerData) o; - return pluginID == that.pluginID && - Objects.equals(extensionInformation, that.extensionInformation) && - Objects.equals(tabs, that.tabs); - } - - @Override - public int hashCode() { - return Objects.hash(pluginID, extensionInformation, tabs); - } - - public static class Factory { - - private final ExtensionServerData data; - - public Factory(int pluginId) { - data = new ExtensionServerData(pluginId); - } - - public Factory combine(Factory with) { - if (with != null) { - for (ExtensionTabData tab : with.build().getTabs()) { - Optional found = getTab(tab.getTabInformation().getTabName()); - if (found.isPresent()) { - found.get().combine(tab); - } else { - addTab(tab); - } - } - } - return this; - } - - public Factory setInformation(ExtensionInformation information) { - if (information.getId() != data.pluginID) { - throw new IllegalArgumentException("ID mismatch, wanted id: " + data.pluginID + " but got " + information); - } - data.extensionInformation = information; - return this; - } - - public Factory addTab(ExtensionTabData tab) { - data.tabs.put(tab.getTabInformation().getTabName(), tab); - return this; - } - - public Optional getTab(String tabName) { - return Optional.ofNullable(data.tabs.get(tabName)); - } - - public ExtensionServerData build() { - return data; - } - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateBooleansQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateBooleansQuery.java deleted file mode 100644 index a801f77cf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateBooleansQuery.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.TabInformation; -import com.djrapitops.plan.extension.implementation.results.ExtensionDescriptive; -import com.djrapitops.plan.extension.implementation.results.ExtensionDoubleData; -import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; -import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Query aggregated boolean values from player value table. - *

- * Returns Map: PluginID - ExtensionServerData.Factory. - *

- * How it is done: - * - Combines three queries, one that selects true boolean count, one that selects boolean value count and one that selects provider information. - * - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data - * - (Tab Name can be empty.) - * - Multi-map is sorted into ExtensionPlayerData objects by PluginID, one per ID - *

- * There are multiple data extraction methods to make extracting the value query easier. - * - * @author Rsl1122 - */ -public class ExtensionAggregateBooleansQuery implements Query> { - - private final UUID serverUUID; - - public ExtensionAggregateBooleansQuery(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - @Override - public Map executeQuery(SQLDB db) { - String selectTrueBooleans = SELECT + - ExtensionPlayerValueTable.PROVIDER_ID + - ",COUNT(1) as positive" + - FROM + ExtensionPlayerValueTable.TABLE_NAME + - WHERE + ExtensionPlayerValueTable.BOOLEAN_VALUE + "=?" + - GROUP_BY + ExtensionPlayerValueTable.PROVIDER_ID; - - String selectBooleanCount = SELECT + - ExtensionPlayerValueTable.PROVIDER_ID + - ",COUNT(1) as total" + - FROM + ExtensionPlayerValueTable.TABLE_NAME + - WHERE + ExtensionPlayerValueTable.BOOLEAN_VALUE + IS_NOT_NULL + - GROUP_BY + ExtensionPlayerValueTable.PROVIDER_ID; - - String sql = SELECT + - "b1.total as total," + - "b2.positive as positive," + - "p1." + ExtensionProviderTable.PLUGIN_ID + " as plugin_id," + - "p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," + - "p1." + ExtensionProviderTable.TEXT + " as text," + - "p1." + ExtensionProviderTable.DESCRIPTION + " as description," + - "p1." + ExtensionProviderTable.PRIORITY + " as provider_priority," + - "p1." + ExtensionProviderTable.IS_PLAYER_NAME + " as is_player_name," + - "t1." + ExtensionTabTable.TAB_NAME + " as tab_name," + - "t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," + - "t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," + - "i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," + - "i1." + ExtensionIconTable.FAMILY + " as provider_icon_family," + - "i1." + ExtensionIconTable.COLOR + " as provider_icon_color," + - "i2." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," + - "i2." + ExtensionIconTable.FAMILY + " as tab_icon_family," + - "i2." + ExtensionIconTable.COLOR + " as tab_icon_color" + - FROM + '(' + selectBooleanCount + ") b1" + - INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=b1." + ExtensionPlayerValueTable.PROVIDER_ID + - INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on p1." + ExtensionProviderTable.PLUGIN_ID + "=e1." + ExtensionPluginTable.ID + - LEFT_JOIN + '(' + selectTrueBooleans + ") b2 on b2." + ExtensionPlayerValueTable.PROVIDER_ID + "=b1." + ExtensionPlayerValueTable.PROVIDER_ID + - LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionProviderTable.TAB_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTabTable.ICON_ID + - WHERE + ExtensionPluginTable.SERVER_UUID + "=?" + - AND + "p1." + ExtensionProviderTable.HIDDEN + "=?"; - - return db.query(new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, true); // selectTrueBooleans parameter - statement.setString(2, serverUUID.toString()); - statement.setBoolean(3, false); // Don't select hidden values - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map> tabDataByPluginID = extractTabDataByPluginID(set); - return ExtensionServerDataQuery.flatMapToServerData(tabDataByPluginID); - } - }); - } - - private Map> extractTabDataByPluginID(ResultSet set) throws SQLException { - Map> tabDataByPluginID = new HashMap<>(); - - while (set.next()) { - int pluginID = set.getInt("plugin_id"); - Map tabData = tabDataByPluginID.getOrDefault(pluginID, new HashMap<>()); - - String tabName = Optional.ofNullable(set.getString("tab_name")).orElse(""); - ExtensionTabData.Factory inMap = tabData.get(tabName); - ExtensionTabData.Factory extensionTab = inMap != null ? inMap : extractTab(tabName, set, tabData); - - ExtensionDescriptive extensionDescriptive = extractDescriptive(set); - extractAndPutDataTo(extensionTab, extensionDescriptive, set); - - tabData.put(tabName, extensionTab); - tabDataByPluginID.put(pluginID, tabData); - } - return tabDataByPluginID; - } - - private void extractAndPutDataTo(ExtensionTabData.Factory extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException { - double percentageValue = percentage(set.getInt("positive"), set.getInt("total")); - extensionTab.putPercentageData(new ExtensionDoubleData(descriptive, percentageValue)); - } - - private double percentage(double first, double second) { - if (first == 0.0 || second == 0.0) { - return 0.0; - } - return first / second; - } - - private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException { - String name = set.getString("provider_name") + "_aggregate"; - String text = set.getString(ExtensionProviderTable.TEXT) + " / Players"; - String description = set.getString(ExtensionProviderTable.DESCRIPTION); - int priority = set.getInt("provider_priority"); - - String iconName = set.getString("provider_icon_name"); - Family family = Family.getByName(set.getString("provider_icon_family")).orElse(Family.SOLID); - Color color = Color.getByName(set.getString("provider_icon_color")).orElse(Color.NONE); - Icon icon = new Icon(family, iconName, color); - - return new ExtensionDescriptive(name, text, description, icon, priority); - } - - private ExtensionTabData.Factory extractTab(String tabName, ResultSet set, Map tabData) throws SQLException { - Optional tabPriority = Optional.of(set.getInt("tab_priority")); - if (set.wasNull()) { - tabPriority = Optional.empty(); - } - Optional elementOrder = Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize); - - Icon tabIcon = extractTabIcon(set); - - return tabData.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation( - tabName, - tabIcon, - elementOrder.orElse(ElementOrder.values()), - tabPriority.orElse(100) - ))); - } - - private Icon extractTabIcon(ResultSet set) throws SQLException { - Optional iconName = Optional.ofNullable(set.getString("tab_icon_name")); - if (iconName.isPresent()) { - Family iconFamily = Family.getByName(set.getString("tab_icon_family")).orElse(Family.SOLID); - Color iconColor = Color.getByName(set.getString("tab_icon_color")).orElse(Color.NONE); - return new Icon(iconFamily, iconName.get(), iconColor); - } else { - return TabInformation.defaultIcon(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateDoublesQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateDoublesQuery.java deleted file mode 100644 index db5dcfdc9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateDoublesQuery.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.TabInformation; -import com.djrapitops.plan.extension.implementation.results.ExtensionDescriptive; -import com.djrapitops.plan.extension.implementation.results.ExtensionDoubleData; -import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; -import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Query aggregated boolean values from player value table. - *

- * Returns Map: PluginID - ExtensionServerData.Factory. - *

- * How it is done: - * - Combines three queries, one that selects true boolean count, one that selects boolean value count and one that selects provider information. - * - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data - * - (Tab Name can be empty.) - * - Multi-map is sorted into ExtensionPlayerData objects by PluginID, one per ID - *

- * There are multiple data extraction methods to make extracting the value query easier. - * - * @author Rsl1122 - */ -public class ExtensionAggregateDoublesQuery implements Query> { - - private final UUID serverUUID; - - public ExtensionAggregateDoublesQuery(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - @Override - public Map executeQuery(SQLDB db) { - String selectDoubleAverage = SELECT + - ExtensionPlayerValueTable.PROVIDER_ID + - ",AVG(" + ExtensionPlayerValueTable.DOUBLE_VALUE + ") as average" + - FROM + ExtensionPlayerValueTable.TABLE_NAME + - WHERE + ExtensionPlayerValueTable.DOUBLE_VALUE + IS_NOT_NULL + - GROUP_BY + ExtensionPlayerValueTable.PROVIDER_ID; - - String selectDoubleTotal = SELECT + - ExtensionPlayerValueTable.PROVIDER_ID + - ",SUM(" + ExtensionPlayerValueTable.DOUBLE_VALUE + ") as total" + - FROM + ExtensionPlayerValueTable.TABLE_NAME + - WHERE + ExtensionPlayerValueTable.DOUBLE_VALUE + IS_NOT_NULL + - GROUP_BY + ExtensionPlayerValueTable.PROVIDER_ID; - - String sql = SELECT + - "b1.total as total," + - "b2.average as average," + - "p1." + ExtensionProviderTable.PLUGIN_ID + " as plugin_id," + - "p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," + - "p1." + ExtensionProviderTable.TEXT + " as text," + - "p1." + ExtensionProviderTable.DESCRIPTION + " as description," + - "p1." + ExtensionProviderTable.PRIORITY + " as provider_priority," + - "p1." + ExtensionProviderTable.IS_PLAYER_NAME + " as is_player_name," + - "t1." + ExtensionTabTable.TAB_NAME + " as tab_name," + - "t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," + - "t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," + - "i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," + - "i1." + ExtensionIconTable.FAMILY + " as provider_icon_family," + - "i1." + ExtensionIconTable.COLOR + " as provider_icon_color," + - "i2." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," + - "i2." + ExtensionIconTable.FAMILY + " as tab_icon_family," + - "i2." + ExtensionIconTable.COLOR + " as tab_icon_color" + - FROM + '(' + selectDoubleTotal + ") b1" + - INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=b1." + ExtensionPlayerValueTable.PROVIDER_ID + - INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on p1." + ExtensionProviderTable.PLUGIN_ID + "=e1." + ExtensionPluginTable.ID + - LEFT_JOIN + '(' + selectDoubleAverage + ") b2 on b2." + ExtensionPlayerValueTable.PROVIDER_ID + "=b1." + ExtensionPlayerValueTable.PROVIDER_ID + - LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionProviderTable.TAB_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTabTable.ICON_ID + - WHERE + ExtensionPluginTable.SERVER_UUID + "=?" + - AND + "p1." + ExtensionProviderTable.HIDDEN + "=?"; - - return db.query(new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - statement.setBoolean(2, false); // Don't select hidden values - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map> tabDataByPluginID = extractTabDataByPluginID(set); - return ExtensionServerDataQuery.flatMapToServerData(tabDataByPluginID); - } - }); - } - - private Map> extractTabDataByPluginID(ResultSet set) throws SQLException { - Map> tabDataByPluginID = new HashMap<>(); - - while (set.next()) { - int pluginID = set.getInt("plugin_id"); - Map tabData = tabDataByPluginID.getOrDefault(pluginID, new HashMap<>()); - - String tabName = Optional.ofNullable(set.getString("tab_name")).orElse(""); - ExtensionTabData.Factory inMap = tabData.get(tabName); - ExtensionTabData.Factory extensionTab = inMap != null ? inMap : extractTab(tabName, set, tabData); - - ExtensionDescriptive extensionDescriptive = extractDescriptive(set); - extractAndPutDataTo(extensionTab, extensionDescriptive, set); - - tabData.put(tabName, extensionTab); - tabDataByPluginID.put(pluginID, tabData); - } - return tabDataByPluginID; - } - - private void extractAndPutDataTo(ExtensionTabData.Factory extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException { - extensionTab.putDoubleData(new ExtensionDoubleData(modifiedDescriptive(descriptive, "_avg", "Average "), set.getDouble("average"))); - extensionTab.putDoubleData(new ExtensionDoubleData(modifiedDescriptive(descriptive, "_total", "Total "), set.getDouble("total"))); - } - - private ExtensionDescriptive modifiedDescriptive(ExtensionDescriptive descriptive, String appendToName, String appendToText) { - return new ExtensionDescriptive(descriptive.getName() + appendToName, appendToText + descriptive.getText(), descriptive.getDescription().orElse(null), descriptive.getIcon(), descriptive.getPriority()); - } - - private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException { - String name = set.getString("provider_name"); - String text = set.getString(ExtensionProviderTable.TEXT); - String description = set.getString(ExtensionProviderTable.DESCRIPTION); - int priority = set.getInt("provider_priority"); - - String iconName = set.getString("provider_icon_name"); - Family family = Family.getByName(set.getString("provider_icon_family")).orElse(Family.SOLID); - Color color = Color.getByName(set.getString("provider_icon_color")).orElse(Color.NONE); - Icon icon = new Icon(family, iconName, color); - - return new ExtensionDescriptive(name, text, description, icon, priority); - } - - private ExtensionTabData.Factory extractTab(String tabName, ResultSet set, Map tabData) throws SQLException { - Optional tabPriority = Optional.of(set.getInt("tab_priority")); - if (set.wasNull()) { - tabPriority = Optional.empty(); - } - Optional elementOrder = Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize); - - Icon tabIcon = extractTabIcon(set); - - return tabData.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation( - tabName, - tabIcon, - elementOrder.orElse(ElementOrder.values()), - tabPriority.orElse(100) - ))); - } - - private Icon extractTabIcon(ResultSet set) throws SQLException { - Optional iconName = Optional.ofNullable(set.getString("tab_icon_name")); - if (iconName.isPresent()) { - Family iconFamily = Family.getByName(set.getString("tab_icon_family")).orElse(Family.SOLID); - Color iconColor = Color.getByName(set.getString("tab_icon_color")).orElse(Color.NONE); - return new Icon(iconFamily, iconName.get(), iconColor); - } else { - return TabInformation.defaultIcon(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateNumbersQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateNumbersQuery.java deleted file mode 100644 index 9ff611889..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregateNumbersQuery.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.TabInformation; -import com.djrapitops.plan.extension.implementation.results.ExtensionDescriptive; -import com.djrapitops.plan.extension.implementation.results.ExtensionNumberData; -import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; -import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Query aggregated boolean values from player value table. - *

- * Returns Map: PluginID - ExtensionServerData.Factory. - *

- * How it is done: - * - Combines three queries, one that selects true boolean count, one that selects boolean value count and one that selects provider information. - * - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data - * - (Tab Name can be empty.) - * - Multi-map is sorted into ExtensionPlayerData objects by PluginID, one per ID - *

- * There are multiple data extraction methods to make extracting the value query easier. - * - * @author Rsl1122 - */ -public class ExtensionAggregateNumbersQuery implements Query> { - - private final UUID serverUUID; - - public ExtensionAggregateNumbersQuery(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - @Override - public Map executeQuery(SQLDB db) { - String selectNumberAverage = SELECT + - ExtensionPlayerValueTable.PROVIDER_ID + - ",AVG(" + ExtensionPlayerValueTable.LONG_VALUE + ") as average" + - FROM + ExtensionPlayerValueTable.TABLE_NAME + - WHERE + ExtensionPlayerValueTable.LONG_VALUE + IS_NOT_NULL + - GROUP_BY + ExtensionPlayerValueTable.PROVIDER_ID; - - String selectNumberTotal = SELECT + - ExtensionPlayerValueTable.PROVIDER_ID + - ",SUM(" + ExtensionPlayerValueTable.LONG_VALUE + ") as total" + - FROM + ExtensionPlayerValueTable.TABLE_NAME + - WHERE + ExtensionPlayerValueTable.LONG_VALUE + IS_NOT_NULL + - GROUP_BY + ExtensionPlayerValueTable.PROVIDER_ID; - - String sql = SELECT + - "b1.total as total," + - "b2.average as average," + - "p1." + ExtensionProviderTable.PLUGIN_ID + " as plugin_id," + - "p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," + - "p1." + ExtensionProviderTable.TEXT + " as text," + - "p1." + ExtensionProviderTable.DESCRIPTION + " as description," + - "p1." + ExtensionProviderTable.PRIORITY + " as provider_priority," + - "p1." + ExtensionProviderTable.FORMAT_TYPE + " as format_type," + - "p1." + ExtensionProviderTable.IS_PLAYER_NAME + " as is_player_name," + - "t1." + ExtensionTabTable.TAB_NAME + " as tab_name," + - "t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," + - "t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," + - "i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," + - "i1." + ExtensionIconTable.FAMILY + " as provider_icon_family," + - "i1." + ExtensionIconTable.COLOR + " as provider_icon_color," + - "i2." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," + - "i2." + ExtensionIconTable.FAMILY + " as tab_icon_family," + - "i2." + ExtensionIconTable.COLOR + " as tab_icon_color" + - FROM + '(' + selectNumberTotal + ") b1" + - INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=b1." + ExtensionPlayerValueTable.PROVIDER_ID + - INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on p1." + ExtensionProviderTable.PLUGIN_ID + "=e1." + ExtensionPluginTable.ID + - LEFT_JOIN + '(' + selectNumberAverage + ") b2 on b2." + ExtensionPlayerValueTable.PROVIDER_ID + "=b1." + ExtensionPlayerValueTable.PROVIDER_ID + - LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionProviderTable.TAB_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTabTable.ICON_ID + - WHERE + ExtensionPluginTable.SERVER_UUID + "=?" + - AND + "p1." + ExtensionProviderTable.HIDDEN + "=?" + - AND + "p1." + ExtensionProviderTable.FORMAT_TYPE + "!=?" + - AND + "p1." + ExtensionProviderTable.FORMAT_TYPE + "!=?"; - - return db.query(new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - statement.setBoolean(2, false); // Don't select hidden values - statement.setString(3, FormatType.DATE_YEAR.name()); - statement.setString(4, FormatType.DATE_SECOND.name()); - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map> tabDataByPluginID = extractTabDataByPluginID(set); - return ExtensionServerDataQuery.flatMapToServerData(tabDataByPluginID); - } - }); - } - - private Map> extractTabDataByPluginID(ResultSet set) throws SQLException { - Map> tabDataByPluginID = new HashMap<>(); - - while (set.next()) { - int pluginID = set.getInt("plugin_id"); - Map tabData = tabDataByPluginID.getOrDefault(pluginID, new HashMap<>()); - - String tabName = Optional.ofNullable(set.getString("tab_name")).orElse(""); - ExtensionTabData.Factory inMap = tabData.get(tabName); - ExtensionTabData.Factory extensionTab = inMap != null ? inMap : extractTab(tabName, set, tabData); - - ExtensionDescriptive extensionDescriptive = extractDescriptive(set); - extractAndPutDataTo(extensionTab, extensionDescriptive, set); - - tabData.put(tabName, extensionTab); - tabDataByPluginID.put(pluginID, tabData); - } - return tabDataByPluginID; - } - - private void extractAndPutDataTo(ExtensionTabData.Factory extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException { - FormatType formatType = FormatType.getByName(set.getString(ExtensionProviderTable.FORMAT_TYPE)).orElse(FormatType.NONE); - extensionTab.putNumberData(new ExtensionNumberData(modifiedDescriptive(descriptive, "_avg", "Average "), formatType, (long) set.getDouble("average"))); - extensionTab.putNumberData(new ExtensionNumberData(modifiedDescriptive(descriptive, "_total", "Total "), formatType, (long) set.getDouble("total"))); - } - - private ExtensionDescriptive modifiedDescriptive(ExtensionDescriptive descriptive, String appendToName, String appendToText) { - return new ExtensionDescriptive(descriptive.getName() + appendToName, appendToText + descriptive.getText(), descriptive.getDescription().orElse(null), descriptive.getIcon(), descriptive.getPriority()); - } - - private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException { - String name = set.getString("provider_name"); - String text = set.getString(ExtensionProviderTable.TEXT); - String description = set.getString(ExtensionProviderTable.DESCRIPTION); - int priority = set.getInt("provider_priority"); - - String iconName = set.getString("provider_icon_name"); - Family family = Family.getByName(set.getString("provider_icon_family")).orElse(Family.SOLID); - Color color = Color.getByName(set.getString("provider_icon_color")).orElse(Color.NONE); - Icon icon = new Icon(family, iconName, color); - - return new ExtensionDescriptive(name, text, description, icon, priority); - } - - private ExtensionTabData.Factory extractTab(String tabName, ResultSet set, Map tabData) throws SQLException { - Optional tabPriority = Optional.of(set.getInt("tab_priority")); - if (set.wasNull()) { - tabPriority = Optional.empty(); - } - Optional elementOrder = Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize); - - Icon tabIcon = extractTabIcon(set); - - return tabData.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation( - tabName, - tabIcon, - elementOrder.orElse(ElementOrder.values()), - tabPriority.orElse(100) - ))); - } - - private Icon extractTabIcon(ResultSet set) throws SQLException { - Optional iconName = Optional.ofNullable(set.getString("tab_icon_name")); - if (iconName.isPresent()) { - Family iconFamily = Family.getByName(set.getString("tab_icon_family")).orElse(Family.SOLID); - Color iconColor = Color.getByName(set.getString("tab_icon_color")).orElse(Color.NONE); - return new Icon(iconFamily, iconName.get(), iconColor); - } else { - return TabInformation.defaultIcon(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregatePercentagesQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregatePercentagesQuery.java deleted file mode 100644 index ebac42ed3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionAggregatePercentagesQuery.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.TabInformation; -import com.djrapitops.plan.extension.implementation.results.ExtensionDescriptive; -import com.djrapitops.plan.extension.implementation.results.ExtensionDoubleData; -import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; -import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Query aggregated boolean values from player value table. - *

- * Returns Map: PluginID - ExtensionServerData.Factory. - *

- * How it is done: - * - Combines three queries, one that selects true boolean count, one that selects boolean value count and one that selects provider information. - * - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data - * - (Tab Name can be empty.) - * - Multi-map is sorted into ExtensionPlayerData objects by PluginID, one per ID - *

- * There are multiple data extraction methods to make extracting the value query easier. - * - * @author Rsl1122 - */ -public class ExtensionAggregatePercentagesQuery implements Query> { - - private final UUID serverUUID; - - public ExtensionAggregatePercentagesQuery(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - @Override - public Map executeQuery(SQLDB db) { - String selectPercentageAverage = SELECT + - ExtensionPlayerValueTable.PROVIDER_ID + - ",AVG(" + ExtensionPlayerValueTable.PERCENTAGE_VALUE + ") as average" + - FROM + ExtensionPlayerValueTable.TABLE_NAME + - WHERE + ExtensionPlayerValueTable.PERCENTAGE_VALUE + IS_NOT_NULL + - GROUP_BY + ExtensionPlayerValueTable.PROVIDER_ID; - - String sql = SELECT + - "b1.average as average," + - "p1." + ExtensionProviderTable.PLUGIN_ID + " as plugin_id," + - "p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," + - "p1." + ExtensionProviderTable.TEXT + " as text," + - "p1." + ExtensionProviderTable.DESCRIPTION + " as description," + - "p1." + ExtensionProviderTable.PRIORITY + " as provider_priority," + - "p1." + ExtensionProviderTable.IS_PLAYER_NAME + " as is_player_name," + - "t1." + ExtensionTabTable.TAB_NAME + " as tab_name," + - "t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," + - "t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," + - "i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," + - "i1." + ExtensionIconTable.FAMILY + " as provider_icon_family," + - "i1." + ExtensionIconTable.COLOR + " as provider_icon_color," + - "i2." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," + - "i2." + ExtensionIconTable.FAMILY + " as tab_icon_family," + - "i2." + ExtensionIconTable.COLOR + " as tab_icon_color" + - FROM + '(' + selectPercentageAverage + ") b1" + - INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=b1." + ExtensionPlayerValueTable.PROVIDER_ID + - INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on p1." + ExtensionProviderTable.PLUGIN_ID + "=e1." + ExtensionPluginTable.ID + - LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionProviderTable.TAB_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTabTable.ICON_ID + - WHERE + ExtensionPluginTable.SERVER_UUID + "=?" + - AND + "p1." + ExtensionProviderTable.HIDDEN + "=?"; - - return db.query(new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - statement.setBoolean(2, false); // Don't select hidden values - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map> tabDataByPluginID = extractTabDataByPluginID(set); - return ExtensionServerDataQuery.flatMapToServerData(tabDataByPluginID); - } - }); - } - - private Map> extractTabDataByPluginID(ResultSet set) throws SQLException { - Map> tabDataByPluginID = new HashMap<>(); - - while (set.next()) { - int pluginID = set.getInt("plugin_id"); - Map tabData = tabDataByPluginID.getOrDefault(pluginID, new HashMap<>()); - - String tabName = Optional.ofNullable(set.getString("tab_name")).orElse(""); - ExtensionTabData.Factory inMap = tabData.get(tabName); - ExtensionTabData.Factory extensionTab = inMap != null ? inMap : extractTab(tabName, set, tabData); - - ExtensionDescriptive extensionDescriptive = extractDescriptive(set); - extractAndPutDataTo(extensionTab, extensionDescriptive, set); - - tabData.put(tabName, extensionTab); - tabDataByPluginID.put(pluginID, tabData); - } - return tabDataByPluginID; - } - - private void extractAndPutDataTo(ExtensionTabData.Factory extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException { - extensionTab.putPercentageData(new ExtensionDoubleData(modifiedDescriptive(descriptive, "_avg", "Average "), set.getDouble("average"))); - } - - private ExtensionDescriptive modifiedDescriptive(ExtensionDescriptive descriptive, String appendToName, String appendToText) { - return new ExtensionDescriptive(descriptive.getName() + appendToName, appendToText + descriptive.getText(), descriptive.getDescription().orElse(null), descriptive.getIcon(), descriptive.getPriority()); - } - - private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException { - String name = set.getString("provider_name"); - String text = set.getString(ExtensionProviderTable.TEXT); - String description = set.getString(ExtensionProviderTable.DESCRIPTION); - int priority = set.getInt("provider_priority"); - - String iconName = set.getString("provider_icon_name"); - Family family = Family.getByName(set.getString("provider_icon_family")).orElse(Family.SOLID); - Color color = Color.getByName(set.getString("provider_icon_color")).orElse(Color.NONE); - Icon icon = new Icon(family, iconName, color); - - return new ExtensionDescriptive(name, text, description, icon, priority); - } - - private ExtensionTabData.Factory extractTab(String tabName, ResultSet set, Map tabData) throws SQLException { - Optional tabPriority = Optional.of(set.getInt("tab_priority")); - if (set.wasNull()) { - tabPriority = Optional.empty(); - } - Optional elementOrder = Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize); - - Icon tabIcon = extractTabIcon(set); - - return tabData.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation( - tabName, - tabIcon, - elementOrder.orElse(ElementOrder.values()), - tabPriority.orElse(100) - ))); - } - - private Icon extractTabIcon(ResultSet set) throws SQLException { - Optional iconName = Optional.ofNullable(set.getString("tab_icon_name")); - if (iconName.isPresent()) { - Family iconFamily = Family.getByName(set.getString("tab_icon_family")).orElse(Family.SOLID); - Color iconColor = Color.getByName(set.getString("tab_icon_color")).orElse(Color.NONE); - return new Icon(iconFamily, iconName.get(), iconColor); - } else { - return TabInformation.defaultIcon(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionInformationQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionInformationQueries.java deleted file mode 100644 index cf2969a25..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionInformationQueries.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryAllStatement; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.results.ExtensionInformation; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Queries for information about DataExtensions stored in the database. - * - * @author Rsl1122 - */ -public class ExtensionInformationQueries { - - private ExtensionInformationQueries() { - /* Static method class */ - } - - public static Query> extensionsOfServer(UUID serverUUID) { - String sql = SELECT + - ExtensionPluginTable.TABLE_NAME + '.' + ExtensionPluginTable.ID + " as id," + - ExtensionPluginTable.TABLE_NAME + '.' + ExtensionPluginTable.PLUGIN_NAME + " as plugin_name," + - ExtensionIconTable.TABLE_NAME + '.' + ExtensionIconTable.ICON_NAME + " as icon_name," + - ExtensionIconTable.COLOR + ',' + - ExtensionIconTable.FAMILY + - FROM + ExtensionPluginTable.TABLE_NAME + - INNER_JOIN + ExtensionIconTable.TABLE_NAME + " on " + - ExtensionPluginTable.ICON_ID + "=" + ExtensionIconTable.TABLE_NAME + '.' + ExtensionIconTable.ID + - WHERE + ExtensionPluginTable.SERVER_UUID + "=?"; - - return new QueryStatement>(sql, 100) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public List processResults(ResultSet set) throws SQLException { - List information = new ArrayList<>(); - while (set.next()) { - information.add(extractExtensionInformationFromQuery(set)); - } - return information; - } - }; - } - - private static ExtensionInformation extractExtensionInformationFromQuery(ResultSet set) throws SQLException { - int id = set.getInt("id"); - String pluginName = set.getString("plugin_name"); - - String iconName = set.getString("icon_name"); - Family iconFamily = Family.getByName(set.getString(ExtensionIconTable.FAMILY)).orElse(Family.SOLID); - Color color = Color.getByName(set.getString(ExtensionIconTable.COLOR)).orElse(Color.NONE); - Icon icon = new Icon(iconFamily, iconName, color); - - return new ExtensionInformation(id, pluginName, icon); - } - - public static Query>> allExtensions() { - String sql = SELECT + - ExtensionPluginTable.TABLE_NAME + '.' + ExtensionPluginTable.ID + " as id," + - ExtensionPluginTable.TABLE_NAME + '.' + ExtensionPluginTable.PLUGIN_NAME + " as plugin_name," + - ExtensionPluginTable.SERVER_UUID + ',' + - ExtensionIconTable.TABLE_NAME + '.' + ExtensionIconTable.ICON_NAME + " as icon_name," + - ExtensionIconTable.COLOR + ',' + - ExtensionIconTable.FAMILY + - FROM + ExtensionPluginTable.TABLE_NAME + - INNER_JOIN + ExtensionIconTable.TABLE_NAME + " on " + - ExtensionPluginTable.ICON_ID + "=" + ExtensionIconTable.TABLE_NAME + '.' + ExtensionIconTable.ID; - - return new QueryAllStatement>>(sql, 100) { - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> byServerUUID = new HashMap<>(); - while (set.next()) { - UUID serverUUID = UUID.fromString(set.getString(ExtensionPluginTable.SERVER_UUID)); - List information = byServerUUID.getOrDefault(serverUUID, new ArrayList<>()); - information.add(extractExtensionInformationFromQuery(set)); - byServerUUID.put(serverUUID, information); - } - return byServerUUID; - } - }; - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerDataQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerDataQuery.java deleted file mode 100644 index d1140ab49..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerDataQuery.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTabTable; -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.TabInformation; -import com.djrapitops.plan.extension.implementation.results.*; -import com.djrapitops.plan.extension.implementation.results.player.ExtensionPlayerData; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Query all ExtensionPlayerData by Server UUIDs. - *

- * Returns Map: Server UUID - List of ExtensionPlayerData. - *

- * How it is done: - * - Two queries are run, one that fetches all extensions and one that fetches all data of the player. - * - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data - * - (Tab Name can be empty.) - * - Multi-map is sorted into ExtensionPlayerData objects by PluginID, one per ID - * - This map is sorted into final Map: Server UUID - List of ExtensionPlayerData at the highest level. - *

- * There are multiple data extraction methods to make extracting the value query easier. - * - * @author Rsl1122 - */ -public class ExtensionPlayerDataQuery implements Query>> { - - private final UUID playerUUID; - - public ExtensionPlayerDataQuery(UUID playerUUID) { - this.playerUUID = playerUUID; - } - - @Override - public Map> executeQuery(SQLDB db) { - Map> extensionsByServerUUID = db.query(ExtensionInformationQueries.allExtensions()); - Map extensionDataByPluginID = db.query(fetchIncompletePlayerDataByPluginID()); - - Map tableDataByPluginID = db.query(new ExtensionPlayerTablesQuery(playerUUID)); - combine(extensionDataByPluginID, tableDataByPluginID); - - return flatMapByServerUUID(extensionsByServerUUID, extensionDataByPluginID); - } - - private void combine( - Map extensionDataByPluginID, - Map aggregates - ) { - for (Map.Entry entry : aggregates.entrySet()) { - Integer pluginID = entry.getKey(); - ExtensionPlayerData.Factory data = entry.getValue(); - - ExtensionPlayerData.Factory found = extensionDataByPluginID.get(pluginID); - if (found == null) { - extensionDataByPluginID.put(pluginID, data); - } else { - found.combine(data); - } - } - } - - private Map> flatMapByServerUUID(Map> extensionsByServerUUID, Map extensionDataByPluginID) { - Map> extensionDataByServerUUID = new HashMap<>(); - - for (Map.Entry> entry : extensionsByServerUUID.entrySet()) { - UUID serverUUID = entry.getKey(); - for (ExtensionInformation extensionInformation : entry.getValue()) { - ExtensionPlayerData.Factory data = extensionDataByPluginID.get(extensionInformation.getId()); - if (data == null) { - continue; - } - List list = extensionDataByServerUUID.getOrDefault(serverUUID, new ArrayList<>()); - list.add(data.setInformation(extensionInformation).build()); - extensionDataByServerUUID.put(serverUUID, list); - } - } - return extensionDataByServerUUID; - } - - private Query> fetchIncompletePlayerDataByPluginID() { - String sql = SELECT + - "v1." + ExtensionPlayerValueTable.BOOLEAN_VALUE + " as boolean_value," + - "v1." + ExtensionPlayerValueTable.DOUBLE_VALUE + " as double_value," + - "v1." + ExtensionPlayerValueTable.PERCENTAGE_VALUE + " as percentage_value," + - "v1." + ExtensionPlayerValueTable.LONG_VALUE + " as long_value," + - "v1." + ExtensionPlayerValueTable.STRING_VALUE + " as string_value," + - "p1." + ExtensionProviderTable.PLUGIN_ID + " as plugin_id," + - "p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," + - "p1." + ExtensionProviderTable.TEXT + " as text," + - "p1." + ExtensionProviderTable.DESCRIPTION + " as description," + - "p1." + ExtensionProviderTable.PRIORITY + " as provider_priority," + - "p1." + ExtensionProviderTable.FORMAT_TYPE + " as format_type," + - "p1." + ExtensionProviderTable.IS_PLAYER_NAME + " as is_player_name," + - "t1." + ExtensionTabTable.TAB_NAME + " as tab_name," + - "t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," + - "t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," + - "i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," + - "i1." + ExtensionIconTable.FAMILY + " as provider_icon_family," + - "i1." + ExtensionIconTable.COLOR + " as provider_icon_color," + - "i2." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," + - "i2." + ExtensionIconTable.FAMILY + " as tab_icon_family," + - "i2." + ExtensionIconTable.COLOR + " as tab_icon_color" + - FROM + ExtensionPlayerValueTable.TABLE_NAME + " v1" + - INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=v1." + ExtensionPlayerValueTable.PROVIDER_ID + - LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionProviderTable.TAB_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTabTable.ICON_ID + - WHERE + ExtensionPlayerValueTable.USER_UUID + "=?" + - AND + "p1." + ExtensionProviderTable.HIDDEN + "=?"; - - return new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - statement.setBoolean(2, false); // Don't select hidden values - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map> tabDataByPluginID = extractTabDataByPluginID(set); - return flatMapToPlayerData(tabDataByPluginID); - } - }; - } - - private Map flatMapToPlayerData(Map> tabDataByPluginID) { - Map dataByPluginID = new HashMap<>(); - for (Map.Entry> entry : tabDataByPluginID.entrySet()) { - Integer pluginID = entry.getKey(); - ExtensionPlayerData.Factory data = dataByPluginID.getOrDefault(pluginID, new ExtensionPlayerData.Factory(pluginID)); - for (ExtensionTabData.Factory tabData : entry.getValue().values()) { - data.addTab(tabData.build()); - } - dataByPluginID.put(pluginID, data); - } - return dataByPluginID; - } - - private Map> extractTabDataByPluginID(ResultSet set) throws SQLException { - Map> tabDataByPluginID = new HashMap<>(); - - while (set.next()) { - int pluginID = set.getInt("plugin_id"); - Map tabData = tabDataByPluginID.getOrDefault(pluginID, new HashMap<>()); - - String tabName = Optional.ofNullable(set.getString("tab_name")).orElse(""); - ExtensionTabData.Factory inMap = tabData.get(tabName); - ExtensionTabData.Factory extensionTab = inMap != null ? inMap : extractTab(tabName, set, tabData); - - ExtensionDescriptive extensionDescriptive = extractDescriptive(set); - extractAndPutDataTo(extensionTab, extensionDescriptive, set); - - tabData.put(tabName, extensionTab); - tabDataByPluginID.put(pluginID, tabData); - } - return tabDataByPluginID; - } - - private void extractAndPutDataTo(ExtensionTabData.Factory extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException { - boolean booleanValue = set.getBoolean(ExtensionPlayerValueTable.BOOLEAN_VALUE); - if (!set.wasNull()) { - extensionTab.putBooleanData(new ExtensionBooleanData(descriptive, booleanValue)); - return; - } - - double doubleValue = set.getDouble(ExtensionPlayerValueTable.DOUBLE_VALUE); - if (!set.wasNull()) { - extensionTab.putDoubleData(new ExtensionDoubleData(descriptive, doubleValue)); - return; - } - - double percentageValue = set.getDouble(ExtensionPlayerValueTable.PERCENTAGE_VALUE); - if (!set.wasNull()) { - extensionTab.putPercentageData(new ExtensionDoubleData(descriptive, percentageValue)); - return; - } - - long numberValue = set.getLong(ExtensionPlayerValueTable.LONG_VALUE); - if (!set.wasNull()) { - FormatType formatType = FormatType.getByName(set.getString(ExtensionProviderTable.FORMAT_TYPE)).orElse(FormatType.NONE); - extensionTab.putNumberData(new ExtensionNumberData(descriptive, formatType, numberValue)); - return; - } - - String stringValue = set.getString(ExtensionPlayerValueTable.STRING_VALUE); - if (stringValue != null) { - boolean isPlayerName = set.getBoolean("is_player_name"); - extensionTab.putStringData(new ExtensionStringData(descriptive, isPlayerName, stringValue)); - } - } - - private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException { - String name = set.getString("provider_name"); - String text = set.getString(ExtensionProviderTable.TEXT); - String description = set.getString(ExtensionProviderTable.DESCRIPTION); - int priority = set.getInt("provider_priority"); - - String iconName = set.getString("provider_icon_name"); - Family family = Family.getByName(set.getString("provider_icon_family")).orElse(Family.SOLID); - Color color = Color.getByName(set.getString("provider_icon_color")).orElse(Color.NONE); - Icon icon = new Icon(family, iconName, color); - - return new ExtensionDescriptive(name, text, description, icon, priority); - } - - private ExtensionTabData.Factory extractTab(String tabName, ResultSet set, Map tabData) throws SQLException { - Optional tabPriority = Optional.of(set.getInt("tab_priority")); - if (set.wasNull()) { - tabPriority = Optional.empty(); - } - Optional elementOrder = Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize); - - Icon tabIcon = extractTabIcon(set); - - return tabData.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation( - tabName, - tabIcon, - elementOrder.orElse(ElementOrder.values()), - tabPriority.orElse(100) - ))); - } - - private Icon extractTabIcon(ResultSet set) throws SQLException { - Optional iconName = Optional.ofNullable(set.getString("tab_icon_name")); - if (iconName.isPresent()) { - Family iconFamily = Family.getByName(set.getString("tab_icon_family")).orElse(Family.SOLID); - Color iconColor = Color.getByName(set.getString("tab_icon_color")).orElse(Color.NONE); - return new Icon(iconFamily, iconName.get(), iconColor); - } else { - return TabInformation.defaultIcon(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerTablesQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerTablesQuery.java deleted file mode 100644 index d106195c8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerTablesQuery.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPlayerTableValueTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTabTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable; -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.TabInformation; -import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; -import com.djrapitops.plan.extension.implementation.results.ExtensionTableData; -import com.djrapitops.plan.extension.implementation.results.player.ExtensionPlayerData; -import com.djrapitops.plan.extension.table.Table; -import com.djrapitops.plan.extension.table.TableAccessor; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Query player tables from tableprovider table. - *

- * Returns Map: PluginID - ExtensionPlayerData.Factory. - *

- * How it is done: - * - TableProviders are queried and formed into Table.Factory objects sorted into a multi-map: PluginID - TableID - Table.Factory - * - Table values are queried and merged into the above multimap - * - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data - * - (Tab Name can be empty.) - * - Multi-map is sorted into ExtensionPlayerData objects by PluginID, one per ID - *

- * There are multiple data extraction methods to make extracting the value query easier. - * - * @author Rsl1122 - */ -public class ExtensionPlayerTablesQuery implements Query> { - - private final UUID playerUUID; - - public ExtensionPlayerTablesQuery(UUID playerUUID) { - this.playerUUID = playerUUID; - } - - private static Map flatMapByPluginID(Map> tabDataByPluginID) { - Map dataByPluginID = new HashMap<>(); - for (Map.Entry> entry : tabDataByPluginID.entrySet()) { - Integer pluginID = entry.getKey(); - ExtensionPlayerData.Factory data = dataByPluginID.getOrDefault(pluginID, new ExtensionPlayerData.Factory(pluginID)); - for (ExtensionTabData.Factory tabData : entry.getValue().values()) { - data.addTab(tabData.build()); - } - dataByPluginID.put(pluginID, data); - } - return dataByPluginID; - } - - @Override - public Map executeQuery(SQLDB db) { - Map> tablesByPluginIDAndTableID = db.query(queryTableProviders()); - Map> tablesWithValues = db.query(queryTableValues(tablesByPluginIDAndTableID)); - - Map> tabDataByPluginID = mapToTabsByPluginID(tablesWithValues); - return flatMapByPluginID(tabDataByPluginID); - } - - /** - * @param tablesByPluginIDAndTableID {@code >} - * @return {@code } - */ - private Map> mapToTabsByPluginID(Map> tablesByPluginIDAndTableID) { - Map> byPluginID = new HashMap<>(); - - for (Map.Entry> entry : tablesByPluginIDAndTableID.entrySet()) { - Integer pluginID = entry.getKey(); - Map byTabName = byPluginID.getOrDefault(pluginID, new HashMap<>()); - for (Table.Factory table : entry.getValue().values()) { - // Extra Table information - String tableName = TableAccessor.getTableName(table); - Color tableColor = TableAccessor.getColor(table); - - // Extra tab information - String tabName = TableAccessor.getTabName(table); - int tabPriority = TableAccessor.getTabPriority(table); - ElementOrder[] tabOrder = TableAccessor.getTabOrder(table); - Icon tabIcon = TableAccessor.getTabIcon(table); - - ExtensionTabData.Factory tab = byTabName.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation(tabName, tabIcon, tabOrder, tabPriority))); - tab.putTableData(new ExtensionTableData( - tableName, table.build(), tableColor - )); - byTabName.put(tabName, tab); - } - byPluginID.put(pluginID, byTabName); - } - - return byPluginID; - } - - // Map: > - private Query>> queryTableValues(Map> tables) { - String selectTableValues = SELECT + - ExtensionTableProviderTable.PLUGIN_ID + ',' + - ExtensionPlayerTableValueTable.TABLE_ID + ',' + - ExtensionPlayerTableValueTable.VALUE_1 + ',' + - ExtensionPlayerTableValueTable.VALUE_2 + ',' + - ExtensionPlayerTableValueTable.VALUE_3 + ',' + - ExtensionPlayerTableValueTable.VALUE_4 + - FROM + ExtensionPlayerTableValueTable.TABLE_NAME + - INNER_JOIN + ExtensionTableProviderTable.TABLE_NAME + " on " + ExtensionTableProviderTable.TABLE_NAME + '.' + ExtensionTableProviderTable.ID + '=' + ExtensionPlayerTableValueTable.TABLE_NAME + '.' + ExtensionPlayerTableValueTable.TABLE_ID + - WHERE + ExtensionPlayerTableValueTable.USER_UUID + "=?"; - - return new QueryStatement>>(selectTableValues, 10000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - while (set.next()) { - Table.Factory table = getTable(set); - if (table == null) { - continue; - } - - Object[] row = extractTableRow(set); - if (row.length > 0) { - table.addRow(row); - } - } - return tables; - } - - private Table.Factory getTable(ResultSet set) throws SQLException { - int pluginID = set.getInt(ExtensionTableProviderTable.PLUGIN_ID); - Map byTableID = tables.get(pluginID); - if (byTableID == null) { - return null; - } - int tableID = set.getInt(ExtensionPlayerTableValueTable.TABLE_ID); - return byTableID.get(tableID); - } - }; - } - - private Object[] extractTableRow(ResultSet set) throws SQLException { - List row = new ArrayList<>(); - for (int i = 1; i <= 5; i++) { - String columnName = "col_" + i + "_value"; // See ExtensionPlayerTableValueTable.VALUE_1 - String value = set.getString(columnName); - if (value == null) { - return row.toArray(new Object[0]); - } - row.add(value); - } - return row.toArray(new Object[0]); - } - - // Map: > - private Query>> queryTableProviders() { - String selectTables = SELECT + - "p1." + ExtensionTableProviderTable.ID + " as table_id," + - "p1." + ExtensionTableProviderTable.PLUGIN_ID + " as plugin_id," + - "p1." + ExtensionTableProviderTable.PROVIDER_NAME + " as table_name," + - "p1." + ExtensionTableProviderTable.COLOR + " as table_color," + - ExtensionTableProviderTable.COL_1 + ',' + - ExtensionTableProviderTable.COL_2 + ',' + - ExtensionTableProviderTable.COL_3 + ',' + - ExtensionTableProviderTable.COL_4 + ',' + - "t1." + ExtensionTabTable.TAB_NAME + " as tab_name," + - "t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," + - "t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," + - "i1." + ExtensionIconTable.ICON_NAME + " as i1_name," + - "i1." + ExtensionIconTable.FAMILY + " as i1_family," + - "i1." + ExtensionIconTable.COLOR + " as i1_color," + - "i2." + ExtensionIconTable.ICON_NAME + " as i2_name," + - "i2." + ExtensionIconTable.FAMILY + " as i2_family," + - "i2." + ExtensionIconTable.COLOR + " as i2_color," + - "i3." + ExtensionIconTable.ICON_NAME + " as i3_name," + - "i3." + ExtensionIconTable.FAMILY + " as i3_family," + - "i3." + ExtensionIconTable.COLOR + " as i3_color," + - "i4." + ExtensionIconTable.ICON_NAME + " as i4_name," + - "i4." + ExtensionIconTable.FAMILY + " as i4_family," + - "i4." + ExtensionIconTable.COLOR + " as i4_color," + - "i6." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," + - "i6." + ExtensionIconTable.FAMILY + " as tab_icon_family," + - "i6." + ExtensionIconTable.COLOR + " as tab_icon_color" + - FROM + ExtensionTableProviderTable.TABLE_NAME + " p1" + - INNER_JOIN + ExtensionPlayerTableValueTable.TABLE_NAME + " v1 on v1." + ExtensionPlayerTableValueTable.TABLE_ID + "=p1." + ExtensionTableProviderTable.ID + - LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionTableProviderTable.TAB_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_1_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_2_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i3 on i3." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_3_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i4 on i4." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_4_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i6 on i6." + ExtensionIconTable.ID + "=t1." + ExtensionTabTable.ICON_ID + - WHERE + "v1." + ExtensionPlayerTableValueTable.USER_UUID + "=?"; - - return new QueryStatement>>(selectTables, 100) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, playerUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> byPluginID = new HashMap<>(); - - while (set.next()) { - int pluginID = set.getInt("plugin_id"); - Map byTableID = byPluginID.getOrDefault(pluginID, new HashMap<>()); - - int tableID = set.getInt("table_id"); - Table.Factory table = Table.builder(); - - extractColumns(set, table); - - TableAccessor.setColor(table, Color.getByName(set.getString("table_color")).orElse(Color.NONE)); - TableAccessor.setTableName(table, set.getString("table_name")); - TableAccessor.setTabName(table, Optional.ofNullable(set.getString("tab_name")).orElse("")); - TableAccessor.setTabPriority(table, Optional.of(set.getInt("tab_priority")).orElse(100)); - TableAccessor.setTabOrder(table, Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize).orElse(ElementOrder.values())); - TableAccessor.setTabIcon(table, extractIcon(set, "tab_icon")); - - byTableID.put(tableID, table); - byPluginID.put(pluginID, byTableID); - } - - return byPluginID; - } - }; - } - - private void extractColumns(ResultSet set, Table.Factory table) throws SQLException { - String col1 = set.getString(ExtensionTableProviderTable.COL_1); - if (col1 != null) { - table.columnOne(col1, extractIcon(set, "i1")); - } - String col2 = set.getString(ExtensionTableProviderTable.COL_2); - if (col2 != null) { - table.columnTwo(col2, extractIcon(set, "i2")); - } - String col3 = set.getString(ExtensionTableProviderTable.COL_3); - if (col3 != null) { - table.columnThree(col3, extractIcon(set, "i3")); - } - String col4 = set.getString(ExtensionTableProviderTable.COL_4); - if (col4 != null) { - table.columnFour(col4, extractIcon(set, "i4")); - } - } - - private Icon extractIcon(ResultSet set, String iconColumnName) throws SQLException { - String iconName = set.getString(iconColumnName + "_name"); - if (iconName == null) { - return null; - } - return new Icon( - Family.getByName(set.getString(iconColumnName + "_family")).orElse(Family.SOLID), - iconName, - Color.getByName(set.getString(iconColumnName + "_color")).orElse(Color.NONE) - ); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerDataQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerDataQuery.java deleted file mode 100644 index a88d91ced..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerDataQuery.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.TabInformation; -import com.djrapitops.plan.extension.implementation.results.*; -import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Query ExtensionServerData of a server. - *

- * Returns List of ExtensionServerData. - *

- * How it is done: - * - Two queries are run, one that fetches all extensions and one that fetches all data of the player. - * - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data - * - (Tab Name can be empty.) - * - Multi-map is sorted into ExtensionServerData objects by PluginID, one per ID - * - This map is combined with similar maps that contain aggregated player values - * - This map is sorted into List of ExtensionPlayerData at the highest level. - *

- * There are multiple data extraction methods to make extracting the value query easier. - * - * @author Rsl1122 - */ -public class ExtensionServerDataQuery implements Query> { - - private final UUID serverUUID; - - public ExtensionServerDataQuery(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - static Map flatMapToServerData(Map> tabDataByPluginID) { - Map dataByPluginID = new HashMap<>(); - for (Map.Entry> entry : tabDataByPluginID.entrySet()) { - Integer pluginID = entry.getKey(); - ExtensionServerData.Factory data = dataByPluginID.getOrDefault(pluginID, new ExtensionServerData.Factory(pluginID)); - for (ExtensionTabData.Factory tabData : entry.getValue().values()) { - data.addTab(tabData.build()); - } - dataByPluginID.put(pluginID, data); - } - return dataByPluginID; - } - - @Override - public List executeQuery(SQLDB db) { - List extensionsOfServer = db.query(ExtensionInformationQueries.extensionsOfServer(serverUUID)); - Map extensionDataByPluginID = db.query(fetchIncompleteServerDataByPluginID()); - - combine(extensionDataByPluginID, db.query(new ExtensionAggregateBooleansQuery(serverUUID))); - combine(extensionDataByPluginID, db.query(new ExtensionAggregateDoublesQuery(serverUUID))); - combine(extensionDataByPluginID, db.query(new ExtensionAggregateNumbersQuery(serverUUID))); - combine(extensionDataByPluginID, db.query(new ExtensionAggregatePercentagesQuery(serverUUID))); - combine(extensionDataByPluginID, db.query(new ExtensionServerTablesQuery(serverUUID))); - - return combineWithExtensionInfo(extensionsOfServer, extensionDataByPluginID); - } - - private void combine( - Map extensionDataByPluginID, - Map aggregates - ) { - for (Map.Entry entry : aggregates.entrySet()) { - Integer pluginID = entry.getKey(); - ExtensionServerData.Factory data = entry.getValue(); - - ExtensionServerData.Factory found = extensionDataByPluginID.get(pluginID); - if (found == null) { - extensionDataByPluginID.put(pluginID, data); - } else { - found.combine(data); - } - } - } - - private List combineWithExtensionInfo( - List extensionsOfServer, - Map extensionDataByPluginID - ) { - List extensionServerData = new ArrayList<>(); - - for (ExtensionInformation extensionInformation : extensionsOfServer) { - ExtensionServerData.Factory data = extensionDataByPluginID.get(extensionInformation.getId()); - if (data == null) { - continue; - } - extensionServerData.add(data.setInformation(extensionInformation).build()); - } - return extensionServerData; - } - - private Query> fetchIncompleteServerDataByPluginID() { - String sql = SELECT + - "v1." + ExtensionServerValueTable.BOOLEAN_VALUE + " as boolean_value," + - "v1." + ExtensionServerValueTable.DOUBLE_VALUE + " as double_value," + - "v1." + ExtensionServerValueTable.PERCENTAGE_VALUE + " as percentage_value," + - "v1." + ExtensionServerValueTable.LONG_VALUE + " as long_value," + - "v1." + ExtensionServerValueTable.STRING_VALUE + " as string_value," + - "p1." + ExtensionProviderTable.PLUGIN_ID + " as plugin_id," + - "p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," + - "p1." + ExtensionProviderTable.TEXT + " as text," + - "p1." + ExtensionProviderTable.DESCRIPTION + " as description," + - "p1." + ExtensionProviderTable.PRIORITY + " as provider_priority," + - "p1." + ExtensionProviderTable.FORMAT_TYPE + " as format_type," + - "p1." + ExtensionProviderTable.IS_PLAYER_NAME + " as is_player_name," + - "t1." + ExtensionTabTable.TAB_NAME + " as tab_name," + - "t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," + - "t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," + - "i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," + - "i1." + ExtensionIconTable.FAMILY + " as provider_icon_family," + - "i1." + ExtensionIconTable.COLOR + " as provider_icon_color," + - "i2." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," + - "i2." + ExtensionIconTable.FAMILY + " as tab_icon_family," + - "i2." + ExtensionIconTable.COLOR + " as tab_icon_color" + - FROM + ExtensionServerValueTable.TABLE_NAME + " v1" + - INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=v1." + ExtensionServerValueTable.PROVIDER_ID + - INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on p1." + ExtensionProviderTable.PLUGIN_ID + "=e1." + ExtensionPluginTable.ID + - LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionProviderTable.TAB_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTabTable.ICON_ID + - WHERE + ExtensionPluginTable.SERVER_UUID + "=?" + - AND + "p1." + ExtensionProviderTable.HIDDEN + "=?"; - - return new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - statement.setBoolean(2, false); // Don't select hidden values - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - Map> tabDataByPluginID = extractTabDataByPluginID(set); - return flatMapToServerData(tabDataByPluginID); - } - }; - } - - private Map> extractTabDataByPluginID(ResultSet set) throws SQLException { - Map> tabDataByPluginID = new HashMap<>(); - - while (set.next()) { - int pluginID = set.getInt("plugin_id"); - Map tabData = tabDataByPluginID.getOrDefault(pluginID, new HashMap<>()); - - String tabName = Optional.ofNullable(set.getString("tab_name")).orElse(""); - ExtensionTabData.Factory inMap = tabData.get(tabName); - ExtensionTabData.Factory extensionTab = inMap != null ? inMap : extractTab(tabName, set, tabData); - - ExtensionDescriptive extensionDescriptive = extractDescriptive(set); - extractAndPutDataTo(extensionTab, extensionDescriptive, set); - - tabData.put(tabName, extensionTab); - tabDataByPluginID.put(pluginID, tabData); - } - return tabDataByPluginID; - } - - private void extractAndPutDataTo(ExtensionTabData.Factory extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException { - boolean booleanValue = set.getBoolean(ExtensionServerValueTable.BOOLEAN_VALUE); - if (!set.wasNull()) { - extensionTab.putBooleanData(new ExtensionBooleanData(descriptive, booleanValue)); - return; - } - - double doubleValue = set.getDouble(ExtensionServerValueTable.DOUBLE_VALUE); - if (!set.wasNull()) { - extensionTab.putDoubleData(new ExtensionDoubleData(descriptive, doubleValue)); - return; - } - - double percentageValue = set.getDouble(ExtensionServerValueTable.PERCENTAGE_VALUE); - if (!set.wasNull()) { - extensionTab.putPercentageData(new ExtensionDoubleData(descriptive, percentageValue)); - return; - } - - long numberValue = set.getLong(ExtensionServerValueTable.LONG_VALUE); - if (!set.wasNull()) { - FormatType formatType = FormatType.getByName(set.getString(ExtensionProviderTable.FORMAT_TYPE)).orElse(FormatType.NONE); - extensionTab.putNumberData(new ExtensionNumberData(descriptive, formatType, numberValue)); - return; - } - - String stringValue = set.getString(ExtensionServerValueTable.STRING_VALUE); - if (stringValue != null) { - boolean isPlayerName = set.getBoolean("is_player_name"); - extensionTab.putStringData(new ExtensionStringData(descriptive, isPlayerName, stringValue)); - } - } - - private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException { - String name = set.getString("provider_name"); - String text = set.getString(ExtensionProviderTable.TEXT); - String description = set.getString(ExtensionProviderTable.DESCRIPTION); - int priority = set.getInt("provider_priority"); - - String iconName = set.getString("provider_icon_name"); - Family family = Family.getByName(set.getString("provider_icon_family")).orElse(Family.SOLID); - Color color = Color.getByName(set.getString("provider_icon_color")).orElse(Color.NONE); - Icon icon = new Icon(family, iconName, color); - - return new ExtensionDescriptive(name, text, description, icon, priority); - } - - private ExtensionTabData.Factory extractTab(String tabName, ResultSet set, Map tabData) throws SQLException { - Optional tabPriority = Optional.of(set.getInt("tab_priority")); - if (set.wasNull()) { - tabPriority = Optional.empty(); - } - Optional elementOrder = Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize); - - Icon tabIcon = extractTabIcon(set); - - return tabData.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation( - tabName, - tabIcon, - elementOrder.orElse(ElementOrder.values()), - tabPriority.orElse(100) - ))); - } - - private Icon extractTabIcon(ResultSet set) throws SQLException { - Optional iconName = Optional.ofNullable(set.getString("tab_icon_name")); - if (iconName.isPresent()) { - Family iconFamily = Family.getByName(set.getString("tab_icon_family")).orElse(Family.SOLID); - Color iconColor = Color.getByName(set.getString("tab_icon_color")).orElse(Color.NONE); - return new Icon(iconFamily, iconName.get(), iconColor); - } else { - return TabInformation.defaultIcon(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerPlayerDataTableQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerPlayerDataTableQuery.java deleted file mode 100644 index 8a4954064..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerPlayerDataTableQuery.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.*; -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.results.*; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Query Extension data of x most recent players on a server. - *

- * Returns Map: Player UUID - ExtensionTabData (container for provider based data) - * - * @author Rsl1122 - */ -public class ExtensionServerPlayerDataTableQuery implements Query> { - - private final UUID serverUUID; - private final int xMostRecentPlayers; - - public ExtensionServerPlayerDataTableQuery(UUID serverUUID, int xMostRecentPlayers) { - this.serverUUID = serverUUID; - this.xMostRecentPlayers = xMostRecentPlayers; - } - - @Override - public Map executeQuery(SQLDB db) { - return db.query(fetchIncompletePlayerDataByPluginID()); - } - - private Query> fetchIncompletePlayerDataByPluginID() { - String selectLimitedNumberOfPlayerUUIDsByLastSeenDate = SELECT + - SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_UUID + - ",MAX(" + SessionsTable.SESSION_END + ") as last_seen" + - FROM + SessionsTable.TABLE_NAME + - GROUP_BY + SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_UUID + ',' + SessionsTable.SESSION_END + - ORDER_BY + SessionsTable.SESSION_END + " DESC LIMIT ?"; - - String sql = SELECT + - "v1." + ExtensionPlayerValueTable.USER_UUID + " as uuid," + - "v1." + ExtensionPlayerValueTable.BOOLEAN_VALUE + " as boolean_value," + - "v1." + ExtensionPlayerValueTable.DOUBLE_VALUE + " as double_value," + - "v1." + ExtensionPlayerValueTable.PERCENTAGE_VALUE + " as percentage_value," + - "v1." + ExtensionPlayerValueTable.LONG_VALUE + " as long_value," + - "v1." + ExtensionPlayerValueTable.STRING_VALUE + " as string_value," + - "p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," + - "p1." + ExtensionProviderTable.TEXT + " as text," + - "p1." + ExtensionProviderTable.FORMAT_TYPE + " as format_type," + - "p1." + ExtensionProviderTable.IS_PLAYER_NAME + " as is_player_name," + - "i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," + - "i1." + ExtensionIconTable.FAMILY + " as provider_icon_family" + - FROM + ExtensionPlayerValueTable.TABLE_NAME + " v1" + - INNER_JOIN + '(' + selectLimitedNumberOfPlayerUUIDsByLastSeenDate + ") as last_seen_q on last_seen_q.uuid=v1." + ExtensionPlayerValueTable.USER_UUID + - INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=v1." + ExtensionPlayerValueTable.PROVIDER_ID + - INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on e1." + ExtensionPluginTable.ID + "=p1." + ExtensionProviderTable.PLUGIN_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID + - WHERE + "e1." + ExtensionPluginTable.SERVER_UUID + "=?" + - AND + "p1." + ExtensionProviderTable.SHOW_IN_PLAYERS_TABLE + "=?" + - AND + "p1." + ExtensionProviderTable.IS_PLAYER_NAME + "=?"; - - return new QueryStatement>(sql, 1000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setInt(1, xMostRecentPlayers); // Limit to x most recently seen players - statement.setString(2, serverUUID.toString()); - statement.setBoolean(3, true); // Select only values that should be shown - statement.setBoolean(4, false); // Don't select player_name String values - } - - @Override - public Map processResults(ResultSet set) throws SQLException { - return extractDataByPlayer(set); - } - }; - } - - private Map extractDataByPlayer(ResultSet set) throws SQLException { - Map dataByPlayer = new HashMap<>(); - - while (set.next()) { - UUID playerUUID = UUID.fromString(set.getString("uuid")); - ExtensionTabData.Factory data = dataByPlayer.getOrDefault(playerUUID, new ExtensionTabData.Factory(null)); - - ExtensionDescriptive extensionDescriptive = extractDescriptive(set); - extractAndPutDataTo(data, extensionDescriptive, set); - - dataByPlayer.put(playerUUID, data); - } - return dataByPlayer.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().build())); - } - - private void extractAndPutDataTo(ExtensionTabData.Factory extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException { - boolean booleanValue = set.getBoolean(ExtensionServerValueTable.BOOLEAN_VALUE); - if (!set.wasNull()) { - extensionTab.putBooleanData(new ExtensionBooleanData(descriptive, booleanValue)); - return; - } - - double doubleValue = set.getDouble(ExtensionPlayerValueTable.DOUBLE_VALUE); - if (!set.wasNull()) { - extensionTab.putDoubleData(new ExtensionDoubleData(descriptive, doubleValue)); - return; - } - - double percentageValue = set.getDouble(ExtensionServerValueTable.PERCENTAGE_VALUE); - if (!set.wasNull()) { - extensionTab.putPercentageData(new ExtensionDoubleData(descriptive, percentageValue)); - return; - } - - long numberValue = set.getLong(ExtensionPlayerValueTable.LONG_VALUE); - if (!set.wasNull()) { - FormatType formatType = FormatType.getByName(set.getString(ExtensionProviderTable.FORMAT_TYPE)).orElse(FormatType.NONE); - extensionTab.putNumberData(new ExtensionNumberData(descriptive, formatType, numberValue)); - return; - } - - String stringValue = set.getString(ExtensionPlayerValueTable.STRING_VALUE); - if (stringValue != null) { - boolean isPlayerName = false; - extensionTab.putStringData(new ExtensionStringData(descriptive, isPlayerName, stringValue)); - } - } - - private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException { - String name = set.getString("provider_name"); - String text = set.getString(ExtensionProviderTable.TEXT); - - String iconName = set.getString("provider_icon_name"); - Family family = Family.getByName(set.getString("provider_icon_family")).orElse(Family.SOLID); - Icon icon = new Icon(family, iconName, Color.NONE); - - return new ExtensionDescriptive(name, text, null, icon, 0); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerTablesQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerTablesQuery.java deleted file mode 100644 index 047b7b2be..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerTablesQuery.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.queries; - -import com.djrapitops.plan.db.SQLDB; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.QueryStatement; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionServerTableValueTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTabTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable; -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Family; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.TabInformation; -import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; -import com.djrapitops.plan.extension.implementation.results.ExtensionTableData; -import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData; -import com.djrapitops.plan.extension.table.Table; -import com.djrapitops.plan.extension.table.TableAccessor; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Query server tables from tableprovider table. - *

- * Returns Map: PluginID - ExtensionServerData.Factory. - *

- * How it is done: - * - TableProviders are queried and formed into Table.Factory objects sorted into a multi-map: PluginID - TableID - Table.Factory - * - Table values are queried and merged into the above multimap - * - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data - * - (Tab Name can be empty.) - * - Multi-map is sorted into ExtensionServerData objects by PluginID, one per ID - *

- * There are multiple data extraction methods to make extracting the value query easier. - * - * @author Rsl1122 - */ -public class ExtensionServerTablesQuery implements Query> { - - private final UUID serverUUID; - - public ExtensionServerTablesQuery(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - @Override - public Map executeQuery(SQLDB db) { - Map> tablesByPluginIDAndTableID = db.query(queryTableProviders()); - Map> tablesWithValues = db.query(queryTableValues(tablesByPluginIDAndTableID)); - - Map> tabDataByPluginID = mapToTabsByPluginID(tablesWithValues); - return ExtensionServerDataQuery.flatMapToServerData(tabDataByPluginID); - } - - /** - * @param tablesByPluginIDAndTableID {@code >} - * @return {@code } - */ - private Map> mapToTabsByPluginID(Map> tablesByPluginIDAndTableID) { - Map> byPluginID = new HashMap<>(); - - for (Map.Entry> entry : tablesByPluginIDAndTableID.entrySet()) { - Integer pluginID = entry.getKey(); - Map byTabName = byPluginID.getOrDefault(pluginID, new HashMap<>()); - for (Table.Factory table : entry.getValue().values()) { - // Extra Table information - String tableName = TableAccessor.getTableName(table); - Color tableColor = TableAccessor.getColor(table); - - // Extra tab information - String tabName = TableAccessor.getTabName(table); - int tabPriority = TableAccessor.getTabPriority(table); - ElementOrder[] tabOrder = TableAccessor.getTabOrder(table); - Icon tabIcon = TableAccessor.getTabIcon(table); - - ExtensionTabData.Factory tab = byTabName.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation(tabName, tabIcon, tabOrder, tabPriority))); - tab.putTableData(new ExtensionTableData( - tableName, table.build(), tableColor - )); - byTabName.put(tabName, tab); - } - byPluginID.put(pluginID, byTabName); - } - - return byPluginID; - } - - // Map: > - private Query>> queryTableValues(Map> tables) { - String selectTableValues = SELECT + - ExtensionTableProviderTable.PLUGIN_ID + ',' + - ExtensionServerTableValueTable.TABLE_ID + ',' + - ExtensionServerTableValueTable.VALUE_1 + ',' + - ExtensionServerTableValueTable.VALUE_2 + ',' + - ExtensionServerTableValueTable.VALUE_3 + ',' + - ExtensionServerTableValueTable.VALUE_4 + ',' + - ExtensionServerTableValueTable.VALUE_5 + - FROM + ExtensionServerTableValueTable.TABLE_NAME + - INNER_JOIN + ExtensionTableProviderTable.TABLE_NAME + " on " + ExtensionTableProviderTable.TABLE_NAME + '.' + ExtensionTableProviderTable.ID + '=' + ExtensionServerTableValueTable.TABLE_NAME + '.' + ExtensionServerTableValueTable.TABLE_ID + - WHERE + ExtensionServerTableValueTable.SERVER_UUID + "=?"; - - return new QueryStatement>>(selectTableValues, 10000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - while (set.next()) { - Table.Factory table = getTable(set); - if (table == null) { - continue; - } - - Object[] row = extractTableRow(set); - if (row.length > 0) { - table.addRow(row); - } - } - return tables; - } - - private Table.Factory getTable(ResultSet set) throws SQLException { - int pluginID = set.getInt(ExtensionTableProviderTable.PLUGIN_ID); - Map byTableID = tables.get(pluginID); - if (byTableID == null) { - return null; - } - int tableID = set.getInt(ExtensionServerTableValueTable.TABLE_ID); - return byTableID.get(tableID); - } - }; - } - - private Object[] extractTableRow(ResultSet set) throws SQLException { - List row = new ArrayList<>(); - for (int i = 1; i <= 5; i++) { - String columnName = "col_" + i + "_value"; // See ExtensionServerTableValueTable.VALUE_1 - String value = set.getString(columnName); - if (value == null) { - return row.toArray(new Object[0]); - } - row.add(value); - } - return row.toArray(new Object[0]); - } - - // Map: > - private Query>> queryTableProviders() { - String selectTables = SELECT + - "p1." + ExtensionTableProviderTable.ID + " as table_id," + - "p1." + ExtensionTableProviderTable.PLUGIN_ID + " as plugin_id," + - "p1." + ExtensionTableProviderTable.PROVIDER_NAME + " as table_name," + - "p1." + ExtensionTableProviderTable.COLOR + " as table_color," + - ExtensionTableProviderTable.COL_1 + ',' + - ExtensionTableProviderTable.COL_2 + ',' + - ExtensionTableProviderTable.COL_3 + ',' + - ExtensionTableProviderTable.COL_4 + ',' + - ExtensionTableProviderTable.COL_5 + ',' + - "t1." + ExtensionTabTable.TAB_NAME + " as tab_name," + - "t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," + - "t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," + - "i1." + ExtensionIconTable.ICON_NAME + " as i1_name," + - "i1." + ExtensionIconTable.FAMILY + " as i1_family," + - "i1." + ExtensionIconTable.COLOR + " as i1_color," + - "i2." + ExtensionIconTable.ICON_NAME + " as i2_name," + - "i2." + ExtensionIconTable.FAMILY + " as i2_family," + - "i2." + ExtensionIconTable.COLOR + " as i2_color," + - "i3." + ExtensionIconTable.ICON_NAME + " as i3_name," + - "i3." + ExtensionIconTable.FAMILY + " as i3_family," + - "i3." + ExtensionIconTable.COLOR + " as i3_color," + - "i4." + ExtensionIconTable.ICON_NAME + " as i4_name," + - "i4." + ExtensionIconTable.FAMILY + " as i4_family," + - "i4." + ExtensionIconTable.COLOR + " as i4_color," + - "i5." + ExtensionIconTable.ICON_NAME + " as i5_name," + - "i5." + ExtensionIconTable.FAMILY + " as i5_family," + - "i5." + ExtensionIconTable.COLOR + " as i5_color," + - "i6." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," + - "i6." + ExtensionIconTable.FAMILY + " as tab_icon_family," + - "i6." + ExtensionIconTable.COLOR + " as tab_icon_color" + - FROM + ExtensionTableProviderTable.TABLE_NAME + " p1" + - INNER_JOIN + ExtensionServerTableValueTable.TABLE_NAME + " v1 on v1." + ExtensionServerTableValueTable.TABLE_ID + "=p1." + ExtensionTableProviderTable.ID + - LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionTableProviderTable.TAB_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_1_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_2_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i3 on i3." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_3_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i4 on i4." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_4_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i5 on i5." + ExtensionIconTable.ID + "=p1." + ExtensionTableProviderTable.ICON_5_ID + - LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i6 on i6." + ExtensionIconTable.ID + "=t1." + ExtensionTabTable.ICON_ID + - WHERE + "v1." + ExtensionServerTableValueTable.SERVER_UUID + "=?"; - - return new QueryStatement>>(selectTables, 100) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> byPluginID = new HashMap<>(); - - while (set.next()) { - int pluginID = set.getInt("plugin_id"); - Map byTableID = byPluginID.getOrDefault(pluginID, new HashMap<>()); - - int tableID = set.getInt("table_id"); - Table.Factory table = Table.builder(); - - extractColumns(set, table); - - TableAccessor.setColor(table, Color.getByName(set.getString("table_color")).orElse(Color.NONE)); - TableAccessor.setTableName(table, set.getString("table_name")); - TableAccessor.setTabName(table, Optional.ofNullable(set.getString("tab_name")).orElse("")); - TableAccessor.setTabPriority(table, Optional.of(set.getInt("tab_priority")).orElse(100)); - TableAccessor.setTabOrder(table, Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize).orElse(ElementOrder.values())); - TableAccessor.setTabIcon(table, extractIcon(set, "tab_icon")); - - byTableID.put(tableID, table); - byPluginID.put(pluginID, byTableID); - } - - return byPluginID; - } - }; - } - - private void extractColumns(ResultSet set, Table.Factory table) throws SQLException { - String col1 = set.getString(ExtensionTableProviderTable.COL_1); - if (col1 != null) { - table.columnOne(col1, extractIcon(set, "i1")); - } - String col2 = set.getString(ExtensionTableProviderTable.COL_2); - if (col2 != null) { - table.columnTwo(col2, extractIcon(set, "i2")); - } - String col3 = set.getString(ExtensionTableProviderTable.COL_3); - if (col3 != null) { - table.columnThree(col3, extractIcon(set, "i3")); - } - String col4 = set.getString(ExtensionTableProviderTable.COL_4); - if (col4 != null) { - table.columnFour(col4, extractIcon(set, "i4")); - } - String col5 = set.getString(ExtensionTableProviderTable.COL_5); - if (col5 != null) { - table.columnFive(col5, extractIcon(set, "i5")); - } - } - - private Icon extractIcon(ResultSet set, String iconColumnName) throws SQLException { - String iconName = set.getString(iconColumnName + "_name"); - if (iconName == null) { - return null; - } - return new Icon( - Family.getByName(set.getString(iconColumnName + "_family")).orElse(Family.SOLID), - iconName, - Color.getByName(set.getString(iconColumnName + "_color")).orElse(Color.NONE) - ); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StoreIconTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StoreIconTransaction.java deleted file mode 100644 index 05173f089..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StoreIconTransaction.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement; -import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.extension.icon.Icon; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Transaction to store an Icon to the database. - * - * @author Rsl1122 - */ -public class StoreIconTransaction extends Transaction { - - private final Icon icon; - - public StoreIconTransaction(Icon icon) { - this.icon = icon; - } - - @Override - protected void performOperations() { - if (!query(isIconStored())) { - execute(insertIcon()); - } - } - - private Executable insertIcon() { - String sql = "INSERT INTO " + ExtensionIconTable.TABLE_NAME + "(" + - ExtensionIconTable.ICON_NAME + "," + - ExtensionIconTable.FAMILY + "," + - ExtensionIconTable.COLOR + - ") VALUES (?,?,?)"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - ExtensionIconTable.set3IconValuesToStatement(statement, icon); - } - }; - } - - private Query isIconStored() { - String sql = SELECT + "COUNT(1) as c" + - FROM + ExtensionIconTable.TABLE_NAME + - WHERE + ExtensionIconTable.ICON_NAME + "=?" + - AND + ExtensionIconTable.FAMILY + "=?" + - AND + ExtensionIconTable.COLOR + "=?"; - return new HasMoreThanZeroQueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - ExtensionIconTable.set3IconValuesToStatement(statement, icon); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StorePluginTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StorePluginTransaction.java deleted file mode 100644 index f5c2cd897..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StorePluginTransaction.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.extension.icon.Icon; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; - -/** - * Transaction to update command usage information in the database. - * - * @author Rsl1122 - */ -public class StorePluginTransaction extends Transaction { - - private final String pluginName; - private final long time; - private final UUID serverUUID; - private final Icon icon; - - public StorePluginTransaction(String pluginName, long time, UUID serverUUID, Icon icon) { - this.pluginName = pluginName; - this.time = time; - this.serverUUID = serverUUID; - this.icon = icon; - } - - @Override - protected void performOperations() { - execute(storePlugin()); - } - - private Executable storePlugin() { - return connection -> { - if (!updatePlugin().execute(connection)) { - return insertPlugin().execute(connection); - } - return false; - }; - } - - private Executable updatePlugin() { - String sql = "UPDATE " + ExtensionPluginTable.TABLE_NAME + - " SET " + - ExtensionPluginTable.LAST_UPDATED + "=?," + - ExtensionPluginTable.ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + - WHERE + ExtensionPluginTable.PLUGIN_NAME + "=?" + - AND + ExtensionPluginTable.SERVER_UUID + "=?"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, time); - ExtensionIconTable.set3IconValuesToStatement(statement, 2, icon); - statement.setString(5, pluginName); - statement.setString(6, serverUUID.toString()); - } - }; - } - - private Executable insertPlugin() { - String sql = "INSERT INTO " + ExtensionPluginTable.TABLE_NAME + "(" + - ExtensionPluginTable.PLUGIN_NAME + "," + - ExtensionPluginTable.LAST_UPDATED + "," + - ExtensionPluginTable.SERVER_UUID + "," + - ExtensionPluginTable.ICON_ID + - ") VALUES (?,?,?," + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, pluginName); - statement.setLong(2, time); - statement.setString(3, serverUUID.toString()); - ExtensionIconTable.set3IconValuesToStatement(statement, 4, icon); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StoreTabInformationTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StoreTabInformationTransaction.java deleted file mode 100644 index a4c44b37d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/StoreTabInformationTransaction.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTabTable; -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.implementation.TabInformation; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; - -/** - * Transaction for storing {@link TabInformation}s. - * - * @author Rsl1122 - */ -public class StoreTabInformationTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final TabInformation tabInformation; - - public StoreTabInformationTransaction(String pluginName, UUID serverUUID, TabInformation tabInformation) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.tabInformation = tabInformation; - } - - @Override - protected void performOperations() { - execute(storeTab()); - } - - private Executable storeTab() { - return connection -> { - if (!updateTab().execute(connection)) { - return insertTab().execute(connection); - } - return false; - }; - } - - private Executable updateTab() { - String sql = "UPDATE " + ExtensionTabTable.TABLE_NAME + - " SET " + - ExtensionTabTable.TAB_PRIORITY + "=?," + - ExtensionTabTable.ELEMENT_ORDER + "=?," + - ExtensionTabTable.ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + - WHERE + ExtensionTabTable.PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + - AND + ExtensionTabTable.TAB_NAME + "=?"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setInt(1, tabInformation.getTabPriority()); - statement.setString(2, ElementOrder.serialize(tabInformation.getTabElementOrder().orElse(ElementOrder.values()))); - ExtensionIconTable.set3IconValuesToStatement(statement, 3, tabInformation.getTabIcon()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 6, pluginName, serverUUID); - statement.setString(8, tabInformation.getTabName()); - } - }; - } - - private Executable insertTab() { - String sql = "INSERT INTO " + ExtensionTabTable.TABLE_NAME + "(" + - ExtensionTabTable.TAB_NAME + "," + - ExtensionTabTable.ELEMENT_ORDER + "," + - ExtensionTabTable.TAB_PRIORITY + "," + - ExtensionTabTable.ICON_ID + "," + - ExtensionTabTable.PLUGIN_ID + - ") VALUES (?,?,?," + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + "," + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, tabInformation.getTabName()); - statement.setString(2, ElementOrder.serialize(tabInformation.getTabElementOrder().orElse(ElementOrder.values()))); - statement.setInt(3, tabInformation.getTabPriority()); - ExtensionIconTable.set3IconValuesToStatement(statement, 4, tabInformation.getTabIcon()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 7, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreBooleanProviderTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreBooleanProviderTransaction.java deleted file mode 100644 index e7d5dd0a6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreBooleanProviderTransaction.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.providers; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTabTable; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.implementation.providers.DataProvider; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Optional; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionProviderTable.*; - -/** - * Transaction to store information about a {@link com.djrapitops.plan.extension.implementation.providers.BooleanDataProvider}. - * - * @author Rsl1122 - */ -public class StoreBooleanProviderTransaction extends Transaction { - - private final String providedCondition; - private final boolean hidden; - private final UUID serverUUID; - private final ProviderInformation providerInformation; - - public StoreBooleanProviderTransaction(DataProvider booleanProvider, String providedCondition, boolean hidden, UUID serverUUID) { - this.providedCondition = providedCondition; - this.hidden = hidden; - this.serverUUID = serverUUID; - this.providerInformation = booleanProvider.getProviderInformation(); - } - - @Override - protected void performOperations() { - execute(storeProvider()); - } - - private Executable storeProvider() { - return connection -> { - if (!updateProvider().execute(connection)) { - return insertProvider().execute(connection); - } - return false; - }; - } - - private Executable updateProvider() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - TEXT + "=?," + - DESCRIPTION + "=?," + - PRIORITY + "=?," + - CONDITION + "=?," + - PROVIDED_CONDITION + "=?," + - TAB_ID + '=' + ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' + - ICON_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - HIDDEN + "=?," + - SHOW_IN_PLAYERS_TABLE + "=?" + - WHERE + PLUGIN_ID + '=' + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + - AND + PROVIDER_NAME + "=?"; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, providerInformation.getText()); - Optional description = providerInformation.getDescription(); - if (description.isPresent()) { - statement.setString(2, description.get()); - } else { - statement.setNull(2, Types.VARCHAR); - } - statement.setInt(3, providerInformation.getPriority()); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent()) { - statement.setString(4, condition.get()); - } else { - statement.setNull(4, Types.VARCHAR); - } - if (providedCondition != null) { - statement.setString(5, providedCondition); - } else { - statement.setNull(5, Types.VARCHAR); - } - ExtensionTabTable.set3TabValuesToStatement(statement, 6, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 9, providerInformation.getIcon()); - statement.setBoolean(12, hidden); - statement.setBoolean(13, providerInformation.isShownInPlayersTable()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 14, providerInformation.getPluginName(), serverUUID); - statement.setString(16, providerInformation.getName()); - } - }; - } - - private Executable insertProvider() { - String sql = "INSERT INTO " + TABLE_NAME + '(' + - PROVIDER_NAME + ',' + - TEXT + ',' + - DESCRIPTION + ',' + - PRIORITY + ',' + - CONDITION + ',' + - PROVIDED_CONDITION + ',' + - HIDDEN + ',' + - SHOW_IN_PLAYERS_TABLE + ',' + - TAB_ID + ',' + - ICON_ID + ',' + - PLUGIN_ID + - ") VALUES (?,?,?,?,?,?,?,?," + - ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' + - ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ')'; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, providerInformation.getName()); - statement.setString(2, providerInformation.getText()); - Optional description = providerInformation.getDescription(); - if (description.isPresent()) { - statement.setString(3, description.get()); - } else { - statement.setNull(3, Types.VARCHAR); - } - statement.setInt(4, providerInformation.getPriority()); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent()) { - statement.setString(5, condition.get()); - } else { - statement.setNull(5, Types.VARCHAR); - } - if (providedCondition != null) { - statement.setString(6, providedCondition); - } else { - statement.setNull(6, Types.VARCHAR); - } - statement.setBoolean(7, hidden); - statement.setBoolean(8, providerInformation.isShownInPlayersTable()); - ExtensionTabTable.set3TabValuesToStatement(statement, 9, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 12, providerInformation.getIcon()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 15, providerInformation.getPluginName(), serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreDoubleProviderTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreDoubleProviderTransaction.java deleted file mode 100644 index 725da2073..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreDoubleProviderTransaction.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.providers; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTabTable; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.implementation.providers.DataProvider; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Optional; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionProviderTable.*; - -/** - * Transaction to store information about a dobule {@link DataProvider}. - *

- * Includes: - * {@link com.djrapitops.plan.extension.implementation.providers.DoubleDataProvider}. - * {@link com.djrapitops.plan.extension.implementation.providers.PercentageDataProvider}. - * - * @author Rsl1122 - */ -public class StoreDoubleProviderTransaction extends Transaction { - - private final UUID serverUUID; - private final ProviderInformation providerInformation; - - public StoreDoubleProviderTransaction(DataProvider provider, UUID serverUUID) { - this.serverUUID = serverUUID; - this.providerInformation = provider.getProviderInformation(); - } - - @Override - protected void performOperations() { - execute(storeProvider()); - } - - private Executable storeProvider() { - return connection -> { - if (!updateProvider().execute(connection)) { - return insertProvider().execute(connection); - } - return false; - }; - } - - private Executable updateProvider() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - TEXT + "=?," + - DESCRIPTION + "=?," + - PRIORITY + "=?," + - CONDITION + "=?," + - TAB_ID + "=" + ExtensionTabTable.STATEMENT_SELECT_TAB_ID + "," + - ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - SHOW_IN_PLAYERS_TABLE + "=?" + - WHERE + PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + - AND + PROVIDER_NAME + "=?"; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, providerInformation.getText()); - Optional description = providerInformation.getDescription(); - if (description.isPresent()) { - statement.setString(2, description.get()); - } else { - statement.setNull(2, Types.VARCHAR); - } - statement.setInt(3, providerInformation.getPriority()); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent()) { - statement.setString(4, condition.get()); - } else { - statement.setNull(4, Types.VARCHAR); - } - ExtensionTabTable.set3TabValuesToStatement(statement, 5, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 8, providerInformation.getIcon()); - statement.setBoolean(11, providerInformation.isShownInPlayersTable()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 12, providerInformation.getPluginName(), serverUUID); - statement.setString(14, providerInformation.getName()); - } - }; - } - - private Executable insertProvider() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - PROVIDER_NAME + "," + - TEXT + "," + - DESCRIPTION + "," + - PRIORITY + "," + - CONDITION + "," + - SHOW_IN_PLAYERS_TABLE + ',' + - TAB_ID + "," + - ICON_ID + "," + - PLUGIN_ID + - ") VALUES (?,?,?,?,?,?," + - ExtensionTabTable.STATEMENT_SELECT_TAB_ID + "," + - ExtensionIconTable.STATEMENT_SELECT_ICON_ID + "," + - ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, providerInformation.getName()); - statement.setString(2, providerInformation.getText()); - Optional description = providerInformation.getDescription(); - if (description.isPresent()) { - statement.setString(3, description.get()); - } else { - statement.setNull(3, Types.VARCHAR); - } - statement.setInt(4, providerInformation.getPriority()); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent()) { - statement.setString(5, condition.get()); - } else { - statement.setNull(5, Types.VARCHAR); - } - statement.setBoolean(6, providerInformation.isShownInPlayersTable()); - ExtensionTabTable.set3TabValuesToStatement(statement, 7, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 10, providerInformation.getIcon()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 13, providerInformation.getPluginName(), serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreNumberProviderTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreNumberProviderTransaction.java deleted file mode 100644 index c02f1b2fb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreNumberProviderTransaction.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.providers; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTabTable; -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.implementation.providers.DataProvider; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Optional; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionProviderTable.*; - -/** - * Transaction to store information about a {@link com.djrapitops.plan.extension.implementation.providers.NumberDataProvider}. - * - * @author Rsl1122 - */ -@SuppressWarnings("Duplicates") -public class StoreNumberProviderTransaction extends Transaction { - - private final FormatType formatType; - private final UUID serverUUID; - private final ProviderInformation providerInformation; - - public StoreNumberProviderTransaction(DataProvider provider, FormatType formatType, UUID serverUUID) { - this.formatType = formatType; - this.serverUUID = serverUUID; - this.providerInformation = provider.getProviderInformation(); - } - - @Override - protected void performOperations() { - execute(storeProvider()); - } - - private Executable storeProvider() { - return connection -> { - if (!updateProvider().execute(connection)) { - return insertProvider().execute(connection); - } - return false; - }; - } - - private Executable updateProvider() { - String sql = "UPDATE " + TABLE_NAME + " SET " + - TEXT + "=?," + - DESCRIPTION + "=?," + - PRIORITY + "=?," + - CONDITION + "=?," + - SHOW_IN_PLAYERS_TABLE + "=?," + - FORMAT_TYPE + "=?," + - TAB_ID + "=" + ExtensionTabTable.STATEMENT_SELECT_TAB_ID + "," + - ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + - WHERE + PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + - AND + PROVIDER_NAME + "=?"; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, providerInformation.getText()); - Optional description = providerInformation.getDescription(); - if (description.isPresent()) { - statement.setString(2, description.get()); - } else { - statement.setNull(2, Types.VARCHAR); - } - statement.setInt(3, providerInformation.getPriority()); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent()) { - statement.setString(4, condition.get()); - } else { - statement.setNull(4, Types.VARCHAR); - } - statement.setBoolean(5, providerInformation.isShownInPlayersTable()); - statement.setString(6, formatType.name()); - ExtensionTabTable.set3TabValuesToStatement(statement, 7, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 10, providerInformation.getIcon()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 13, providerInformation.getPluginName(), serverUUID); - statement.setString(15, providerInformation.getName()); - } - }; - } - - private Executable insertProvider() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - PROVIDER_NAME + "," + - TEXT + "," + - DESCRIPTION + "," + - PRIORITY + "," + - CONDITION + "," + - SHOW_IN_PLAYERS_TABLE + ',' + - FORMAT_TYPE + "," + - TAB_ID + "," + - ICON_ID + "," + - PLUGIN_ID + - ") VALUES (?,?,?,?,?,?,?," + - ExtensionTabTable.STATEMENT_SELECT_TAB_ID + "," + - ExtensionIconTable.STATEMENT_SELECT_ICON_ID + "," + - ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, providerInformation.getName()); - statement.setString(2, providerInformation.getText()); - Optional description = providerInformation.getDescription(); - if (description.isPresent()) { - statement.setString(3, description.get()); - } else { - statement.setNull(3, Types.VARCHAR); - } - statement.setInt(4, providerInformation.getPriority()); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent()) { - statement.setString(5, condition.get()); - } else { - statement.setNull(5, Types.VARCHAR); - } - statement.setBoolean(6, providerInformation.isShownInPlayersTable()); - statement.setString(7, formatType.name()); - ExtensionTabTable.set3TabValuesToStatement(statement, 8, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 11, providerInformation.getIcon()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 14, providerInformation.getPluginName(), serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreStringProviderTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreStringProviderTransaction.java deleted file mode 100644 index 836b9dc46..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreStringProviderTransaction.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.providers; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTabTable; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.implementation.providers.DataProvider; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Optional; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionProviderTable.*; - -/** - * Transaction to store information about a {@link com.djrapitops.plan.extension.implementation.providers.StringDataProvider}. - * - * @author Rsl1122 - */ -public class StoreStringProviderTransaction extends Transaction { - - private final boolean playerName; - private final UUID serverUUID; - private ProviderInformation providerInformation; - - public StoreStringProviderTransaction(DataProvider provider, boolean playerName, UUID serverUUID) { - this.playerName = playerName; - this.serverUUID = serverUUID; - providerInformation = provider.getProviderInformation(); - } - - @Override - protected void performOperations() { - execute(storeProvider()); - } - - private Executable storeProvider() { - return connection -> { - if (!updateProvider().execute(connection)) { - return insertProvider().execute(connection); - } - return false; - }; - } - - private Executable updateProvider() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - TEXT + "=?," + - DESCRIPTION + "=?," + - PRIORITY + "=?," + - CONDITION + "=?," + - SHOW_IN_PLAYERS_TABLE + "=?," + - IS_PLAYER_NAME + "=?," + - TAB_ID + "=" + ExtensionTabTable.STATEMENT_SELECT_TAB_ID + "," + - ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + - WHERE + PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + - AND + PROVIDER_NAME + "=?"; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, providerInformation.getText()); - Optional description = providerInformation.getDescription(); - if (description.isPresent()) { - statement.setString(2, description.get()); - } else { - statement.setNull(2, Types.VARCHAR); - } - statement.setInt(3, providerInformation.getPriority()); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent()) { - statement.setString(4, condition.get()); - } else { - statement.setNull(4, Types.VARCHAR); - } - statement.setBoolean(5, providerInformation.isShownInPlayersTable()); - statement.setBoolean(6, playerName); - ExtensionTabTable.set3TabValuesToStatement(statement, 7, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 10, providerInformation.getIcon()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 13, providerInformation.getPluginName(), serverUUID); - statement.setString(15, providerInformation.getName()); - } - }; - } - - private Executable insertProvider() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - PROVIDER_NAME + "," + - TEXT + "," + - DESCRIPTION + "," + - PRIORITY + "," + - CONDITION + "," + - SHOW_IN_PLAYERS_TABLE + "," + - IS_PLAYER_NAME + "," + - TAB_ID + "," + - ICON_ID + "," + - PLUGIN_ID + - ") VALUES (?,?,?,?,?,?,?," + - ExtensionTabTable.STATEMENT_SELECT_TAB_ID + "," + - ExtensionIconTable.STATEMENT_SELECT_ICON_ID + "," + - ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, providerInformation.getName()); - statement.setString(2, providerInformation.getText()); - Optional description = providerInformation.getDescription(); - if (description.isPresent()) { - statement.setString(3, description.get()); - } else { - statement.setNull(3, Types.VARCHAR); - } - statement.setInt(4, providerInformation.getPriority()); - Optional condition = providerInformation.getCondition(); - if (condition.isPresent()) { - statement.setString(5, condition.get()); - } else { - statement.setNull(5, Types.VARCHAR); - } - statement.setBoolean(6, providerInformation.isShownInPlayersTable()); - statement.setBoolean(7, playerName); - ExtensionTabTable.set3TabValuesToStatement(statement, 8, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 11, providerInformation.getIcon()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 14, providerInformation.getPluginName(), serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreTableProviderTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreTableProviderTransaction.java deleted file mode 100644 index 5b203abe9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/providers/StoreTableProviderTransaction.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.providers; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionIconTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTabTable; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Icon; -import com.djrapitops.plan.extension.implementation.ProviderInformation; -import com.djrapitops.plan.extension.table.Table; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable.*; - -/** - * Transaction to store information about a {@link com.djrapitops.plan.extension.implementation.providers.TableDataProvider}. - * - * @author Rsl1122 - */ -public class StoreTableProviderTransaction extends Transaction { - - private final UUID serverUUID; - private final ProviderInformation providerInformation; - private final Color tableColor; - private final Table table; - - public StoreTableProviderTransaction(UUID serverUUID, ProviderInformation providerInformation, Color tableColor, Table table) { - this.providerInformation = providerInformation; - this.tableColor = tableColor; - this.table = table; - this.serverUUID = serverUUID; - } - - @Override - protected void performOperations() { - execute(storeProvider()); - } - - private Executable storeProvider() { - return connection -> { - if (!updateProvider().execute(connection)) { - return insertProvider().execute(connection); - } - return false; - }; - } - - private Executable updateProvider() { - String[] columns = table.getColumns(); - Icon[] icons = table.getIcons(); - - String sql = "UPDATE " + TABLE_NAME + " SET " + - COLOR + "=?," + - COL_1 + "=?," + - COL_2 + "=?," + - COL_3 + "=?," + - COL_4 + "=?," + - COL_5 + "=?," + - CONDITION + "=?," + - TAB_ID + '=' + ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' + - ICON_1_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - ICON_2_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - ICON_3_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - ICON_4_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - ICON_5_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + - WHERE + PROVIDER_NAME + "=?" + - AND + PLUGIN_ID + '=' + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, tableColor.name()); - setStringOrNull(statement, 2, columns[0]); - setStringOrNull(statement, 3, columns[1]); - setStringOrNull(statement, 4, columns[2]); - setStringOrNull(statement, 5, columns[3]); - setStringOrNull(statement, 6, columns[4]); - setStringOrNull(statement, 7, providerInformation.getCondition().orElse(null)); - ExtensionTabTable.set3TabValuesToStatement(statement, 8, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 11, icons[0]); - ExtensionIconTable.set3IconValuesToStatement(statement, 14, icons[1]); - ExtensionIconTable.set3IconValuesToStatement(statement, 17, icons[2]); - ExtensionIconTable.set3IconValuesToStatement(statement, 20, icons[3]); - ExtensionIconTable.set3IconValuesToStatement(statement, 23, icons[4]); - statement.setString(26, providerInformation.getName()); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 27, providerInformation.getPluginName(), serverUUID); - } - }; - } - - private Executable insertProvider() { - String[] columns = table.getColumns(); - Icon[] icons = table.getIcons(); - - String sql = "INSERT INTO " + TABLE_NAME + '(' + - PROVIDER_NAME + ',' + - COLOR + ',' + - COL_1 + ',' + - COL_2 + ',' + - COL_3 + ',' + - COL_4 + ',' + - COL_5 + ',' + - CONDITION + ',' + - TAB_ID + ',' + - PLUGIN_ID + ',' + - ICON_1_ID + ',' + - ICON_2_ID + ',' + - ICON_3_ID + ',' + - ICON_4_ID + ',' + - ICON_5_ID + - ") VALUES (?,?,?,?,?,?,?,?," + - ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' + - ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ',' + - ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' + - ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ')'; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, providerInformation.getName()); - statement.setString(2, tableColor.name()); - setStringOrNull(statement, 3, columns[0]); - setStringOrNull(statement, 4, columns[1]); - setStringOrNull(statement, 5, columns[2]); - setStringOrNull(statement, 6, columns[3]); - setStringOrNull(statement, 7, columns[4]); - setStringOrNull(statement, 8, providerInformation.getCondition().orElse(null)); - ExtensionTabTable.set3TabValuesToStatement(statement, 9, providerInformation.getTab().orElse("No Tab"), providerInformation.getPluginName(), serverUUID); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 12, providerInformation.getPluginName(), serverUUID); - ExtensionIconTable.set3IconValuesToStatement(statement, 14, icons[0]); - ExtensionIconTable.set3IconValuesToStatement(statement, 17, icons[1]); - ExtensionIconTable.set3IconValuesToStatement(statement, 20, icons[2]); - ExtensionIconTable.set3IconValuesToStatement(statement, 23, icons[3]); - ExtensionIconTable.set3IconValuesToStatement(statement, 26, icons[4]); - } - }; - } - - private void setStringOrNull(PreparedStatement statement, int index, String value) throws SQLException { - if (value != null) { - statement.setString(index, value); - } else { - statement.setNull(index, Types.VARCHAR); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveInvalidResultsTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveInvalidResultsTransaction.java deleted file mode 100644 index 4b0913ff7..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveInvalidResultsTransaction.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.*; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Collection; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; - -/** - * Transaction to remove method results that correspond to {@link com.djrapitops.plan.extension.annotation.InvalidateMethod} annotations. - * - * @author Rsl1122 - */ -public class RemoveInvalidResultsTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final Collection invalidatedMethods; - - public RemoveInvalidResultsTransaction(String pluginName, UUID serverUUID, Collection invalidatedMethods) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.invalidatedMethods = invalidatedMethods; - } - - @Override - protected void performOperations() { - for (String invalidatedMethod : invalidatedMethods) { - execute(deleteInvalidPlayerMethodResults(invalidatedMethod)); - execute(deleteInvalidServerMethodResults(invalidatedMethod)); - execute(deleteInvalidMethodProvider(invalidatedMethod)); - - execute(deleteInvalidPlayerTableResults(invalidatedMethod)); - execute(deleteInvalidServerTableResults(invalidatedMethod)); - execute(deleteInvalidTableProvider(invalidatedMethod)); - } - } - - private Executable deleteInvalidPlayerMethodResults(String invalidMethod) { - String sql = "DELETE FROM " + ExtensionPlayerValueTable.TABLE_NAME + - WHERE + ExtensionPlayerValueTable.PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - ExtensionProviderTable.set3PluginValuesToStatement(statement, 1, invalidMethod, pluginName, serverUUID); - } - }; - } - - private Executable deleteInvalidServerMethodResults(String invalidMethod) { - String sql = "DELETE FROM " + ExtensionServerValueTable.TABLE_NAME + - WHERE + ExtensionServerValueTable.PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - ExtensionProviderTable.set3PluginValuesToStatement(statement, 1, invalidMethod, pluginName, serverUUID); - } - }; - } - - private Executable deleteInvalidPlayerTableResults(String invalidMethod) { - String sql = "DELETE FROM " + ExtensionPlayerTableValueTable.TABLE_NAME + - WHERE + ExtensionPlayerTableValueTable.TABLE_ID + "=" + ExtensionTableProviderTable.STATEMENT_SELECT_TABLE_ID; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - ExtensionTableProviderTable.set3PluginValuesToStatement(statement, 1, invalidMethod, pluginName, serverUUID); - } - }; - } - - private Executable deleteInvalidServerTableResults(String invalidMethod) { - String sql = "DELETE FROM " + ExtensionServerTableValueTable.TABLE_NAME + - WHERE + ExtensionServerTableValueTable.TABLE_ID + "=" + ExtensionTableProviderTable.STATEMENT_SELECT_TABLE_ID; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - ExtensionTableProviderTable.set3PluginValuesToStatement(statement, 1, invalidMethod, pluginName, serverUUID); - } - }; - } - - private Executable deleteInvalidMethodProvider(String invalidMethod) { - String sql = "DELETE FROM " + ExtensionProviderTable.TABLE_NAME + - WHERE + ExtensionProviderTable.PROVIDER_NAME + "=?" + - AND + ExtensionProviderTable.PLUGIN_ID + '=' + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, invalidMethod); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 2, pluginName, serverUUID); - } - }; - } - - private Executable deleteInvalidTableProvider(String invalidMethod) { - String sql = "DELETE FROM " + ExtensionTableProviderTable.TABLE_NAME + - WHERE + ExtensionTableProviderTable.TABLE_NAME + "=?" + - AND + ExtensionTableProviderTable.PLUGIN_ID + '=' + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, invalidMethod); - ExtensionPluginTable.set2PluginValuesToStatement(statement, 2, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalPlayerResultsTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalPlayerResultsTransaction.java deleted file mode 100644 index 8bbda64c4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalPlayerResultsTransaction.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionPlayerTableValueTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Transaction to remove older results that violate an updated condition value. - *

- * How it works: - * - Select all fulfilled conditions for all players (conditionName when true and not_conditionName when false) - * - Left join with player value and provider tables when uuids match, and when condition matches a condition in the query above. - * - Filter the join query for values where the condition did not match any provided condition in the join (Is null) - * - Delete all player values with IDs that are returned by the left join query after filtering - * - * @author Rsl1122 - */ -public class RemoveUnsatisfiedConditionalPlayerResultsTransaction extends Transaction { - - private final String providerTable; - private final String playerValueTable; - private final String playerTableValueTable; - private final String tableTable; - - public RemoveUnsatisfiedConditionalPlayerResultsTransaction() { - providerTable = ExtensionProviderTable.TABLE_NAME; - playerValueTable = ExtensionPlayerValueTable.TABLE_NAME; - tableTable = ExtensionTableProviderTable.TABLE_NAME; - playerTableValueTable = ExtensionPlayerTableValueTable.TABLE_NAME; - } - - @Override - protected void performOperations() { - String selectSatisfiedConditions = getSatisfiedConditionsSQL(); - - execute(deleteUnsatisfiedValues(selectSatisfiedConditions)); - execute(deleteUnsatisfiedTableValues(selectSatisfiedConditions)); - } - - private String getSatisfiedConditionsSQL() { - String reversedCondition = dbType == DBType.SQLITE ? "'not_' || " + ExtensionProviderTable.PROVIDED_CONDITION : "CONCAT('not_'," + ExtensionProviderTable.PROVIDED_CONDITION + ')'; - - String selectSatisfiedPositiveConditions = SELECT + - ExtensionProviderTable.PROVIDED_CONDITION + ',' + - ExtensionProviderTable.PLUGIN_ID + ',' + - ExtensionPlayerTableValueTable.USER_UUID + - FROM + providerTable + - INNER_JOIN + playerValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionPlayerValueTable.PROVIDER_ID + - WHERE + ExtensionPlayerValueTable.BOOLEAN_VALUE + "=?" + - AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL; - String selectSatisfiedNegativeConditions = SELECT + - reversedCondition + " as " + ExtensionProviderTable.PROVIDED_CONDITION + ',' + - ExtensionProviderTable.PLUGIN_ID + ',' + - ExtensionPlayerTableValueTable.USER_UUID + - FROM + providerTable + - INNER_JOIN + playerValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionPlayerValueTable.PROVIDER_ID + - WHERE + ExtensionPlayerValueTable.BOOLEAN_VALUE + "=?" + - AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL; - - // Query contents: Set of provided_conditions - return '(' + selectSatisfiedPositiveConditions + " UNION " + selectSatisfiedNegativeConditions + ") q1"; - } - - private Executable deleteUnsatisfiedValues(String selectSatisfiedConditions) { - // Query contents: - // id | uuid | q1.uuid | condition | q1.provided_condition - // -- | ---- | ------- | --------- | --------------------- - // 1 | ... | ... | A | A Satisfied condition - // 2 | ... | ... | not_B | not_B Satisfied condition - // 3 | ... | ... | NULL | NULL Satisfied condition - // 4 | ... | ... | B | NULL Unsatisfied condition, filtered to these in WHERE clause. - // 5 | ... | ... | not_C | NULL Unsatisfied condition - String selectUnsatisfiedValueIDs = SELECT + playerValueTable + '.' + ExtensionPlayerValueTable.ID + - FROM + providerTable + - INNER_JOIN + playerValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionPlayerValueTable.PROVIDER_ID + - LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled - " on (" + - playerValueTable + '.' + ExtensionPlayerValueTable.USER_UUID + - "=q1." + ExtensionPlayerValueTable.USER_UUID + - AND + ExtensionProviderTable.CONDITION + - "=q1." + ExtensionProviderTable.PROVIDED_CONDITION + - AND + providerTable + '.' + ExtensionProviderTable.PLUGIN_ID + - "=q1." + ExtensionProviderTable.PLUGIN_ID + - ')' + - WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query - AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition - - // Nested query here is required because MySQL limits update statements with nested queries: - // The nested query creates a temporary table that bypasses the same table query-update limit. - // Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception. - String sql = "DELETE FROM " + playerValueTable + - WHERE + ExtensionPlayerValueTable.ID + " IN (" + SELECT + ExtensionPlayerValueTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)"; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, true); // Select provided conditions with 'true' value - statement.setBoolean(2, false); // Select negated conditions with 'false' value - } - }; - } - - private Executable deleteUnsatisfiedTableValues(String selectSatisfiedConditions) { - String selectUnsatisfiedValueIDs = SELECT + ExtensionTableProviderTable.ID + - FROM + tableTable + - LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled - " on (" + - tableTable + '.' + ExtensionTableProviderTable.CONDITION + - "=q1." + ExtensionProviderTable.PROVIDED_CONDITION + - AND + tableTable + '.' + ExtensionTableProviderTable.PLUGIN_ID + - "=q1." + ExtensionProviderTable.PLUGIN_ID + - ')' + - WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query - AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition - - // Nested query here is required because MySQL limits update statements with nested queries: - // The nested query creates a temporary table that bypasses the same table query-update limit. - // Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception. - String deleteValuesSQL = "DELETE FROM " + playerTableValueTable + - WHERE + ExtensionPlayerTableValueTable.TABLE_ID + " IN (" + SELECT + ExtensionTableProviderTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)"; - - return new ExecStatement(deleteValuesSQL) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, true); // Select provided conditions with 'true' value - statement.setBoolean(2, false); // Select negated conditions with 'false' value - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalServerResultsTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalServerResultsTransaction.java deleted file mode 100644 index 2718ef6f9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalServerResultsTransaction.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; -import com.djrapitops.plan.db.sql.tables.ExtensionServerTableValueTable; -import com.djrapitops.plan.db.sql.tables.ExtensionServerValueTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; - -/** - * Transaction to remove older results that violate an updated condition value. - *

- * How it works: - * - Select all fulfilled conditions for all servers (conditionName when true and not_conditionName when false) - * - Left join with server value and provider tables when plugin_ids match, and when condition matches a condition in the - * query above. (plugin_ids can be linked to servers) - * - Filter the join query for values where the condition did not match any provided condition in the join (Is null) - * - Delete all server values with IDs that are returned by the left join query after filtering - * - * @author Rsl1122 - */ -public class RemoveUnsatisfiedConditionalServerResultsTransaction extends Transaction { - - private final String providerTable; - private final String serverValueTable; - private final String serverTableValueTable; - private final String tableTable; - - public RemoveUnsatisfiedConditionalServerResultsTransaction() { - providerTable = ExtensionProviderTable.TABLE_NAME; - serverValueTable = ExtensionServerValueTable.TABLE_NAME; - tableTable = ExtensionTableProviderTable.TABLE_NAME; - serverTableValueTable = ExtensionServerTableValueTable.TABLE_NAME; - } - - @Override - protected void performOperations() { - String selectSatisfiedConditions = getSatisfiedConditionsSQL(); - execute(deleteUnsatisfiedValues(selectSatisfiedConditions)); - execute(deleteUnsatisfiedTableValues(selectSatisfiedConditions)); - } - - private Executable deleteUnsatisfiedValues(String selectSatisfiedConditions) { - // Query contents: - // id | provider_id | q1.provider_id | condition | q1.provided_condition - // -- | ----------- | -------------- | --------- | --------------------- - // 1 | ... | ... | A | A Satisfied condition - // 2 | ... | ... | not_B | not_B Satisfied condition - // 3 | ... | ... | NULL | NULL Satisfied condition - // 4 | ... | ... | B | NULL Unsatisfied condition, filtered to these in WHERE clause. - // 5 | ... | ... | not_C | NULL Unsatisfied condition - String selectUnsatisfiedValueIDs = SELECT + serverValueTable + '.' + ExtensionServerValueTable.ID + - FROM + providerTable + - INNER_JOIN + serverValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionServerValueTable.PROVIDER_ID + - LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled - " on (" + - ExtensionProviderTable.CONDITION + "=q1." + ExtensionProviderTable.PROVIDED_CONDITION + - AND + providerTable + '.' + ExtensionProviderTable.PLUGIN_ID + "=q1." + ExtensionProviderTable.PLUGIN_ID + - ')' + - WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query - AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition - - // Nested query here is required because MySQL limits update statements with nested queries: - // The nested query creates a temporary table that bypasses the same table query-update limit. - // Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception. - String sql = "DELETE FROM " + serverValueTable + - WHERE + ExtensionServerValueTable.ID + " IN (" + SELECT + ExtensionServerValueTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)"; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, true); // Select provided conditions with 'true' value - statement.setBoolean(2, false); // Select negated conditions with 'false' value - } - }; - } - - private String getSatisfiedConditionsSQL() { - String reversedCondition = dbType == DBType.SQLITE ? "'not_' || " + ExtensionProviderTable.PROVIDED_CONDITION : "CONCAT('not_'," + ExtensionProviderTable.PROVIDED_CONDITION + ')'; - - String selectSatisfiedPositiveConditions = SELECT + - ExtensionProviderTable.PROVIDED_CONDITION + ',' + - ExtensionProviderTable.PLUGIN_ID + - FROM + providerTable + - INNER_JOIN + serverValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionServerValueTable.PROVIDER_ID + - WHERE + ExtensionServerValueTable.BOOLEAN_VALUE + "=?" + - AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL; - String selectSatisfiedNegativeConditions = SELECT + - reversedCondition + " as " + ExtensionProviderTable.PROVIDED_CONDITION + ',' + - ExtensionProviderTable.PLUGIN_ID + - FROM + providerTable + - INNER_JOIN + serverValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionServerValueTable.PROVIDER_ID + - WHERE + ExtensionServerValueTable.BOOLEAN_VALUE + "=?" + - AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL; - - // Query contents: Set of provided_conditions - return '(' + selectSatisfiedPositiveConditions + " UNION " + selectSatisfiedNegativeConditions + ") q1"; - } - - private Executable deleteUnsatisfiedTableValues(String selectSatisfiedConditions) { - String selectUnsatisfiedValueIDs = SELECT + ExtensionTableProviderTable.ID + - FROM + tableTable + - LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled - " on (" + - tableTable + '.' + ExtensionTableProviderTable.CONDITION + - "=q1." + ExtensionProviderTable.PROVIDED_CONDITION + - AND + tableTable + '.' + ExtensionTableProviderTable.PLUGIN_ID + - "=q1." + ExtensionProviderTable.PLUGIN_ID + - ')' + - WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query - AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition - - // Nested query here is required because MySQL limits update statements with nested queries: - // The nested query creates a temporary table that bypasses the same table query-update limit. - // Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception. - String deleteValuesSQL = "DELETE FROM " + serverTableValueTable + - WHERE + ExtensionServerTableValueTable.TABLE_ID + " IN (" + SELECT + ExtensionTableProviderTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)"; - - return new ExecStatement(deleteValuesSQL) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, true); // Select provided conditions with 'true' value - statement.setBoolean(2, false); // Select negated conditions with 'false' value - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerBooleanResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerBooleanResultTransaction.java deleted file mode 100644 index 9b01dcbb0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerBooleanResultTransaction.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.BooleanDataProvider}. - * - * @author Rsl1122 - */ -public class StorePlayerBooleanResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - private final UUID playerUUID; - - private final boolean value; - - public StorePlayerBooleanResultTransaction(String pluginName, UUID serverUUID, String providerName, UUID playerUUID, boolean value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.playerUUID = playerUUID; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - BOOLEAN_VALUE + "=?" + - WHERE + USER_UUID + "=?" + - AND + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - BOOLEAN_VALUE + "," + - USER_UUID + "," + - PROVIDER_ID + - ") VALUES (?,?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerDoubleResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerDoubleResultTransaction.java deleted file mode 100644 index f64c182cf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerDoubleResultTransaction.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.DoubleDataProvider}. - * - * @author Rsl1122 - */ -public class StorePlayerDoubleResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - private final UUID playerUUID; - - private final double value; - - public StorePlayerDoubleResultTransaction(String pluginName, UUID serverUUID, String providerName, UUID playerUUID, double value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.playerUUID = playerUUID; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - DOUBLE_VALUE + "=?" + - WHERE + USER_UUID + "=?" + - AND + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setDouble(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - DOUBLE_VALUE + "," + - USER_UUID + "," + - PROVIDER_ID + - ") VALUES (?,?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setDouble(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerNumberResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerNumberResultTransaction.java deleted file mode 100644 index f20ecd43d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerNumberResultTransaction.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.NumberDataProvider}. - * - * @author Rsl1122 - */ -public class StorePlayerNumberResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - private final UUID playerUUID; - - private final long value; - - public StorePlayerNumberResultTransaction(String pluginName, UUID serverUUID, String providerName, UUID playerUUID, long value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.playerUUID = playerUUID; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - LONG_VALUE + "=?" + - WHERE + USER_UUID + "=?" + - AND + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - LONG_VALUE + "," + - USER_UUID + "," + - PROVIDER_ID + - ") VALUES (?,?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerPercentageResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerPercentageResultTransaction.java deleted file mode 100644 index 0bb8e1336..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerPercentageResultTransaction.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.PercentageDataProvider}. - * - * @author Rsl1122 - */ -public class StorePlayerPercentageResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - private final UUID playerUUID; - - private final double value; - - public StorePlayerPercentageResultTransaction(String pluginName, UUID serverUUID, String providerName, UUID playerUUID, double value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.playerUUID = playerUUID; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - PERCENTAGE_VALUE + "=?" + - WHERE + USER_UUID + "=?" + - AND + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setDouble(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - PERCENTAGE_VALUE + "," + - USER_UUID + "," + - PROVIDER_ID + - ") VALUES (?,?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setDouble(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerStringResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerStringResultTransaction.java deleted file mode 100644 index a858d7c3c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerStringResultTransaction.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.AND; -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.StringDataProvider}. - * - * @author Rsl1122 - */ -public class StorePlayerStringResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - private final UUID playerUUID; - - private final String value; - - public StorePlayerStringResultTransaction(String pluginName, UUID serverUUID, String providerName, UUID playerUUID, String value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.playerUUID = playerUUID; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - STRING_VALUE + "=?" + - WHERE + USER_UUID + "=?" + - AND + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - STRING_VALUE + "," + - USER_UUID + "," + - PROVIDER_ID + - ") VALUES (?,?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, value); - statement.setString(2, playerUUID.toString()); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 3, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerTableResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerTableResultTransaction.java deleted file mode 100644 index 73f0b6a53..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerTableResultTransaction.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.access.*; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable; -import com.djrapitops.plan.extension.table.Table; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; -import static com.djrapitops.plan.db.sql.tables.ExtensionPlayerTableValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.TableDataProvider}. - * - * @author Rsl1122 - */ -public class StorePlayerTableResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - private final UUID playerUUID; - - private final Table table; - - public StorePlayerTableResultTransaction(String pluginName, UUID serverUUID, String providerName, UUID playerUUID, Table table) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.playerUUID = playerUUID; - this.table = table; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - int maxColumnSize = table.getMaxColumnSize(); - if (maxColumnSize == 0) { - return false; - } - - Integer tableID = query(tableID()); - deleteOldValues(tableID).execute(connection); - insertNewValues(tableID).execute(connection); - return false; - }; - } - - private Executable deleteOldValues(int tableID) { - String sql = "DELETE FROM " + TABLE_NAME + - WHERE + TABLE_ID + "=?" + - AND + USER_UUID + "=?"; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setInt(1, tableID); - statement.setString(2, playerUUID.toString()); - } - }; - } - - private Executable insertNewValues(int tableID) { - String sql = "INSERT INTO " + TABLE_NAME + '(' + - TABLE_ID + ',' + - USER_UUID + ',' + - VALUE_1 + ',' + - VALUE_2 + ',' + - VALUE_3 + ',' + - VALUE_4 + - ") VALUES (?,?,?,?,?,?)"; - - return new ExecBatchStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - int maxColumnSize = Math.min(table.getMaxColumnSize(), 4); // Limit to maximum 4 columns, or how many column names there are. - - for (Object[] row : table.getRows()) { - statement.setInt(1, tableID); - statement.setString(2, playerUUID.toString()); - for (int i = 0; i < maxColumnSize; i++) { - Object value = row[i]; - setStringOrNull(statement, 3 + i, value != null ? value.toString() : null); - } - // Rest are set null if not 4 columns wide. - for (int i = maxColumnSize; i < 4; i++) { - statement.setNull(3 + i, Types.VARCHAR); - } - - statement.addBatch(); - } - } - }; - } - - private void setStringOrNull(PreparedStatement statement, int index, String value) throws SQLException { - if (value != null) { - statement.setString(index, value); - } else { - statement.setNull(index, Types.VARCHAR); - } - } - - private Query tableID() { - String sql = SELECT + ExtensionTableProviderTable.ID + - FROM + ExtensionTableProviderTable.TABLE_NAME + - WHERE + ExtensionTableProviderTable.PROVIDER_NAME + "=?" + - AND + ExtensionTableProviderTable.PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + - " LIMIT 1"; - return new QueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - ExtensionTableProviderTable.set3PluginValuesToStatement(statement, 1, providerName, pluginName, serverUUID); - } - - @Override - public Integer processResults(ResultSet set) throws SQLException { - if (set.next()) { - int id = set.getInt(ExtensionTableProviderTable.ID); - if (!set.wasNull()) { - return id; - } - } - throw new DBOpException("Table Provider was not saved before storing results. Please report this issue. Extension method: " + pluginName + "#" + providerName); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerBooleanResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerBooleanResultTransaction.java deleted file mode 100644 index dd8bbe976..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerBooleanResultTransaction.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionServerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.BooleanDataProvider}. - * - * @author Rsl1122 - */ -public class StoreServerBooleanResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - - private final boolean value; - - public StoreServerBooleanResultTransaction(String pluginName, UUID serverUUID, String providerName, boolean value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - BOOLEAN_VALUE + "=?" + - WHERE + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - BOOLEAN_VALUE + "," + - PROVIDER_ID + - ") VALUES (?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setBoolean(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerDoubleResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerDoubleResultTransaction.java deleted file mode 100644 index 559a36582..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerDoubleResultTransaction.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionServerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.DoubleDataProvider}. - * - * @author Rsl1122 - */ -public class StoreServerDoubleResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - - private final double value; - - public StoreServerDoubleResultTransaction(String pluginName, UUID serverUUID, String providerName, double value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - DOUBLE_VALUE + "=?" + - WHERE + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setDouble(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - DOUBLE_VALUE + "," + - PROVIDER_ID + - ") VALUES (?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setDouble(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerNumberResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerNumberResultTransaction.java deleted file mode 100644 index 62098154a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerNumberResultTransaction.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionServerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.NumberDataProvider}. - * - * @author Rsl1122 - */ -public class StoreServerNumberResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - - private final long value; - - public StoreServerNumberResultTransaction(String pluginName, UUID serverUUID, String providerName, long value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - LONG_VALUE + "=?" + - WHERE + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - LONG_VALUE + "," + - PROVIDER_ID + - ") VALUES (?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setLong(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerPercentageResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerPercentageResultTransaction.java deleted file mode 100644 index 9fb317107..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerPercentageResultTransaction.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionServerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.PercentageDataProvider}. - * - * @author Rsl1122 - */ -public class StoreServerPercentageResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - - private final double value; - - public StoreServerPercentageResultTransaction(String pluginName, UUID serverUUID, String providerName, double value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - PERCENTAGE_VALUE + "=?" + - WHERE + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setDouble(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - PERCENTAGE_VALUE + "," + - PROVIDER_ID + - ") VALUES (?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setDouble(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerStringResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerStringResultTransaction.java deleted file mode 100644 index f6c58510f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerStringResultTransaction.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.db.access.ExecStatement; -import com.djrapitops.plan.db.access.Executable; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.WHERE; -import static com.djrapitops.plan.db.sql.tables.ExtensionServerValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.PercentageDataProvider}. - * - * @author Rsl1122 - */ -public class StoreServerStringResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - - private final String value; - - public StoreServerStringResultTransaction(String pluginName, UUID serverUUID, String providerName, String value) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.value = value; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - if (!updateValue().execute(connection)) { - return insertValue().execute(connection); - } - return false; - }; - } - - private Executable updateValue() { - String sql = "UPDATE " + TABLE_NAME + - " SET " + - STRING_VALUE + "=?" + - WHERE + PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } - - private Executable insertValue() { - String sql = "INSERT INTO " + TABLE_NAME + "(" + - STRING_VALUE + "," + - PROVIDER_ID + - ") VALUES (?," + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID + ")"; - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, value); - ExtensionProviderTable.set3PluginValuesToStatement(statement, 2, providerName, pluginName, serverUUID); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerTableResultTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerTableResultTransaction.java deleted file mode 100644 index ff5211097..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerTableResultTransaction.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.implementation.storage.transactions.results; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.access.*; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionPluginTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable; -import com.djrapitops.plan.extension.table.Table; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.UUID; - -import static com.djrapitops.plan.db.sql.parsing.Sql.*; -import static com.djrapitops.plan.db.sql.tables.ExtensionServerTableValueTable.*; - -/** - * Transaction to store method result of a {@link com.djrapitops.plan.extension.implementation.providers.TableDataProvider}. - * - * @author Rsl1122 - */ -public class StoreServerTableResultTransaction extends Transaction { - - private final String pluginName; - private final UUID serverUUID; - private final String providerName; - - private final Table table; - - public StoreServerTableResultTransaction(String pluginName, UUID serverUUID, String providerName, Table table) { - this.pluginName = pluginName; - this.serverUUID = serverUUID; - this.providerName = providerName; - this.table = table; - } - - @Override - protected void performOperations() { - execute(storeValue()); - } - - private Executable storeValue() { - return connection -> { - int maxColumnSize = table.getMaxColumnSize(); - if (maxColumnSize == 0) { - return false; - } - - Integer tableID = query(tableID()); - deleteOldValues(tableID).execute(connection); - insertNewValues(tableID).execute(connection); - return false; - }; - } - - private Executable deleteOldValues(int tableID) { - String sql = "DELETE FROM " + TABLE_NAME + - WHERE + TABLE_ID + "=?" + - AND + SERVER_UUID + "=?"; - - return new ExecStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setInt(1, tableID); - statement.setString(2, serverUUID.toString()); - } - }; - } - - private Executable insertNewValues(int tableID) { - String sql = "INSERT INTO " + TABLE_NAME + '(' + - TABLE_ID + ',' + - SERVER_UUID + ',' + - VALUE_1 + ',' + - VALUE_2 + ',' + - VALUE_3 + ',' + - VALUE_4 + ',' + - VALUE_5 + - ") VALUES (?,?,?,?,?,?, ?)"; - - return new ExecBatchStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - int maxColumnSize = Math.min(table.getMaxColumnSize(), 5); // Limit to maximum 5 columns, or how many column names there are. - - for (Object[] row : table.getRows()) { - statement.setInt(1, tableID); - statement.setString(2, serverUUID.toString()); - for (int i = 0; i < maxColumnSize; i++) { - Object value = row[i]; - setStringOrNull(statement, 3 + i, value != null ? value.toString() : null); - } - // Rest are set null if not 5 columns wide. - for (int i = maxColumnSize; i < 5; i++) { - statement.setNull(3 + i, Types.VARCHAR); - } - - statement.addBatch(); - } - } - }; - } - - private void setStringOrNull(PreparedStatement statement, int index, String value) throws SQLException { - if (value != null) { - statement.setString(index, value); - } else { - statement.setNull(index, Types.VARCHAR); - } - } - - private Query tableID() { - String sql = SELECT + ExtensionTableProviderTable.ID + - FROM + ExtensionTableProviderTable.TABLE_NAME + - WHERE + ExtensionTableProviderTable.PROVIDER_NAME + "=?" + - AND + ExtensionTableProviderTable.PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + - " LIMIT 1"; - return new QueryStatement(sql) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - ExtensionTableProviderTable.set3PluginValuesToStatement(statement, 1, providerName, pluginName, serverUUID); - } - - @Override - public Integer processResults(ResultSet set) throws SQLException { - if (set.next()) { - int id = set.getInt(ExtensionTableProviderTable.ID); - if (!set.wasNull()) { - return id; - } - } - throw new DBOpException("Table Provider was not saved before storing results. Please report this issue. Extension method: " + pluginName + "#" + providerName); - } - }; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/table/TableAccessor.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/table/TableAccessor.java deleted file mode 100644 index 19fef428f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/table/TableAccessor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.extension.table; - -import com.djrapitops.plan.extension.ElementOrder; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.icon.Icon; - -/** - * Utility for accessing implementation variables inside Table.Factory object. - * - * @author Rsl1122 - */ -public class TableAccessor { - - private TableAccessor() { - /* Static method class */ - } - - public static Color getColor(Table.Factory factory) { - return factory.color; - } - - public static void setColor(Table.Factory factory, Color color) { - factory.color = color; - } - - public static String getTableName(Table.Factory factory) { - return factory.tableName; - } - - public static void setTableName(Table.Factory factory, String tableName) { - factory.tableName = tableName; - } - - public static String getTabName(Table.Factory factory) { - return factory.tabName; - } - - public static void setTabName(Table.Factory factory, String tabName) { - factory.tabName = tabName; - } - - public static int getTabPriority(Table.Factory factory) { - return factory.tabPriority; - } - - public static void setTabPriority(Table.Factory factory, int tabPriority) { - factory.tabPriority = tabPriority; - } - - public static ElementOrder[] getTabOrder(Table.Factory factory) { - return factory.tabOrder; - } - - public static void setTabOrder(Table.Factory factory, ElementOrder[] tabOrder) { - factory.tabOrder = tabOrder; - } - - public static Icon getTabIcon(Table.Factory factory) { - return factory.tabIcon; - } - - public static void setTabIcon(Table.Factory factory, Icon tabIcon) { - factory.tabIcon = tabIcon; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/modules/APFModule.java b/Plan/common/src/main/java/com/djrapitops/plan/modules/APFModule.java deleted file mode 100644 index 3c9c06148..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/modules/APFModule.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plugin.IPlugin; -import com.djrapitops.plugin.benchmarking.Timings; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.debug.DebugLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.RunnableFactory; -import dagger.Module; -import dagger.Provides; - -import javax.inject.Named; -import javax.inject.Singleton; - -/** - * Dagger module for defining Abstract Plugin Framework utilities. - * - * @author Rsl1122 - */ -@Module -public class APFModule { - @Provides - @Singleton - IPlugin provideIPlugin(PlanPlugin plugin) { - return plugin; - } - - @Provides - @Named("currentVersion") - @Singleton - String provideCurrentVersion(IPlugin plugin) { - return plugin.getVersion(); - } - - @Provides - @Singleton - ColorScheme provideColorScheme(PlanPlugin plugin) { - return plugin.getColorScheme(); - } - - @Provides - @Singleton - DebugLogger provideDebugLogger(IPlugin plugin) { - return plugin.getDebugLogger(); - } - - @Provides - @Singleton - PluginLogger providePluginLogger(IPlugin plugin) { - return plugin.getPluginLogger(); - } - - @Provides - @Singleton - ErrorHandler provideErrorHandler(IPlugin plugin) { - return plugin.getErrorHandler(); - } - - @Provides - @Singleton - Timings provideTimings(IPlugin plugin) { - return plugin.getTimings(); - } - - @Provides - @Singleton - RunnableFactory provideRunnableFactory(IPlugin plugin) { - return plugin.getRunnableFactory(); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/modules/FilesModule.java b/Plan/common/src/main/java/com/djrapitops/plan/modules/FilesModule.java deleted file mode 100644 index c75ec9faa..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/modules/FilesModule.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules; - -import com.djrapitops.plan.system.file.PlanFiles; -import dagger.Module; -import dagger.Provides; - -import javax.inject.Named; -import javax.inject.Singleton; -import java.io.File; - -/** - * Dagger Module for the Plan files. - * - * @author Rsl1122 - */ -@Module -public class FilesModule { - - @Provides - @Named("configFile") - @Singleton - File provideConfigFile(PlanFiles files) { - return files.getConfigFile(); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/modules/ProxySuperClassBindingModule.java b/Plan/common/src/main/java/com/djrapitops/plan/modules/ProxySuperClassBindingModule.java deleted file mode 100644 index 72ec7f1da..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/modules/ProxySuperClassBindingModule.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules; - -import com.djrapitops.plan.api.CommonAPI; -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.database.ProxyDBSystem; -import com.djrapitops.plan.system.importing.EmptyImportSystem; -import com.djrapitops.plan.system.importing.ImportSystem; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.ProxyInfoSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.connection.ProxyConnectionSystem; -import com.djrapitops.plan.system.settings.ConfigSystem; -import com.djrapitops.plan.system.settings.ProxyConfigSystem; -import dagger.Binds; -import dagger.Module; - -/** - * Dagger module for binding proxy server classes to super classes. - * - * @author Rsl1122 - */ -@Module -public interface ProxySuperClassBindingModule { - - @Binds - PlanAPI bindProxyPlanAPI(CommonAPI proxyAPI); - - @Binds - DBSystem bindProxyDatabaseSystem(ProxyDBSystem proxyDBSystem); - - @Binds - ConfigSystem bindProxyConfigSystem(ProxyConfigSystem proxyConfigSystem); - - @Binds - InfoSystem bindProxyInfoSystem(ProxyInfoSystem proxyInfoSystem); - - @Binds - ConnectionSystem bindProxyConnectionSystem(ProxyConnectionSystem proxyConnectionSystem); - - @Binds - ImportSystem bindImportSystem(EmptyImportSystem emptyImportSystem); - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/modules/ServerSuperClassBindingModule.java b/Plan/common/src/main/java/com/djrapitops/plan/modules/ServerSuperClassBindingModule.java deleted file mode 100644 index 56a1e8e3d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/modules/ServerSuperClassBindingModule.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules; - -import com.djrapitops.plan.api.CommonAPI; -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.ServerInfoSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.connection.ServerConnectionSystem; -import dagger.Binds; -import dagger.Module; - -/** - * Module for binding Server specific classes to the interface implementations. - * - * @author Rsl1122 - */ -@Module -public interface ServerSuperClassBindingModule { - - @Binds - PlanAPI bindServerPlanAPI(CommonAPI serverAPI); - - @Binds - InfoSystem bindServerInfoSystem(ServerInfoSystem serverInfoSystem); - - @Binds - ConnectionSystem bindServerConnectionSystem(ServerConnectionSystem serverConnectionSystem); -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/modules/SystemObjectProvidingModule.java b/Plan/common/src/main/java/com/djrapitops/plan/modules/SystemObjectProvidingModule.java deleted file mode 100644 index 4d9708407..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/modules/SystemObjectProvidingModule.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.modules; - -import com.djrapitops.plan.data.plugin.PluginsConfigSection; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.LocaleSystem; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import dagger.Module; -import dagger.Provides; - -import javax.inject.Singleton; - -/** - * Module for binding object instances found inside other systems. - * - * @author Rsl1122 - */ -@Module -public class SystemObjectProvidingModule { - - @Provides - @Singleton - Locale provideLocale(LocaleSystem localeSystem) { - return localeSystem.getLocale(); - } - - @Provides - @Singleton - PluginsConfigSection providePluginsConfigSection(PlanConfig config) { - return config.getPluginsConfigSection(); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/query/CommonQueriesImplementation.java b/Plan/common/src/main/java/com/djrapitops/plan/query/CommonQueriesImplementation.java deleted file mode 100644 index c08e867fc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/query/CommonQueriesImplementation.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.query; - -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.containers.ContainerFetchQueries; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries; -import com.djrapitops.plan.db.access.queries.schema.H2SchemaQueries; -import com.djrapitops.plan.db.access.queries.schema.MySQLSchemaQueries; -import com.djrapitops.plan.db.access.queries.schema.SQLiteSchemaQueries; - -import java.util.Optional; -import java.util.Set; -import java.util.UUID; - -public class CommonQueriesImplementation implements CommonQueries { - - private final Database db; - - CommonQueriesImplementation(Database db) { - this.db = db; - } - - @Override - public long fetchPlaytime(UUID playerUUID, UUID serverUUID, long after, long before) { - // TODO Replace with single query later - PlayerContainer player = db.query(ContainerFetchQueries.fetchPlayerContainer(playerUUID)); - return SessionsMutator.forContainer(player) - .filterSessionsBetween(after, before) - .filterPlayedOnServer(serverUUID) - .toPlaytime(); - } - - @Override - public long fetchLastSeen(UUID playerUUID, UUID serverUUID) { - // TODO Replace with single query later - PlayerContainer player = db.query(ContainerFetchQueries.fetchPlayerContainer(playerUUID)); - return SessionsMutator.forContainer(player) - .filterPlayedOnServer(serverUUID) - .toLastSeen(); - } - - @Override - public Set fetchServerUUIDs() { - return db.query(ServerQueries.fetchServerNames()).keySet(); - } - - @Override - public Optional fetchUUIDOf(String playerName) { - return db.query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName)); - } - - @Override - public Optional fetchNameOf(UUID playerUUID) { - return db.query(UserIdentifierQueries.fetchPlayerNameOf(playerUUID)); - } - - @Override - public boolean doesDBHaveTable(String table) { - DBType dbType = db.getType(); - switch (dbType) { - case H2: - return db.query(H2SchemaQueries.doesTableExist(table)); - case SQLITE: - return db.query(SQLiteSchemaQueries.doesTableExist(table)); - case MYSQL: - return db.query(MySQLSchemaQueries.doesTableExist(table)); - default: - throw new IllegalStateException("Unsupported Database Type: " + dbType.getName()); - } - } - - @Override - public boolean doesDBHaveTableColumn(String table, String column) { - DBType dbType = db.getType(); - switch (dbType) { - case H2: - return db.query(H2SchemaQueries.doesColumnExist(table, column)); - case MYSQL: - return db.query(MySQLSchemaQueries.doesColumnExist(table, column)); - case SQLITE: - return db.query(SQLiteSchemaQueries.doesColumnExist(table, column)); - default: - throw new IllegalStateException("Unsupported Database Type: " + dbType.getName()); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/query/QueryServiceImplementation.java b/Plan/common/src/main/java/com/djrapitops/plan/query/QueryServiceImplementation.java deleted file mode 100644 index ba45cebe5..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/query/QueryServiceImplementation.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.query; - -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.QueryAPIExecutable; -import com.djrapitops.plan.db.access.QueryAPIQuery; -import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.sql.PreparedStatement; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Future; -import java.util.function.Consumer; - -@Singleton -public class QueryServiceImplementation implements QueryService { - - private DBSystem dbSystem; - private ServerInfo serverInfo; - - private Set> playerRemoveSubscribers; - private Set clearSubscribers; - - @Inject - public QueryServiceImplementation( - DBSystem dbSystem, - ServerInfo serverInfo - ) { - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - - playerRemoveSubscribers = new HashSet<>(); - clearSubscribers = new HashSet<>(); - } - - public void register() { - QueryService.QueryServiceHolder.set(this); - } - - @Override - public String getDBType() { - Database database = dbSystem.getDatabase(); - if (database == null) throw new IllegalStateException("Database has not been initialized."); - return database.getType().name(); - } - - @Override - public T query(String sql, ThrowingFunction performQuery) { - return dbSystem.getDatabase().query(new QueryAPIQuery<>(sql, performQuery)); - } - - @Override - public Future execute(String sql, ThrowingConsumer performStatement) { - return dbSystem.getDatabase().executeTransaction( - new Transaction() { - @Override - protected void performOperations() { - execute(new QueryAPIExecutable(sql, performStatement)); - } - } - ); - } - - @Override - public void subscribeToPlayerRemoveEvent(Consumer eventListener) { - playerRemoveSubscribers.add(eventListener); - } - - @Override - public void subscribeDataClearEvent(VoidFunction eventListener) { - clearSubscribers.add(eventListener); - } - - public void playerRemoved(UUID playerUUID) { - playerRemoveSubscribers.forEach(subscriber -> subscriber.accept(playerUUID)); - } - - public void dataCleared() { - clearSubscribers.forEach(VoidFunction::apply); - } - - @Override - public Optional getServerUUID() { - return Optional.ofNullable(serverInfo.getServer()).map(Server::getUuid); - } - - @Override - public CommonQueries getCommonQueries() { - Database database = dbSystem.getDatabase(); - if (database == null) throw new IllegalStateException("Database has not been initialized."); - return new CommonQueriesImplementation(database); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/DebugChannels.java b/Plan/common/src/main/java/com/djrapitops/plan/system/DebugChannels.java deleted file mode 100644 index 0bfb6ca49..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/DebugChannels.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system; - -/** - * Identifiers for different Debug channels. - * - * @author Rsl1122 - */ -public class DebugChannels { - - - private DebugChannels() { - /* Static variable class */ - } - - public static final String ANALYSIS = "Analysis"; - public static final String INFO_REQUESTS = "InfoRequests"; - public static final String CONNECTIONS = "Connections"; - public static final String WEB_REQUESTS = "Web Requests"; - public static final String IMPORTING = "Importing"; - public static final String SQL = "SQL"; - public static final String DATA_EXTENSIONS = "DataExtensions"; - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/HtmlUtilities.java b/Plan/common/src/main/java/com/djrapitops/plan/system/HtmlUtilities.java deleted file mode 100644 index 27b29cc09..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/HtmlUtilities.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system; - -import com.djrapitops.plan.utilities.formatting.Formatters; -import com.djrapitops.plan.utilities.html.graphs.Graphs; -import com.djrapitops.plan.utilities.html.structure.Accordions; -import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator; -import com.djrapitops.plan.utilities.html.tables.HtmlTables; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class HtmlUtilities { - - private final Lazy formatters; - private final Lazy htmlTables; - private final Lazy graphs; - private final Lazy accordions; - private final Lazy analysisPluginsTabContentCreator; - - @Inject - public HtmlUtilities( - Lazy formatters, - Lazy htmlTables, - Lazy graphs, - Lazy accordions, - Lazy analysisPluginsTabContentCreator - ) { - this.formatters = formatters; - this.htmlTables = htmlTables; - this.graphs = graphs; - this.accordions = accordions; - this.analysisPluginsTabContentCreator = analysisPluginsTabContentCreator; - } - - public Formatters getFormatters() { - return formatters.get(); - } - - public HtmlTables getHtmlTables() { - return htmlTables.get(); - } - - public Graphs getGraphs() { - return graphs.get(); - } - - public Accordions getAccordions() { - return accordions.get(); - } - - public AnalysisPluginsTabContentCreator getAnalysisPluginsTabContentCreator() { - return analysisPluginsTabContentCreator.get(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/PlanSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/PlanSystem.java deleted file mode 100644 index 4af6b6369..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/PlanSystem.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.capability.CapabilityServiceImplementation; -import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.extension.ExtensionService; -import com.djrapitops.plan.extension.ExtensionServiceImplementation; -import com.djrapitops.plan.query.QueryServiceImplementation; -import com.djrapitops.plan.system.cache.CacheSystem; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.export.ExportSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.importing.ImportSystem; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.listeners.ListenerSystem; -import com.djrapitops.plan.system.locale.LocaleSystem; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.ConfigSystem; -import com.djrapitops.plan.system.tasks.TaskSystem; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * PlanSystem contains everything Plan needs to run. - *

- * This is an abstraction layer on top of Plugin instances so that tests can be run with less mocks. - * - * @author Rsl1122 - */ -@Singleton -public class PlanSystem implements SubSystem { - - private boolean enabled = false; - - private final PlanFiles files; - private final ConfigSystem configSystem; - private final VersionCheckSystem versionCheckSystem; - private final LocaleSystem localeSystem; - private final DBSystem databaseSystem; - private final CacheSystem cacheSystem; - private final ListenerSystem listenerSystem; - private final TaskSystem taskSystem; - private final InfoSystem infoSystem; - private final ServerInfo serverInfo; - private final WebServerSystem webServerSystem; - - private final Processing processing; - - private final ImportSystem importSystem; - private final ExportSystem exportSystem; - private final HtmlUtilities htmlUtilities; - private final HookHandler hookHandler; - private final ExtensionServiceImplementation extensionService; - private final QueryServiceImplementation queryService; - private final PlanAPI planAPI; - private final ErrorHandler errorHandler; - - @Inject - public PlanSystem( - PlanFiles files, - ConfigSystem configSystem, - VersionCheckSystem versionCheckSystem, - LocaleSystem localeSystem, - DBSystem databaseSystem, - CacheSystem cacheSystem, - ListenerSystem listenerSystem, - TaskSystem taskSystem, - InfoSystem infoSystem, - ServerInfo serverInfo, - WebServerSystem webServerSystem, - Processing processing, - ImportSystem importSystem, - ExportSystem exportSystem, - HtmlUtilities htmlUtilities, - HookHandler hookHandler, - ExtensionServiceImplementation extensionService, - QueryServiceImplementation queryService, - PlanAPI planAPI, - ErrorHandler errorHandler - ) { - this.files = files; - this.configSystem = configSystem; - this.versionCheckSystem = versionCheckSystem; - this.localeSystem = localeSystem; - this.databaseSystem = databaseSystem; - this.cacheSystem = cacheSystem; - this.listenerSystem = listenerSystem; - this.taskSystem = taskSystem; - this.infoSystem = infoSystem; - this.serverInfo = serverInfo; - this.webServerSystem = webServerSystem; - this.processing = processing; - this.importSystem = importSystem; - this.exportSystem = exportSystem; - this.htmlUtilities = htmlUtilities; - this.hookHandler = hookHandler; - this.extensionService = extensionService; - this.queryService = queryService; - this.planAPI = planAPI; - this.errorHandler = errorHandler; - } - - @Override - public void enable() throws EnableException { - CapabilityServiceImplementation.initialize(); - - enableSystems( - files, - configSystem, - localeSystem, - versionCheckSystem, - databaseSystem, - webServerSystem, - processing, - serverInfo, - importSystem, - exportSystem, - infoSystem, - cacheSystem, - listenerSystem, - taskSystem, - hookHandler - ); - queryService.register(); - extensionService.register(); - enabled = true; - } - - private void enableSystems(SubSystem... systems) throws EnableException { - for (SubSystem system : systems) { - system.enable(); - } - } - - @Override - public void disable() { - enabled = false; - disableSystems( - taskSystem, - hookHandler, - cacheSystem, - listenerSystem, - importSystem, - exportSystem, - processing, - databaseSystem, - webServerSystem, - infoSystem, - serverInfo, - localeSystem, - configSystem, - files, - versionCheckSystem - ); - } - - private void disableSystems(SubSystem... systems) { - for (SubSystem system : systems) { - try { - if (system != null) { - system.disable(); - } - } catch (Exception e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - } - - // Accessor methods. - - public VersionCheckSystem getVersionCheckSystem() { - return versionCheckSystem; - } - - public ConfigSystem getConfigSystem() { - return configSystem; - } - - public PlanFiles getPlanFiles() { - return files; - } - - public DBSystem getDatabaseSystem() { - return databaseSystem; - } - - public ListenerSystem getListenerSystem() { - return listenerSystem; - } - - public TaskSystem getTaskSystem() { - return taskSystem; - } - - public WebServerSystem getWebServerSystem() { - return webServerSystem; - } - - public ImportSystem getImportSystem() { - return importSystem; - } - - public ExportSystem getExportSystem() { - return exportSystem; - } - - public ServerInfo getServerInfo() { - return serverInfo; - } - - public CacheSystem getCacheSystem() { - return cacheSystem; - } - - public InfoSystem getInfoSystem() { - return infoSystem; - } - - public HookHandler getHookHandler() { - return hookHandler; - } - - public PlanAPI getPlanAPI() { - return planAPI; - } - - public Processing getProcessing() { - return processing; - } - - public LocaleSystem getLocaleSystem() { - return localeSystem; - } - - public HtmlUtilities getHtmlUtilities() { - return htmlUtilities; - } - - public boolean isEnabled() { - return enabled; - } - - public ExtensionService getExtensionService() { - return extensionService; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/SubSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/SubSystem.java deleted file mode 100644 index 01a19b807..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/SubSystem.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system; - -import com.djrapitops.plan.api.exceptions.EnableException; - -/** - * Represents a system that can be enabled and disabled. - * - * @author Rsl1122 - */ -public interface SubSystem { - - /** - * Performs enable actions for the subsystem. - * - * @throws EnableException If an error occurred during enable and it is fatal to the subsystem. - */ - void enable() throws EnableException; - - /** - * Performs disable actions for the subsystem - */ - void disable(); - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/afk/AFKTracker.java b/Plan/common/src/main/java/com/djrapitops/plan/system/afk/AFKTracker.java deleted file mode 100644 index fc8bab177..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/afk/AFKTracker.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.afk; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.TimeSettings; - -import java.util.*; - -/** - * Keeps track how long player has been afk during a session - * - * @author Rsl1122 - */ -public class AFKTracker { - - private final Set usedAFKCommand; - private final Map lastMovement; - private final PlanConfig config; - - public AFKTracker(PlanConfig config) { - this.config = config; - usedAFKCommand = new HashSet<>(); - lastMovement = new HashMap<>(); - } - - public void hasIgnorePermission(UUID uuid) { - lastMovement.put(uuid, -1L); - } - - public void usedAfkCommand(UUID uuid, long time) { - usedAFKCommand.add(uuid); - lastMovement.put(uuid, time - config.get(TimeSettings.AFK_THRESHOLD)); - } - - public void performedAction(UUID uuid, long time) { - Long lastMoved = lastMovement.getOrDefault(uuid, time); - if (lastMoved == -1) { - return; - } - lastMovement.put(uuid, time); - - try { - if (time - lastMoved < config.get(TimeSettings.AFK_THRESHOLD)) { - // Threshold not crossed, no action required. - return; - } - - long removeAfkCommandEffect = usedAFKCommand.contains(uuid) ? config.get(TimeSettings.AFK_THRESHOLD) : 0; - long timeAFK = time - lastMoved - removeAfkCommandEffect; - - Optional cachedSession = SessionCache.getCachedSession(uuid); - if (!cachedSession.isPresent()) { - return; - } - Session session = cachedSession.get(); - session.addAFKTime(timeAFK); - } finally { - usedAFKCommand.remove(uuid); - } - } - - public void loggedOut(UUID uuid, long time) { - performedAction(uuid, time); - lastMovement.remove(uuid); - usedAFKCommand.remove(uuid); - } - - public boolean isAfk(UUID uuid) { - long time = System.currentTimeMillis(); - - Long lastMoved = lastMovement.get(uuid); - if (lastMoved == null || lastMoved == -1) { - return false; - } - return time - lastMoved > config.get(TimeSettings.AFK_THRESHOLD); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java deleted file mode 100644 index 593c3c668..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.cache; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.SubSystem; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * System that holds data caches of the plugin. - * - * @author Rsl1122 - */ -@Singleton -public class CacheSystem implements SubSystem { - - private final SessionCache sessionCache; - private final NicknameCache nicknameCache; - private final GeolocationCache geolocationCache; - - @Inject - public CacheSystem( - SessionCache sessionCache, - NicknameCache nicknameCache, - GeolocationCache geolocationCache - ) { - this.sessionCache = sessionCache; - this.nicknameCache = nicknameCache; - this.geolocationCache = geolocationCache; - } - - @Override - public void enable() throws EnableException { - nicknameCache.enable(); - geolocationCache.enable(); - } - - @Override - public void disable() { - geolocationCache.clearCache(); - } - - public NicknameCache getNicknameCache() { - return nicknameCache; - } - - public GeolocationCache getGeolocationCache() { - return geolocationCache; - } - - public SessionCache getSessionCache() { - return sessionCache; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java b/Plan/common/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java deleted file mode 100644 index 9f26e20f6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.cache; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DataGatheringSettings; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.maxmind.geoip2.DatabaseReader; -import com.maxmind.geoip2.exception.GeoIp2Exception; -import com.maxmind.geoip2.model.CountryResponse; -import com.maxmind.geoip2.record.Country; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.URL; -import java.net.UnknownHostException; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; -import java.nio.file.Files; -import java.util.HashMap; -import java.util.Map; -import java.util.zip.GZIPInputStream; - -/** - * This class contains the geolocation cache. - *

- * It caches all IPs with their matching country. - * - * @author Fuzzlemann - */ -@Singleton -public class GeolocationCache implements SubSystem { - - private final Locale locale; - private final PlanFiles files; - private final PlanConfig config; - private final PluginLogger logger; - private final Map cached; - - private File geolocationDB; - - @Inject - public GeolocationCache( - Locale locale, - PlanFiles files, - PlanConfig config, - PluginLogger logger - ) { - this.locale = locale; - this.files = files; - this.config = config; - this.logger = logger; - - this.cached = new HashMap<>(); - } - - @Override - public void enable() throws EnableException { - geolocationDB = files.getFileFromPluginFolder("GeoIP.dat"); - if (config.isTrue(DataGatheringSettings.GEOLOCATIONS)) { - try { - checkDB(); - } catch (UnknownHostException e) { - logger.error(locale.getString(PluginLang.ENABLE_NOTIFY_GEOLOCATIONS_INTERNET_REQUIRED)); - } catch (IOException e) { - throw new EnableException(locale.getString(PluginLang.ENABLE_FAIL_GEODB_WRITE), e); - } - } else { - logger.log(L.INFO_COLOR, "§e" + locale.getString(PluginLang.ENABLE_NOTIFY_GEOLOCATIONS_DISABLED)); - } - } - - /** - * Retrieves the country in full length (e.g. United States) from the IP Address. - *

- * This method uses {@code cached}, every first access is getting cached and then retrieved later. - * - * @param ipAddress The IP Address from which the country is retrieved - * @return The name of the country in full length. - *

- * An exception from that rule is when the country is unknown or the retrieval of the country failed in any way, - * if that happens, "Not Known" will be returned. - * @see #getUnCachedCountry(String) - */ - public String getCountry(String ipAddress) { - String country = getCachedCountry(ipAddress); - - if (country != null) { - return country; - } else { - country = getUnCachedCountry(ipAddress); - cached.put(ipAddress, country); - - return country; - } - } - - /** - * Returns the cached country - * - * @param ipAddress The IP Address which is retrieved out of the cache - * @return The cached country, {@code null} if the country is not cached - */ - private String getCachedCountry(String ipAddress) { - return cached.get(ipAddress); - } - - /** - * Retrieves the country in full length (e.g. United States) from the IP Address. - *

- * This product includes GeoLite2 data created by MaxMind, available from - * http://www.maxmind.com. - * - * @param ipAddress The IP Address from which the country is retrieved - * @return The name of the country in full length. - *

- * An exception from that rule is when the country is unknown or the retrieval of the country failed in any way, - * if that happens, "Not Known" will be returned. - * @see http://maxmind.com - * @see #getCountry(String) - */ - private String getUnCachedCountry(String ipAddress) { - if ("127.0.0.1".equals(ipAddress)) { - return "Local Machine"; - } - try { - checkDB(); - - try ( - // See https://github.com/maxmind/MaxMind-DB-Reader-java#file-lock-on-windows - // for why InputStream is being used here instead. - InputStream in = Files.newInputStream(geolocationDB.toPath()); - DatabaseReader reader = new DatabaseReader.Builder(in).build() - ) { - InetAddress inetAddress = InetAddress.getByName(ipAddress); - - CountryResponse response = reader.country(inetAddress); - Country country = response.getCountry(); - String countryName = country.getName(); - - return countryName != null ? countryName : "Not Known"; - } - - } catch (IOException | GeoIp2Exception e) { - return "Not Known"; - } - } - - /** - * Checks if the DB exists, if not, it downloads it - * - * @throws IOException when an error at download or saving the DB happens - */ - private void checkDB() throws IOException { - if (geolocationDB.exists()) { - return; - } - URL downloadSite = new URL("http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz"); - try ( - InputStream in = downloadSite.openStream(); - GZIPInputStream gzipIn = new GZIPInputStream(in); - ReadableByteChannel rbc = Channels.newChannel(gzipIn); - FileOutputStream fos = new FileOutputStream(geolocationDB.getAbsoluteFile()); - FileChannel channel = fos.getChannel() - ) { - channel.transferFrom(rbc, 0, Long.MAX_VALUE); - } - } - - /** - * Checks if the IP Address is cached - * - * @param ipAddress The IP Address which is checked - * @return true if the IP Address is cached - */ - boolean isCached(String ipAddress) { - return cached.containsKey(ipAddress); - } - - @Override - public void disable() { - cached.clear(); - } - - /** - * Clears the cache - */ - public void clearCache() { - cached.clear(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/cache/NicknameCache.java b/Plan/common/src/main/java/com/djrapitops/plan/system/cache/NicknameCache.java deleted file mode 100644 index b793ec7fe..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/cache/NicknameCache.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.cache; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.db.access.queries.objects.NicknameQueries; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -/** - * Used for caching nicknames when the player is online. - * - * @author Rsl1122 - */ -@Singleton -public class NicknameCache implements SubSystem { - - private final DBSystem dbSystem; - private final ServerInfo serverInfo; - private final ErrorHandler errorHandler; - - private final Map displayNames; - - @Inject - public NicknameCache( - DBSystem dbSystem, - ServerInfo serverInfo, - ErrorHandler errorHandler - ) { - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.errorHandler = errorHandler; - displayNames = new HashMap<>(); - } - - @Override - public void enable() { - // Nothing to enable - } - - @Override - public void disable() { - displayNames.clear(); - } - - public void removeDisplayName(UUID uuid) { - displayNames.remove(uuid); - } - - /** - * Used to get the player display name in the cache. - *

- * If not cached, one from the database will be cached. - * - * @param uuid UUID of the player. - * @return latest displayName or null if none are saved. - */ - public String getDisplayName(UUID uuid) { - String cached = displayNames.get(uuid); - - if (cached == null) { - cached = updateFromDatabase(uuid, cached); - } - return cached; - } - - private String updateFromDatabase(UUID uuid, String cached) { - try { - Optional latest = dbSystem.getDatabase().query( - NicknameQueries.fetchLastSeenNicknameOfPlayer(uuid, serverInfo.getServerUUID()) - ); - if (latest.isPresent()) { - cached = latest.get().getName(); - displayNames.put(uuid, cached); - } - } catch (DBOpException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - return cached; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java b/Plan/common/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java deleted file mode 100644 index f1df66f91..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.cache; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.google.common.collect.ImmutableMap; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -/** - * This class is used to store active sessions of players in memory. - * - * @author Rsl1122 - */ -@Singleton -public class SessionCache { - - private static final Map ACTIVE_SESSIONS = new HashMap<>(); - - @Inject - public SessionCache() { - // Dagger requires empty inject constructor - } - - public static Map getActiveSessions() { - return ImmutableMap.copyOf(ACTIVE_SESSIONS); - } - - public static void clear() { - ACTIVE_SESSIONS.clear(); - } - - public static void refreshActiveSessionsState() { - for (Session session : ACTIVE_SESSIONS.values()) { - session.getUnsafe(SessionKeys.WORLD_TIMES).updateState(System.currentTimeMillis()); - } - } - - /** - * Used to get the Session of the player in the sessionCache. - * - * @param playerUUID UUID of the player. - * @return Optional with the session inside it if found. - */ - public static Optional getCachedSession(UUID playerUUID) { - return Optional.ofNullable(ACTIVE_SESSIONS.get(playerUUID)); - } - - /** - * Cache a new session. - * - * @param playerUUID UUID of the player - * @param session Session to cache. - * @return Optional: previous session. Recipients of this object should decide if it needs to be saved. - */ - public Optional cacheSession(UUID playerUUID, Session session) { - if (getCachedSession(playerUUID).isPresent()) { - return endSession(playerUUID, session.getUnsafe(SessionKeys.START)); - } - ACTIVE_SESSIONS.put(playerUUID, session); - return Optional.empty(); - } - - /** - * End a session and save it to database. - * - * @param playerUUID UUID of the player. - * @param time Time the session ended. - * @return Optional: ended session. Recipients of this object should decide if it needs to be saved. - */ - public Optional endSession(UUID playerUUID, long time) { - Session session = ACTIVE_SESSIONS.get(playerUUID); - if (session == null || session.getUnsafe(SessionKeys.START) > time) { - return Optional.empty(); - } - removeSessionFromCache(playerUUID); - session.endSession(time); - return Optional.of(session); - } - - protected void removeSessionFromCache(UUID playerUUID) { - ACTIVE_SESSIONS.remove(playerUUID); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/DBSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/DBSystem.java deleted file mode 100644 index e180e0061..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/DBSystem.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.database; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.H2DB; -import com.djrapitops.plan.db.SQLiteDB; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plugin.benchmarking.Timings; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Singleton; -import java.util.HashSet; -import java.util.Set; - -/** - * System that holds the active databases. - * - * @author Rsl1122 - */ -@Singleton -public abstract class DBSystem implements SubSystem { - - protected final Locale locale; - private final SQLiteDB.Factory sqLiteFactory; - private final H2DB.Factory h2Factory; - protected final PluginLogger logger; - protected final Timings timings; - protected final ErrorHandler errorHandler; - - protected Database db; - protected Set databases; - - public DBSystem( - Locale locale, - SQLiteDB.Factory sqLiteDB, - H2DB.Factory h2Factory, - PluginLogger logger, - Timings timings, - ErrorHandler errorHandler - ) { - this.locale = locale; - this.sqLiteFactory = sqLiteDB; - this.h2Factory = h2Factory; - this.logger = logger; - this.timings = timings; - this.errorHandler = errorHandler; - databases = new HashSet<>(); - } - - public Database getActiveDatabaseByName(String dbName) { - return DBType.getForName(dbName) - .map(this::getActiveDatabaseByType) - .orElseThrow(() -> new IllegalArgumentException(locale.getString(PluginLang.ENABLE_FAIL_WRONG_DB, dbName))); - } - - public Database getActiveDatabaseByType(DBType type) { - for (Database database : getDatabases()) { - if (database.getType() == type) { - return database; - } - } - throw new IllegalArgumentException(locale.getString(PluginLang.ENABLE_FAIL_WRONG_DB, type != null ? type.getName() : "null")); - } - - public Set getDatabases() { - return databases; - } - - @Override - public void disable() { - if (db != null) { - db.close(); - } - } - - public Database getDatabase() { - return db; - } - - @Override - public void enable() throws EnableException { - try { - db.init(); - logger.info(locale.getString(PluginLang.ENABLED_DATABASE, db.getType().getName())); - } catch (DBInitException e) { - Throwable cause = e.getCause(); - String message = cause == null ? e.getMessage() : cause.getMessage(); - throw new EnableException(db.getType().getName() + " init failure: " + message, cause); - } - } - - public void setActiveDatabase(Database db) { - this.db.close(); - this.db = db; - } - - public SQLiteDB.Factory getSqLiteFactory() { - return sqLiteFactory; - } - - public H2DB.Factory getH2Factory() { - return h2Factory; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/ProxyDBSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/ProxyDBSystem.java deleted file mode 100644 index c1655dce2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/ProxyDBSystem.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.database; - -import com.djrapitops.plan.db.H2DB; -import com.djrapitops.plan.db.MySQLDB; -import com.djrapitops.plan.db.SQLiteDB; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plugin.benchmarking.Timings; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Bungee Database system that initializes MySQL object. - * - * @author Rsl1122 - */ -@Singleton -public class ProxyDBSystem extends DBSystem { - - @Inject - public ProxyDBSystem( - Locale locale, - MySQLDB mySQLDB, - SQLiteDB.Factory sqLiteDB, - H2DB.Factory h2DB, - PluginLogger logger, - Timings timings, - ErrorHandler errorHandler - ) { - super(locale, sqLiteDB, h2DB, logger, timings, errorHandler); - databases.add(mySQLDB); - db = mySQLDB; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java deleted file mode 100644 index 0682c63f4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.database.databases.operation; - -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.UserInfo; -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.containers.ServerContainer; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.settings.config.Config; - -import java.util.*; - -/** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ -@Deprecated -public interface FetchOperations { - - /** - * Used to get a NetworkContainer, some limitations apply to values returned by DataContainer keys. - *

- * Limitations: - * - Bungee ServerContainer does not support: ServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_DEATHS, PLAYER_KILL_COUNT - * - Bungee ServerContainer ServerKeys.TPS only contains playersOnline values - * - NetworkKeys.PLAYERS PlayerContainers: - * - do not support: PlayerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_DEATHS, PLAYER_KILL_COUNT - * - PlayerKeys.PER_SERVER does not support: PerServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_DEATHS, PLAYER_KILL_COUNT - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @return a new NetworkContainer. - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.queries.containers.NetworkContainerQuery} - */ - @Deprecated - NetworkContainer getNetworkContainer(); - - /** - * Used to get a ServerContainer, some limitations apply to values returned by DataContainer keys. - *

- * Limitations: - * - ServerKeys.PLAYERS PlayerContainers PlayerKeys.PER_SERVER only contains information about the queried server. - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @param serverUUID UUID of the Server. - * @return a new ServerContainer. - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.queries.containers.ServerContainerQuery}. - */ - @Deprecated - ServerContainer getServerContainer(UUID serverUUID); - - /** - * Used to get PlayerContainers of all players on the network, some limitations apply to DataContainer keys. - *

- * Limitations: - * - PlayerContainers do not support: PlayerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT - * - PlayerContainers PlayerKeys.PER_SERVER does not support: PerServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @return a list of PlayerContainers in Plan database. - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.queries.containers.AllPlayerContainersQuery}. - */ - @Deprecated - List getAllPlayerContainers(); - - /** - * Used to get a PlayerContainer of a specific player. - *

- * Blocking methods are not called until DataContainer getter methods are called. - * - * @param uuid UUID of the player. - * @return a new PlayerContainer. - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.queries.containers.PlayerContainerQuery}. - */ - @Deprecated - PlayerContainer getPlayerContainer(UUID uuid); - - // UUIDs - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Set getSavedUUIDs(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Set getSavedUUIDs(UUID server); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Map getServerNames(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Optional getServerUUID(String serverName); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - UUID getUuidOf(String playerName); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - WebUser getWebUser(String username); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Optional getServerName(UUID serverUUID); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Optional getBungeeInformation(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Optional getServerID(UUID serverUUID); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - List getTPSData(UUID serverUUID); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Map>> getSessionsWithNoExtras(); - - /** - * @deprecated It was not possible to keep this compatible so now empty map is returned. - */ - @Deprecated - Map getUsers(); - - /** - * @deprecated Now empty map is returned. - */ - @Deprecated - Map getLastSeenForAllPlayers(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Map> getAllGeoInfo(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Map getPlayerNames(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - String getPlayerName(UUID playerUUID); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - List getNicknames(UUID uuid); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Map getBukkitServers(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - List getWebUsers(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - List getServers(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - List getServerUUIDs(); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Map> getPlayersOnlineForServers(Collection servers); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Map getPlayersRegisteredForServers(Collection servers); - - /** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ - @Deprecated - Optional getNewConfig(long updatedAfter, UUID serverUUID); -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java deleted file mode 100644 index 6af93e9ac..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.database.databases.sql.operation; - -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.UserInfo; -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.containers.ServerContainer; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.ServerAggregateQueries; -import com.djrapitops.plan.db.access.queries.containers.ContainerFetchQueries; -import com.djrapitops.plan.db.access.queries.objects.*; -import com.djrapitops.plan.system.database.databases.operation.FetchOperations; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.settings.config.Config; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * @deprecated Bad API, replaced with {@link com.djrapitops.plan.db.access.Query} objects. - */ -@Deprecated -public class SQLFetchOps implements FetchOperations { - - private final Database db; - - public SQLFetchOps(Database db) { - this.db = db; - } - - @Override - public NetworkContainer getNetworkContainer() { - return db.query(ContainerFetchQueries.fetchNetworkContainer()); - } - - @Override - public ServerContainer getServerContainer(UUID serverUUID) { - return db.query(ContainerFetchQueries.fetchServerContainer(serverUUID)); - } - - @Override - public List getAllPlayerContainers() { - return db.query(ContainerFetchQueries.fetchAllPlayerContainers()); - } - - @Override - public PlayerContainer getPlayerContainer(UUID uuid) { - return db.query(ContainerFetchQueries.fetchPlayerContainer(uuid)); - } - - @Override - public Set getSavedUUIDs() { - return db.query(UserIdentifierQueries.fetchAllPlayerUUIDs()); - } - - @Override - public Set getSavedUUIDs(UUID serverUUID) { - return db.query(UserIdentifierQueries.fetchPlayerUUIDsOfServer(serverUUID)); - } - - @Override - public Map getServerNames() { - return db.query(ServerQueries.fetchServerNames()); - } - - @Override - public Optional getServerUUID(String serverName) { - return db.query(ServerQueries.fetchServerMatchingIdentifier(serverName)) - .map(Server::getUuid); - } - - @Override - public UUID getUuidOf(String playerName) { - return db.query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName)).orElse(null); - } - - @Override - public WebUser getWebUser(String username) { - return db.query(WebUserQueries.fetchWebUser(username)).orElse(null); - } - - @Override - public List getTPSData(UUID serverUUID) { - return db.query(TPSQueries.fetchTPSDataOfServer(serverUUID)); - } - - @Override - public Map>> getSessionsWithNoExtras() { - return db.query(SessionQueries.fetchAllSessionsWithoutKillOrWorldData()); - } - - @Override - public Map getUsers() { - return new HashMap<>(); - } - - @Override - public Map getLastSeenForAllPlayers() { - return new HashMap<>(); - } - - @Override - public Map> getAllGeoInfo() { - return db.query(GeoInfoQueries.fetchAllGeoInformation()); - } - - @Override - public Map getPlayerNames() { - return db.query(UserIdentifierQueries.fetchAllPlayerNames()); - } - - @Override - public String getPlayerName(UUID playerUUID) { - return db.query(UserIdentifierQueries.fetchPlayerNameOf(playerUUID)).orElse(null); - } - - @Override - public Optional getServerName(UUID serverUUID) { - return db.query(ServerQueries.fetchServerMatchingIdentifier(serverUUID)).map(Server::getName); - } - - @Override - public List getNicknames(UUID playerUUID) { - return db.query(NicknameQueries.fetchNicknameDataOfPlayer(playerUUID)).stream() - .map(Nickname::getName).collect(Collectors.toList()); - } - - @Override - public Optional getBungeeInformation() { - return db.query(ServerQueries.fetchProxyServerInformation()); - } - - @Override - public Optional getServerID(UUID serverUUID) { - return db.query(ServerQueries.fetchServerMatchingIdentifier(serverUUID)).map(Server::getId); - } - - @Override - public Map getBukkitServers() { - return db.query(ServerQueries.fetchPlanServerInformation()).entrySet().stream() - .filter(entry -> entry.getValue().isNotProxy()) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - @Override - public List getWebUsers() { - return new ArrayList<>(db.query(WebUserQueries.fetchAllPlanWebUsers())); - } - - @Override - public List getServers() { - List servers = new ArrayList<>(db.query(ServerQueries.fetchPlanServerInformation()).values()); - Collections.sort(servers); - return servers; - } - - @Override - public List getServerUUIDs() { - return new ArrayList<>(db.query(ServerQueries.fetchPlanServerInformation()).keySet()); - } - - @Override - public Map> getPlayersOnlineForServers(Collection servers) { - return db.query(TPSQueries.fetchPlayerOnlineDataOfServers(servers)); - } - - @Override - public Map getPlayersRegisteredForServers(Collection servers) { - return db.query(ServerAggregateQueries.serverUserCounts()); - } - - @Override - public Optional getNewConfig(long updatedAfter, UUID serverUUID) { - return db.query(new NewerConfigQuery(serverUUID, updatedAfter)); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/export/ExportSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/export/ExportSystem.java deleted file mode 100644 index 47aa56180..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/export/ExportSystem.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.export; - -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.ExportSettings; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * System in charge of exporting html. - * - * @author Rsl1122 - */ -@Singleton -public class ExportSystem implements SubSystem { - - private final PlanConfig config; - private final ServerInfo serverInfo; - private final Processing processing; - private final HtmlExport htmlExport; - private final ConnectionSystem connectionSystem; - - @Inject - public ExportSystem( - PlanConfig config, - ServerInfo serverInfo, - Processing processing, - HtmlExport htmlExport, - ConnectionSystem connectionSystem - ) { - this.config = config; - this.serverInfo = serverInfo; - this.processing = processing; - this.htmlExport = htmlExport; - this.connectionSystem = connectionSystem; - } - - @Override - public void enable() { - if (serverInfo.getServer().isNotProxy() && connectionSystem.isServerAvailable()) { - return; - } - if (config.isTrue(ExportSettings.JS_AND_CSS)) { - processing.submitNonCritical(htmlExport::exportJs); - processing.submitNonCritical(htmlExport::exportCss); - processing.submitNonCritical(htmlExport::exportPlugins); - } - if (config.isTrue(ExportSettings.PLAYERS_PAGE)) { - processing.submitNonCritical(htmlExport::exportPlayersPage); - } - if (config.isTrue(ExportSettings.PLAYER_PAGES)) { - processing.submitNonCritical(htmlExport::exportAvailablePlayers); - } - if (config.isTrue(ExportSettings.SERVER_PAGE)) { - processing.submitNonCritical(() -> { - htmlExport.cacheNetworkPage(); - htmlExport.exportAvailableServerPages(); - }); - } - } - - @Override - public void disable() { - // Nothing to disable - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/export/HtmlExport.java b/Plan/common/src/main/java/com/djrapitops/plan/system/export/HtmlExport.java deleted file mode 100644 index 844955ecb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/export/HtmlExport.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.export; - -import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.data.container.BaseUser; -import com.djrapitops.plan.db.access.queries.objects.BaseUserQueries; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.ExportSettings; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.pages.json.JSONFactory; -import com.djrapitops.plan.system.webserver.response.pages.NetworkPageResponse; -import com.djrapitops.plan.utilities.html.pages.InspectPage; -import com.djrapitops.plan.utilities.html.pages.NetworkPage; -import com.djrapitops.plan.utilities.html.pages.PageFactory; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.file.Files; -import java.util.*; - -/** - * Class responsible for Html Export task. - * - * @author Rsl1122 - */ -@Singleton -public class HtmlExport extends SpecificExport { - - private final PlanConfig config; - private final Theme theme; - private final PlanFiles files; - private final DBSystem dbSystem; - private final PageFactory pageFactory; - private final ConnectionSystem connectionSystem; - private final ErrorHandler errorHandler; - - @Inject - public HtmlExport( - PlanFiles files, - PlanConfig config, - Theme theme, - DBSystem dbSystem, - PageFactory pageFactory, - JSONFactory jsonFactory, - ServerInfo serverInfo, - ConnectionSystem connectionSystem, - ErrorHandler errorHandler - ) { - super(files, jsonFactory, serverInfo); - this.config = config; - this.theme = theme; - this.files = files; - this.dbSystem = dbSystem; - this.pageFactory = pageFactory; - this.connectionSystem = connectionSystem; - this.errorHandler = errorHandler; - } - - @Override - protected String getPath() { - return config.get(ExportSettings.HTML_EXPORT_PATH); - } - - public void exportServer(UUID serverUUID) { - if (serverInfo.getServer().isNotProxy() && connectionSystem.isServerAvailable()) { - return; - } - dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverUUID)) - .map(Server::getName) - .ifPresent(serverName -> { - try { - exportAvailableServerPage(serverUUID, serverName); - } catch (IOException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - }); - } - - public void exportPlayerPage(UUID playerUUID) { - Optional name = dbSystem.getDatabase().query(UserIdentifierQueries.fetchPlayerNameOf(playerUUID)); - exportPlayerPage(playerUUID, name.orElse("Unknown")); - } - - public void exportPlayerPage(UUID playerUUID, String playerName) { - InspectPage playerPage = pageFactory.inspectPage(playerUUID); - try { - exportPlayerPage(playerName, playerPage.toHtml()); - } catch (ParseException | IOException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - - public void exportCachedPlayerPage(UUID playerUUID) { - if (serverInfo.getServer().isNotProxy() && connectionSystem.isServerAvailable()) { - return; - } - - dbSystem.getDatabase().query(UserIdentifierQueries.fetchPlayerNameOf(playerUUID)) - .ifPresent(playerName -> { - try { - exportAvailablePlayerPage(playerUUID, playerName); - } catch (IOException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - }); - } - - public void exportPlayersPage() { - try { - String html = pageFactory.playersPage().toHtml() - .replace("href=\"plugins/", "href=\"../plugins/") - .replace("href=\"css/", "href=\"../css/") - .replace("src=\"plugins/", "src=\"../plugins/") - .replace("src=\"js/", "src=\"../js/"); - List lines = Arrays.asList(html.split("\n")); - - File htmlLocation = new File(getFolder(), "players"); - Verify.isTrue(htmlLocation.exists() && htmlLocation.isDirectory() || htmlLocation.mkdirs(), - () -> new FileNotFoundException("Output folder could not be created at" + htmlLocation.getAbsolutePath())); - File exportFile = new File(htmlLocation, "index.html"); - export(exportFile, lines); - } catch (IOException | DBOpException | ParseException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - public void exportAvailablePlayers() { - try { - Collection users = dbSystem.getDatabase().query(BaseUserQueries.fetchAllBaseUsers()); - for (BaseUser user : users) { - exportAvailablePlayerPage(user.getUuid(), user.getName()); - } - } catch (IOException | DBOpException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - public void cacheNetworkPage() { - if (serverInfo.getServer().isNotProxy()) { - return; - } - - NetworkPage networkPage = pageFactory.networkPage(); - ResponseCache.cacheResponse(PageId.SERVER.of(serverInfo.getServerUUID()), () -> { - try { - return new NetworkPageResponse(networkPage); - } catch (ParseException e) { - errorHandler.log(L.WARN, this.getClass(), e); - return null; - } - }); - } - - public void exportNetworkPage() { - if (serverInfo.getServer().isNotProxy()) { - return; - } - - cacheNetworkPage(); - try { - exportAvailableServerPage(serverInfo.getServerUUID(), serverInfo.getServer().getName()); - } catch (IOException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - public void exportAvailableServerPages() { - try { - Map serverNames = dbSystem.getDatabase().query(ServerQueries.fetchServerNames()); - - for (Map.Entry entry : serverNames.entrySet()) { - exportAvailableServerPage(entry.getKey(), entry.getValue()); - } - } catch (IOException | DBOpException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - public void exportCss() { - String[] resources = new String[]{ - "web/css/main.css", - "web/css/materialize.css", - "web/css/style.css", - "web/css/themes/all-themes.css" - }; - copyFromJar(resources); - } - - public void exportJs() { - String[] resources = new String[]{ - "web/js/demo.js", - "web/js/admin.js", - "web/js/helpers.js", - "web/js/script.js", - "web/js/charts/activityPie.js", - "web/js/charts/lineGraph.js", - "web/js/charts/horizontalBarGraph.js", - "web/js/charts/stackGraph.js", - "web/js/charts/performanceGraph.js", - "web/js/charts/playerGraph.js", - "web/js/charts/playerGraphNoNav.js", - "web/js/charts/resourceGraph.js", - "web/js/charts/diskGraph.js", - "web/js/charts/tpsGraph.js", - "web/js/charts/worldGraph.js", - "web/js/charts/worldMap.js", - "web/js/charts/punchCard.js", - "web/js/charts/serverPie.js", - "web/js/charts/worldPie.js", - "web/js/charts/healthGauge.js", - "web/js/charts/sessionCalendar.js", - "web/js/charts/onlineActivityCalendar.js" - }; - copyFromJar(resources); - - try { - String demo = files.getCustomizableResourceOrDefault("web/js/demo.js") - .asString() - .replace("${defaultTheme}", theme.getValue(ThemeVal.THEME_DEFAULT)); - List lines = Arrays.asList(demo.split("\n")); - File outputFolder = new File(getFolder(), "js"); - Verify.isTrue(outputFolder.exists() && outputFolder.isDirectory() || outputFolder.mkdirs(), - () -> new FileNotFoundException("Output folder could not be created at " + outputFolder.getAbsolutePath())); - export(new File(outputFolder, "demo.js"), lines); - } catch (IOException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - public void exportPlugins() { - String[] resources = new String[]{ - "web/plugins/node-waves/waves.css", - "web/plugins/node-waves/waves.js", - "web/plugins/animate-css/animate.css", - "web/plugins/jquery-slimscroll/jquery.slimscroll.js", - "web/plugins/jquery/jquery.min.js", - "web/plugins/fullcalendar/fullcalendar.min.js", - "web/plugins/fullcalendar/fullcalendar.min.css", - "web/plugins/momentjs/moment.js", - }; - copyFromJar(resources); - } - - private void copyFromJar(String[] resources) { - for (String resource : resources) { - try { - copyFromJar(resource); - } catch (IOException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - } - - private void copyFromJar(String resource) throws IOException { - List lines = files.getCustomizableResourceOrDefault(resource).asLines(); - - File to = new File(getFolder(), resource.replace("web/", "").replace("/", File.separator)); - File locationFolder = to.getParentFile(); - - Verify.isTrue(locationFolder.exists() && locationFolder.isDirectory() || locationFolder.mkdirs(), - () -> new FileNotFoundException("Output folder could not be created at" + locationFolder.getAbsolutePath())); - - if (to.exists()) { - Files.delete(to.toPath()); - if (!to.createNewFile()) { - return; - } - } - - export(to, lines); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/export/JSONExport.java b/Plan/common/src/main/java/com/djrapitops/plan/system/export/JSONExport.java deleted file mode 100644 index 04ddf947c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/export/JSONExport.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.export; - -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.ExportSettings; -import com.djrapitops.plan.system.webserver.pages.json.JSONFactory; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.io.IOException; -import java.net.URLEncoder; -import java.util.Collections; -import java.util.UUID; - -/** - * Class in charge of exporting json files. - * - * @author Rsl1122 - */ -@Singleton -public class JSONExport extends SpecificExport { - - private final PlanConfig config; - private final DBSystem dbSystem; - private final ResponseFactory responseFactory; - private final ErrorHandler errorHandler; - - @Inject - public JSONExport( - PlanFiles files, - PlanConfig config, - DBSystem dbSystem, - ServerInfo serverInfo, - JSONFactory jsonFactory, - ResponseFactory responseFactory, - ErrorHandler errorHandler - ) { - super(files, jsonFactory, serverInfo); - this.config = config; - this.dbSystem = dbSystem; - this.responseFactory = responseFactory; - this.errorHandler = errorHandler; - } - - @Override - protected String getPath() { - return config.get(ExportSettings.JSON_EXPORT_PATH); - } - - public void exportPlayerJSON(UUID playerUUID) { - String json = responseFactory.rawPlayerPageResponse(playerUUID).getContent(); - - dbSystem.getDatabase().query(UserIdentifierQueries.fetchPlayerNameOf(playerUUID)) - .ifPresent(playerName -> { - try { - File htmlLocation = getPlayerFolder(); - htmlLocation.mkdirs(); - File exportFile = new File(htmlLocation, URLEncoder.encode(playerName, "UTF-8") + ".json"); - - export(exportFile, Collections.singletonList(json)); - } catch (IOException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - }); - } - - public void exportServerJSON(UUID serverUUID) { - String json = responseFactory.rawServerPageResponse(serverUUID).getContent(); - dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverUUID)) - .map(Server::getName) - .ifPresent(serverName -> { - try { - File htmlLocation = getServerFolder(); - htmlLocation.mkdirs(); - File exportFile = new File(htmlLocation, URLEncoder.encode(serverName, "UTF-8") + ".json"); - - export(exportFile, Collections.singletonList(json)); - } catch (IOException e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/export/SpecificExport.java b/Plan/common/src/main/java/com/djrapitops/plan/system/export/SpecificExport.java deleted file mode 100644 index b10b48bd9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/export/SpecificExport.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.export; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.pages.json.JSONFactory; -import com.djrapitops.plan.system.webserver.response.Response; - -import java.io.File; -import java.io.IOException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -/** - * Abstract Html Export Task. - * - * @author Rsl1122 - */ -public abstract class SpecificExport { - - private final PlanFiles files; - private final JSONFactory jsonFactory; // Hacky, TODO export needs a rework - protected final ServerInfo serverInfo; - - SpecificExport( - PlanFiles files, - JSONFactory jsonFactory, ServerInfo serverInfo - ) { - this.files = files; - this.jsonFactory = jsonFactory; - this.serverInfo = serverInfo; - } - - protected File getFolder() { - File folder; - - String path = getPath(); - boolean isAbsolute = Paths.get(path).isAbsolute(); - if (isAbsolute) { - folder = new File(path); - } else { - File dataFolder = files.getDataFolder(); - folder = new File(dataFolder, path); - } - - if (!folder.exists() || !folder.isDirectory()) { - folder.mkdirs(); - } - return folder; - } - - protected abstract String getPath(); - - protected void export(File to, List lines) throws IOException { - Files.write(to.toPath(), lines, StandardCharsets.UTF_8, StandardOpenOption.CREATE); - } - - File getServerFolder() { - File server = new File(getFolder(), "server"); - server.mkdirs(); - return server; - } - - File getPlayerFolder() { - File player = new File(getFolder(), "player"); - player.mkdirs(); - return player; - } - - void exportPlayerPage(String playerName, String html) throws IOException { - List lines = Arrays.asList(html.replace("../", "../../").split("\n")); - - File htmlLocation = new File(getPlayerFolder(), URLEncoder.encode(playerName, "UTF-8").replace(".", "%2E")); - htmlLocation.mkdirs(); - File exportFile = new File(htmlLocation, "index.html"); - - export(exportFile, lines); - } - - void exportAvailablePlayerPage(UUID playerUUID, String name) throws IOException { - Response response = ResponseCache.loadResponse(PageId.PLAYER.of(playerUUID)); - if (response == null) { - return; - } - - String html = response.getContent(); - exportPlayerPage(name, html); - } - - void exportAvailableServerPage(UUID serverUUID, String serverName) throws IOException { - - Response response = ResponseCache.loadResponse(PageId.SERVER.of(serverUUID)); - if (response == null) { - return; - } - - String html = response.getContent() - .replace("href=\"plugins/", "href=\"../plugins/") - .replace("href=\"css/", "href=\"../css/") - .replace("src=\"plugins/", "src=\"../plugins/") - .replace("src=\"js/", "src=\"../js/") - .replace("../json/players?serverName=" + serverName, "./players_table.json"); - - File htmlLocation; - if (serverInfo.getServer().isProxy()) { - if (serverUUID.equals(serverInfo.getServerUUID())) { - htmlLocation = new File(getFolder(), "network"); - } else { - htmlLocation = new File(getServerFolder(), URLEncoder.encode(serverName, "UTF-8").replace(".", "%2E")); - html = html.replace("../", "../../"); - exportPlayersTableJSON(htmlLocation, serverUUID); - } - } else { - htmlLocation = getServerFolder(); - exportPlayersTableJSON(htmlLocation, serverUUID); - } - - htmlLocation.mkdirs(); - File exportFile = new File(htmlLocation, "index.html"); - - List lines = Arrays.asList(html.split("\n")); - - export(exportFile, lines); - } - - private void exportPlayersTableJSON(File htmlLocation, UUID serverUUID) throws IOException { - htmlLocation.mkdirs(); - File exportFile = new File(htmlLocation, "players_table.json"); - export(exportFile, Collections.singletonList(jsonFactory.serverPlayersTableJSON(serverUUID))); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/file/FileResource.java b/Plan/common/src/main/java/com/djrapitops/plan/system/file/FileResource.java deleted file mode 100644 index 00e239c71..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/file/FileResource.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.file; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * {@link Resource} implementation for a {@link File}. - * - * @author Rsl1122 - */ -public class FileResource implements Resource { - - private final String resourceName; - private final File file; - - public FileResource(String resourceName, File file) { - this.resourceName = resourceName; - this.file = file; - } - - public static List lines(File file) throws IOException { - List lines = new ArrayList<>(); - if (file != null && file.exists()) { - try (Stream linesStream = Files.lines(file.toPath(), StandardCharsets.UTF_8)) { - lines = linesStream.collect(Collectors.toList()); - } - } - return lines; - } - - @Override - public String getResourceName() { - return resourceName; - } - - @Override - public InputStream asInputStream() throws IOException { - return new FileInputStream(file); - } - - @Override - public List asLines() throws IOException { - return lines(file); - } - - @Override - public String asString() throws IOException { - StringBuilder flat = new StringBuilder(); - try (Scanner scanner = new Scanner(file, "UTF-8")) { - while (scanner.hasNextLine()) { - flat.append(scanner.nextLine()).append("\r\n"); - } - } - return flat.toString(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/file/JarResource.java b/Plan/common/src/main/java/com/djrapitops/plan/system/file/JarResource.java deleted file mode 100644 index 406ff6e79..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/file/JarResource.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.file; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; - -/** - * {@link Resource} implementation for something that is read via InputStream. - * - * @author Rsl1122 - */ -public class JarResource implements Resource { - - private final String resourceName; - private final StreamSupplier streamSupplier; - - public JarResource(String resourceName, StreamSupplier streamSupplier) { - this.resourceName = resourceName; - this.streamSupplier = streamSupplier; - } - - @Override - public InputStream asInputStream() throws IOException { - InputStream stream = streamSupplier.get(); - if (stream == null) { - throw new FileNotFoundException("a Resource was not found inside the jar (" + resourceName + "), " + - "Plan does not support /reload or updates using " + - "Plugin Managers, restart the server and see if the error persists."); - } - return stream; - } - - @Override - public List asLines() throws IOException { - List lines = new ArrayList<>(); - try ( - InputStream inputStream = asInputStream(); - Scanner scanner = new Scanner(inputStream, "UTF-8") - ) { - while (scanner.hasNextLine()) { - lines.add(scanner.nextLine()); - } - } - return lines; - } - - @Override - public String asString() throws IOException { - StringBuilder flat = new StringBuilder(); - try ( - InputStream inputStream = asInputStream(); - Scanner scanner = new Scanner(inputStream, "UTF-8") - ) { - while (scanner.hasNextLine()) { - flat.append(scanner.nextLine()).append("\r\n"); - } - } - return flat.toString(); - } - - @Override - public String getResourceName() { - return resourceName; - } - - interface StreamSupplier { - InputStream get() throws IOException; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/file/PlanFiles.java b/Plan/common/src/main/java/com/djrapitops/plan/system/file/PlanFiles.java deleted file mode 100644 index 14b9f9c82..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/file/PlanFiles.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.file; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.Optional; - -/** - * Abstracts File methods of Plugin classes so that they can be tested without Mocks. - * - * @author Rsl1122 - */ -@Singleton -public class PlanFiles implements SubSystem { - - protected final PlanPlugin plugin; - - private final File dataFolder; - private final File configFile; - - @Inject - public PlanFiles(PlanPlugin plugin) { - this.dataFolder = plugin.getDataFolder(); - this.plugin = plugin; - this.configFile = getFileFromPluginFolder("config.yml"); - } - - public File getDataFolder() { - return dataFolder; - } - - public File getLogsFolder() { - File folder = getFileFromPluginFolder("logs"); - folder.mkdirs(); - return folder; - } - - public File getConfigFile() { - return configFile; - } - - public File getLocaleFile() { - return getFileFromPluginFolder("locale.txt"); - } - - public File getFileFromPluginFolder(String name) { - return new File(dataFolder, name.replace("/", File.separator)); - } - - @Override - public void enable() throws EnableException { - Verify.isTrue((dataFolder.exists() && dataFolder.isDirectory()) || dataFolder.mkdirs(), - () -> new EnableException("Could not create data folder at " + dataFolder.getAbsolutePath())); - try { - Verify.isTrue((configFile.exists() && configFile.isFile()) || configFile.createNewFile(), - () -> new EnableException("Could not create config file at " + configFile.getAbsolutePath())); - } catch (IOException e) { - throw new EnableException("Failed to create config.yml", e); - } - } - - @Override - public void disable() { - // No disable actions necessary. - } - - /** - * Get a file in the jar as a {@link Resource}. - * - * @param resourceName Path to the file inside jar/assets/plan/ folder. - * @return a {@link Resource} for accessing the resource. - */ - public Resource getResourceFromJar(String resourceName) { - return new JarResource("assets/plan/" + resourceName, () -> plugin.getResource("assets/plan/" + resourceName)); - } - - /** - * Get a file from plugin folder as a {@link Resource}. - * - * @param resourceName Path to the file inside the plugin folder. - * @return a {@link Resource} for accessing the resource. - */ - public Resource getResourceFromPluginFolder(String resourceName) { - return new FileResource(resourceName, getFileFromPluginFolder(resourceName)); - } - - /** - * Get a customizable resource from the plugin files or from the jar if one doesn't exist. - * - * @param resourceName Path to the file inside the plugin folder. - * @return a {@link Resource} for accessing the resource, either from the plugin folder or jar. - */ - public Resource getCustomizableResourceOrDefault(String resourceName) { - return attemptToFind(resourceName).map(file -> (Resource) new FileResource(resourceName, file)).orElse(getResourceFromJar(resourceName)); - } - - private Optional attemptToFind(String resourceName) { - if (dataFolder.exists() && dataFolder.isDirectory()) { - - String[] path = resourceName.split("/"); - - Path toFile = dataFolder.getAbsoluteFile().toPath().toAbsolutePath(); - for (String next : path) { - toFile = toFile.resolve(next); - } - - File found = toFile.toFile(); - if (found.exists()) { - return Optional.of(found); - } - } - return Optional.empty(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/file/Resource.java b/Plan/common/src/main/java/com/djrapitops/plan/system/file/Resource.java deleted file mode 100644 index 76f84c14a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/file/Resource.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.file; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -/** - * Interface for accessing plugin resources in jar or plugin files. - * - * @author Rsl1122 - */ -public interface Resource { - - /** - * Get the name of this Resource. - * - * @return Relative file path given to {@link PlanFiles}. - */ - String getResourceName(); - - /** - * Get the resource as an InputStream. - * - * @return InputStream of the resource, not closed automatically. - * @throws IOException If the resource is unavailable. - */ - InputStream asInputStream() throws IOException; - - /** - * Get the resource as lines. - * - * @return Lines of the resource file. - * @throws IOException If the resource is unavailable. - */ - List asLines() throws IOException; - - /** - * Get the resource as a String with each line separated by CRLF newline characters {@code \r\n}. - * - * @return Flat string with each line separated by {@code \r\n}. - * @throws IOException If the resource is unavailable. - */ - String asString() throws IOException; - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/EmptyImportSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/importing/EmptyImportSystem.java deleted file mode 100644 index f2f4e76f6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/EmptyImportSystem.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.importing; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Placeholder for a ImportSystem. - * - * @author Rsl1122 - */ -@Singleton -public class EmptyImportSystem extends ImportSystem { - - @Inject - public EmptyImportSystem() { - // Inject constructor required for dagger - } - - @Override - void registerImporters() { - // No importers to register. - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/ImportSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/importing/ImportSystem.java deleted file mode 100644 index 1c3e48888..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/ImportSystem.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.importing; - -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.importing.importers.Importer; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.*; - -/** - * Abstract representation of an ImportSystem. - * - * @author Rsl1122 - */ -public abstract class ImportSystem implements SubSystem { - - protected Map importers; - - public ImportSystem() { - importers = new HashMap<>(); - } - - @Override - public void enable() { - registerImporters(); - } - - abstract void registerImporters(); - - public void registerImporter(Importer importer) { - Verify.nullCheck(importer, () -> new IllegalArgumentException("Importer cannot be null")); - - importers.put(importer.getName(), importer); - } - - public Optional getImporter(String name) { - return Optional.ofNullable(importers.get(name)); - } - - public List getImporterNames() { - List names = new ArrayList<>(importers.keySet()); - Collections.sort(names); - return names; - } - - @Override - public void disable() { - importers.clear(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/data/ServerImportData.java b/Plan/common/src/main/java/com/djrapitops/plan/system/importing/data/ServerImportData.java deleted file mode 100644 index 1319b15f6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/data/ServerImportData.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.importing.data; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.builders.TPSBuilder; - -import java.util.*; - -/** - * @author Fuzzlemann - */ -public class ServerImportData { - - private Map commandUsages; - private List tpsData; - - private ServerImportData(Map commandUsages, List tpsData) { - this.commandUsages = commandUsages; - this.tpsData = tpsData; - } - - public static ServerImportDataBuilder builder() { - return new ServerImportDataBuilder(); - } - - public Map getCommandUsages() { - return commandUsages; - } - - public void setCommandUsages(Map commandUsages) { - this.commandUsages = commandUsages; - } - - public List getTpsData() { - return tpsData; - } - - public void setTpsData(List tpsData) { - this.tpsData = tpsData; - } - - public static final class ServerImportDataBuilder { - private final Map commandUsages = new HashMap<>(); - private final List tpsData = new ArrayList<>(); - - private ServerImportDataBuilder() { - /* Private Constructor */ - } - - public ServerImportDataBuilder commandUsage(String command, Integer usages) { - this.commandUsages.put(command, usages); - return this; - } - - public ServerImportDataBuilder commandUsages(Map commandUsages) { - this.commandUsages.putAll(commandUsages); - return this; - } - - public ServerImportDataBuilder tpsData(long date, double ticksPerSecond, int players, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded) { - TPS tps = TPSBuilder.get() - .date(date) - .tps(ticksPerSecond) - .playersOnline(players) - .usedCPU(cpuUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(chunksLoaded) - .toTPS(); - this.tpsData.add(tps); - return this; - } - - public ServerImportDataBuilder tpsData(TPS... tpsData) { - this.tpsData.addAll(Arrays.asList(tpsData)); - return this; - } - - public ServerImportDataBuilder tpsData(Collection tpsData) { - this.tpsData.addAll(tpsData); - return this; - } - - public ServerImportData build() { - return new ServerImportData(commandUsages, tpsData); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/data/UserImportData.java b/Plan/common/src/main/java/com/djrapitops/plan/system/importing/data/UserImportData.java deleted file mode 100644 index 93d92dca6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/data/UserImportData.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.importing.data; - -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.data.time.GMTimes; - -import java.util.*; - -/** - * @author Fuzzlemann - */ -public class UserImportData { - - private String name; - private UUID uuid; - private List nicknames; - - private long registered; - private boolean op; - - private boolean banned; - private int timesKicked; - - private List ips; - private Map worldTimes; - - private List kills; - private int mobKills; - private int deaths; - - private UserImportData(String name, UUID uuid, List nicknames, long registered, boolean op, boolean banned, int timesKicked, List ips, Map worldTimes, List kills, int mobKills, int deaths) { - this.name = name; - this.uuid = uuid; - this.nicknames = nicknames; - this.registered = registered; - this.op = op; - this.banned = banned; - this.timesKicked = timesKicked; - this.ips = ips; - this.worldTimes = worldTimes; - this.kills = kills; - this.mobKills = mobKills; - this.deaths = deaths; - } - - public static UserImportDataBuilder builder(UUID serverUUID) { - return new UserImportDataBuilder(serverUUID); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public UUID getUuid() { - return uuid; - } - - public void setUuid(UUID uuid) { - this.uuid = uuid; - } - - public List getNicknames() { - return nicknames; - } - - public void setNicknames(List nicknames) { - this.nicknames = nicknames; - } - - public long getRegistered() { - return registered; - } - - public void setRegistered(long registered) { - this.registered = registered; - } - - public boolean isOp() { - return op; - } - - public void setOp(boolean op) { - this.op = op; - } - - public boolean isBanned() { - return banned; - } - - public void setBanned(boolean banned) { - this.banned = banned; - } - - public int getTimesKicked() { - return timesKicked; - } - - public void setTimesKicked(int timesKicked) { - this.timesKicked = timesKicked; - } - - public List getIps() { - return ips; - } - - public void setIps(List ips) { - this.ips = ips; - } - - public Map getWorldTimes() { - return worldTimes; - } - - public void setWorldTimes(Map worldTimes) { - this.worldTimes = worldTimes; - } - - public List getKills() { - return kills; - } - - public void setKills(List kills) { - this.kills = kills; - } - - public int getMobKills() { - return mobKills; - } - - public void setMobKills(int mobKills) { - this.mobKills = mobKills; - } - - public int getDeaths() { - return deaths; - } - - public void setDeaths(int deaths) { - this.deaths = deaths; - } - - public static final class UserImportDataBuilder { - private final UUID serverUUID; - - private final List nicknames = new ArrayList<>(); - private final List ips = new ArrayList<>(); - private final Map worldTimes = new HashMap<>(); - private final List kills = new ArrayList<>(); - private String name; - private UUID uuid; - private long registered; - private boolean op; - private boolean banned; - private int timesKicked; - private int mobKills; - private int deaths; - - private UserImportDataBuilder(UUID serverUUID) { - this.serverUUID = serverUUID; - } - - public UserImportDataBuilder name(String name) { - this.name = name; - return this; - } - - public UserImportDataBuilder uuid(UUID uuid) { - this.uuid = uuid; - return this; - } - - public UserImportDataBuilder uuid(String uuid) { - return uuid(UUID.fromString(uuid)); - } - - public UserImportDataBuilder registered(long registered) { - this.registered = registered; - return this; - } - - public UserImportDataBuilder op() { - return op(true); - } - - public UserImportDataBuilder op(boolean op) { - this.op = op; - return this; - } - - public UserImportDataBuilder nicknames(String... nicknames) { - long time = System.currentTimeMillis(); - - Arrays.stream(nicknames) - .map(nick -> new Nickname(nick, time, serverUUID)) - .forEach(this.nicknames::add); - return this; - } - - public UserImportDataBuilder nicknames(Collection nicknames) { - this.nicknames.addAll(nicknames); - return this; - } - - public UserImportDataBuilder banned() { - return banned(true); - } - - public UserImportDataBuilder banned(boolean banned) { - this.banned = banned; - return this; - } - - public UserImportDataBuilder timesKicked(int timesKicked) { - this.timesKicked += timesKicked; - return this; - } - - public UserImportDataBuilder ips(String... ips) { - this.ips.addAll(Arrays.asList(ips)); - return this; - } - - public UserImportDataBuilder ips(Collection ips) { - this.ips.addAll(ips); - return this; - } - - public UserImportDataBuilder worldTimes(String worldName, long... times) { - GMTimes gmTimes = new GMTimes(); - gmTimes.setAllGMTimes(times); - - this.worldTimes.put(worldName, gmTimes); - return this; - } - - public UserImportDataBuilder worldTimes(String worldName, GMTimes gmTimes) { - this.worldTimes.put(worldName, gmTimes); - return this; - } - - public UserImportDataBuilder worldTimes(Map worldTimes) { - this.worldTimes.putAll(worldTimes); - return this; - } - - public UserImportDataBuilder kills(PlayerKill... kills) { - this.kills.addAll(Arrays.asList(kills)); - return this; - } - - public UserImportDataBuilder kills(Collection kills) { - this.kills.addAll(kills); - return this; - } - - public UserImportDataBuilder mobKills(int mobKills) { - this.mobKills += mobKills; - return this; - } - - public UserImportDataBuilder deaths(int deaths) { - this.deaths += deaths; - return this; - } - - public UserImportData build() { - return new UserImportData(name, uuid, nicknames, registered, op, banned, timesKicked, ips, worldTimes, kills, mobKills, deaths); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof UserImportData)) return false; - UserImportData that = (UserImportData) o; - return registered == that.registered && - op == that.op && - banned == that.banned && - timesKicked == that.timesKicked && - mobKills == that.mobKills && - deaths == that.deaths && - Objects.equals(name, that.name) && - Objects.equals(uuid, that.uuid) && - Objects.equals(nicknames, that.nicknames) && - Objects.equals(ips, that.ips) && - Objects.equals(worldTimes, that.worldTimes) && - Objects.equals(kills, that.kills); - } - - @Override - public int hashCode() { - return Objects.hash(name, uuid, nicknames, registered, op, banned, timesKicked, ips, worldTimes, kills, mobKills, deaths); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/importers/Importer.java b/Plan/common/src/main/java/com/djrapitops/plan/system/importing/importers/Importer.java deleted file mode 100644 index a04380c0e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/importing/importers/Importer.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.importing.importers; - -public interface Importer { - void processImport(); - - String getName(); -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java deleted file mode 100644 index a0a2fa502..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info; - -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.DebugChannels; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.request.GenerateRequest; -import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.info.request.InfoRequestFactory; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.logging.console.PluginLogger; -import dagger.Lazy; - -import java.util.UUID; - -/** - * Information management system. - *

- * Subclasses should decide how InfoRequests are run locally if necessary. - *

- * Everything should be called from an Async thread. - * - * @author Rsl1122 - */ -public abstract class InfoSystem implements SubSystem { - - protected final InfoRequestFactory infoRequestFactory; - protected final ConnectionSystem connectionSystem; - protected final ServerInfo serverInfo; - protected final Lazy webServer; - protected final PluginLogger logger; - - protected InfoSystem( - InfoRequestFactory infoRequestFactory, - ConnectionSystem connectionSystem, - ServerInfo serverInfo, - Lazy webServer, - PluginLogger logger - ) { - this.infoRequestFactory = infoRequestFactory; - this.connectionSystem = connectionSystem; - this.serverInfo = serverInfo; - this.webServer = webServer; - this.logger = logger; - } - - /** - * Refreshes Player page. - *

- * No calls from non-async thread found on 09.02.2018 - * - * @param player UUID of the player. - * @throws WebException If fails. - */ - public void generateAndCachePlayerPage(UUID player) throws WebException { - GenerateRequest infoRequest = infoRequestFactory.generateInspectPageRequest(player); - try { - sendRequest(infoRequest); - } catch (ConnectionFailException e) { - runLocally(infoRequest); - } - } - - /** - * Refreshes Analysis page. - *

- * No calls from non-async thread found on 09.02.2018 - * - * @param serverUUID UUID of the server to analyze - * @throws WebException If fails. - */ - public void generateAnalysisPage(UUID serverUUID) throws WebException { - GenerateRequest request = infoRequestFactory.generateAnalysisPageRequest(serverUUID); - if (serverInfo.getServerUUID().equals(serverUUID)) { - runLocally(request); - } else { - sendRequest(request); - } - } - - /** - * Send an InfoRequest to another server or run locally if necessary. - *

- * No calls from non-async thread found on 09.02.2018 - * - * @param infoRequest InfoRequest to send or run. - * @throws WebException If fails. - */ - public void sendRequest(InfoRequest infoRequest) throws WebException { - try { - if (!connectionSystem.isServerAvailable()) { - logger.getDebugLogger().logOn(DebugChannels.INFO_REQUESTS, "Main server unavailable, running locally."); - runLocally(infoRequest); - return; - } - connectionSystem.sendInfoRequest(infoRequest); - } catch (WebException original) { - try { - logger.getDebugLogger().logOn(DebugChannels.INFO_REQUESTS, "Exception during request: " + original.toString() + ", running locally."); - runLocally(infoRequest); - } catch (NoServersException e2) { - throw original; - } - } - } - - /** - * Run the InfoRequest locally. - *

- * No calls from non-async thread found on 09.02.2018 - * - * @param infoRequest InfoRequest to run. - * @throws WebException If fails. - */ - public abstract void runLocally(InfoRequest infoRequest) throws WebException; - - @Override - public void enable() { - connectionSystem.enable(); - } - - @Override - public void disable() { - connectionSystem.disable(); - } - - public ConnectionSystem getConnectionSystem() { - return connectionSystem; - } - - /** - * Requests Set up from Bungee. - *

- * No calls from non-async thread found on 09.02.2018 - * - * @param addressToRequestServer Address of Bungee server. - * @throws WebException If fails. - */ - public void requestSetUp(String addressToRequestServer) throws WebException { - if (serverInfo.getServer().isProxy()) { - throw new BadRequestException("Method not available on a Proxy server."); - } - Server bungee = new Server(-1, null, "Bungee", addressToRequestServer, -1); - String addressOfThisServer = webServer.get().getAccessAddress(); - - connectionSystem.setSetupAllowed(true); - connectionSystem.sendInfoRequest(infoRequestFactory.sendDBSettingsRequest(addressOfThisServer), bungee); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/ProxyInfoSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/ProxyInfoSystem.java deleted file mode 100644 index 9a703d8d9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/ProxyInfoSystem.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info; - -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.request.*; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.logging.console.PluginLogger; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * InfoSystem for Bungee. - * - * @author Rsl1122 - */ -@Singleton -public class ProxyInfoSystem extends InfoSystem { - - @Inject - public ProxyInfoSystem( - InfoRequestFactory infoRequestFactory, - ConnectionSystem connectionSystem, - ServerInfo serverInfo, - Lazy webServer, - PluginLogger logger - ) { - super(infoRequestFactory, connectionSystem, serverInfo, webServer, logger); - } - - @Override - public void runLocally(InfoRequest infoRequest) throws WebException { - if (infoRequest instanceof CacheRequest - || infoRequest instanceof GenerateInspectPageRequest - || infoRequest instanceof GenerateInspectPluginsTabRequest - ) { - infoRequest.runLocally(); - } else { - // runLocally is called when ConnectionSystem has no servers. - throw new NoServersException("No servers were available to process this request (Local attempt): " + infoRequest.getClass().getSimpleName()); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java deleted file mode 100644 index a0e262a96..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info; - -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.DebugChannels; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.info.request.InfoRequestFactory; -import com.djrapitops.plan.system.info.request.SetupRequest; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.logging.console.PluginLogger; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * InfoSystem for Bukkit servers. - * - * @author Rsl1122 - */ -@Singleton -public class ServerInfoSystem extends InfoSystem { - - @Inject - public ServerInfoSystem( - ConnectionSystem connectionSystem, - ServerInfo serverInfo, - InfoRequestFactory infoRequestFactory, - Lazy webServer, - PluginLogger logger - ) { - super(infoRequestFactory, connectionSystem, serverInfo, webServer, logger); - } - - @Override - public void runLocally(InfoRequest infoRequest) throws WebException { - if (infoRequest instanceof SetupRequest) { - throw new NoServersException("Set-up requests can not be run locally."); - } - logger.getDebugLogger().logOn(DebugChannels.INFO_REQUESTS, "Local: " + infoRequest.getClass().getSimpleName()); - infoRequest.runLocally(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionIn.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionIn.java deleted file mode 100644 index fd30a568e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionIn.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.connection; - -import com.djrapitops.plan.api.exceptions.connection.*; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.info.request.SetupRequest; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plugin.utilities.Verify; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; - -public class ConnectionIn { - - private final Map variables; - private final InfoRequest infoRequest; - private final Database database; - private final ConnectionSystem connectionSystem; - - public ConnectionIn( - Request httpRequest, InfoRequest infoRequest, - Database database, - ConnectionSystem connectionSystem - ) throws WebException { - this.database = database; - this.connectionSystem = connectionSystem; - Verify.nullCheck(httpRequest, infoRequest); - - this.variables = readVariables(httpRequest); - this.infoRequest = infoRequest; - - checkAuthentication(); - } - - private void checkAuthentication() throws WebException { - UUID serverUUID = getServerUUID(); - - try { - if (database.query(ServerQueries.fetchServerMatchingIdentifier(serverUUID)).isPresent()) { - return; - } - } catch (DBOpException e) { - throw new TransferDatabaseException(e); - } - - if (infoRequest instanceof SetupRequest) { - if (!connectionSystem.isSetupAllowed()) { - throw new ForbiddenException("Setup not enabled on this server, use commands to enable."); - } - } else { - throw new UnauthorizedServerException(serverUUID + " (Sender) was not found from database"); - } - } - - private UUID getServerUUID() throws BadRequestException { - String sender = variables.get("sender"); - Verify.nullCheck(sender, () -> new BadRequestException("Sender ('sender') variable not supplied in the request.")); - - try { - return UUID.fromString(sender); - } catch (IllegalArgumentException e) { - throw new BadRequestException("Sender ('sender') was not a valid UUID: " + e.getMessage()); - } - } - - private Map readVariables(Request request) throws WebException { - String requestBody = readRequestBody(request.getRequestBody()); - String[] bodyVariables = requestBody.split(";&variable;"); - - return Arrays.stream(bodyVariables) - .map(variable -> variable.split("=", 2)) - .filter(splitVariables -> splitVariables.length == 2) - .collect(Collectors.toMap(splitVariables -> splitVariables[0], splitVariables -> splitVariables[1], (a, b) -> b)); - } - - public Response handleRequest() throws WebException { - return infoRequest.handleRequest(variables); - } - - private String readRequestBody(InputStream in) throws WebFailException { - try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { - byte[] bytes; - - byte[] buf = new byte[4096]; - for (int n = in.read(buf); n > 0; n = in.read(buf)) { - out.write(buf, 0, n); - } - - bytes = out.toByteArray(); - - return new String(bytes, StandardCharsets.UTF_8); - } catch (IOException e) { - throw new WebFailException("Exception while reading Request.", e); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionLog.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionLog.java deleted file mode 100644 index 30a0a918a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionLog.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.connection; - -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.system.DebugChannels; -import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plugin.logging.debug.DebugLogger; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Class responsible for logging what {@link ConnectionOut} and {@link ConnectionIn} objects get as response. - * - * @author Rsl1122 - */ -@Singleton -public class ConnectionLog { - - private final DebugLogger debugLogger; - - private final Map> log; - - @Inject - public ConnectionLog(DebugLogger debugLogger) { - this.debugLogger = debugLogger; - log = new HashMap<>(); - } - - public void logConnectionTo(Server server, InfoRequest request, int responseCode) { - String requestName = request.getClass().getSimpleName(); - String address = server.getWebAddress(); - logConnection(address, "Out: " + requestName, responseCode); - debugLogger.logOn(DebugChannels.CONNECTIONS, "ConnectionOut: " + requestName + " to " + address); - } - - public void logConnectionFrom(String server, String requestTarget, int responseCode) { - logConnection(server, "In: " + requestTarget, responseCode); - debugLogger.logOn(DebugChannels.CONNECTIONS, "ConnectionIn: " + requestTarget + " from " + server); - } - - private void logConnection(String address, String infoRequestName, int responseCode) { - Map requestMap = log.getOrDefault(address, new HashMap<>()); - requestMap.put(infoRequestName, new Entry(responseCode, System.currentTimeMillis())); - log.put(address, requestMap); - } - - public Map> getLogEntries() { - return log; - } - - public static class Entry implements Comparable, DateHolder { - - private final int responseCode; - private final long date; - - public Entry(int responseCode, long date) { - this.responseCode = responseCode; - this.date = date; - } - - public int getResponseCode() { - return responseCode; - } - - @Override - public long getDate() { - return date; - } - - /** - * Most recent first. - * - * @param o object - * @return -1 or 1 - */ - @Override - public int compareTo(Entry o) { - return Long.compare(o.date, this.date); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Entry)) return false; - Entry entry = (Entry) o; - return responseCode == entry.responseCode && - date == entry.date; - } - - @Override - public int hashCode() { - return Objects.hash(responseCode, date); - } - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java deleted file mode 100644 index 04270b1aa..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.connection; - -import com.djrapitops.plan.api.exceptions.connection.*; -import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.info.request.InfoRequestWithVariables; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plugin.utilities.Verify; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.TrustAllStrategy; -import org.apache.http.entity.ByteArrayEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.ssl.SSLContextBuilder; - -import java.io.IOException; -import java.net.SocketTimeoutException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.util.Map; -import java.util.Properties; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Represents an outbound action request to another Plan server. - * - * @author Rsl1122 - */ -public class ConnectionOut { - - private final Server toServer; - private final UUID serverUUID; - private final InfoRequest infoRequest; - - static { - try { - Properties properties = System.getProperties(); - properties.setProperty("sun.net.client.defaultConnectTimeout", Long.toString(TimeUnit.MINUTES.toMillis(1L))); - properties.setProperty("sun.net.client.defaultReadTimeout", Long.toString(TimeUnit.MINUTES.toMillis(1L))); - properties.setProperty("sun.net.http.retryPost", Boolean.toString(false)); - } catch (Exception e) { - Logger.getGlobal().log(Level.WARNING, "[Plan] Failed to set sun client timeout system properties.", e); - } - } - - private final ConnectionLog connectionLog; - - /** - * Constructor. - * - * @param toServer Full address to another Plan webserver. (http://something:port) - * @param serverUUID UUID of server this outbound connection. - * @param infoRequest Type of the action this connection wants to be performed. - * @param connectionLog Where the connection should be logged. - */ - public ConnectionOut( - Server toServer, UUID serverUUID, InfoRequest infoRequest, - ConnectionLog connectionLog - ) { - this.connectionLog = connectionLog; - Verify.nullCheck(toServer, serverUUID, infoRequest); - this.toServer = toServer; - this.serverUUID = serverUUID; - this.infoRequest = infoRequest; - } - - public void sendRequest() throws WebException { - String address = getAddress(); - - CloseableHttpClient client = null; - HttpPost post = null; - CloseableHttpResponse response = null; - long start = System.currentTimeMillis(); - try { - client = getHttpClient(address); - String url = address + "/info/" + infoRequest.getClass().getSimpleName().toLowerCase(); - - post = new HttpPost(url); - String parameters = parseVariables(); - prepareRequest(post, parameters); - - // Send request - response = client.execute(post); - int responseCode = response.getStatusLine().getStatusCode(); - - handleResult(url, parameters, responseCode); - } catch (SocketTimeoutException e) { - connectionLog.logConnectionTo(toServer, infoRequest, 0); - long seconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - start); - throw new ConnectionFailException("Connection to " + address + " timed out (" + seconds + "s): " + e.getMessage(), e); - } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException | IOException e) { - connectionLog.logConnectionTo(toServer, infoRequest, -1); - throw new ConnectionFailException("Connection failed to address: " + address + " - Make sure the server is online.", e); - } finally { - if (post != null) { - post.releaseConnection(); - } - MiscUtils.close(response); - MiscUtils.close(client); - } - } - - private void handleResult(String url, String parameters, int responseCode) throws WebException { - connectionLog.logConnectionTo(toServer, infoRequest, responseCode); - switch (responseCode) { - case 200: - return; - case 400: - throw new BadRequestException("Bad Request: " + url + " | " + parameters); - case 403: - throw new ForbiddenException(url + " returned 403 | " + parameters); - case 404: - throw new NotFoundException(url + " returned a 404, ensure that your server is connected to an up to date Plan server."); - case 412: - throw new UnauthorizedServerException(url + " reported that it does not recognize this server. Make sure '/plan m setup' was successful."); - case 500: - throw new InternalErrorException(); - case 504: - throw new GatewayException(url + " reported that it failed to connect to this server."); - default: - throw new WebException(url + "| Wrong response code " + responseCode); - } - } - - private void prepareRequest(HttpPost post, String parameters) { - RequestConfig requestConfig = RequestConfig.custom() - .setConnectionRequestTimeout(5000) - .setSocketTimeout(10000) - .setConnectTimeout(9000) - .setRedirectsEnabled(true) - .setRelativeRedirectsAllowed(true) - .setContentCompressionEnabled(true) - .build(); - post.setConfig(requestConfig); - - post.setHeader("Content-Type", "application/x-www-form-urlencoded"); - post.setHeader("charset", "UTF-8"); - post.setHeader("Connection", "close"); - - byte[] toSend = parameters.getBytes(); - post.setEntity(new ByteArrayEntity(toSend)); - } - - private CloseableHttpClient getHttpClient(String address) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { - if (address.startsWith("https")) { - SSLContextBuilder builder = new SSLContextBuilder(); - builder.loadTrustMaterial(null, new TrustAllStrategy()); - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE); - return HttpClients.custom().setSSLSocketFactory(sslsf).build(); - } else { - return HttpClients.createDefault(); - } - } - - private String getAddress() { - String address = toServer.getWebAddress(); - if (address.contains("://:")) { - String[] parts = address.split("://:", 2); - address = parts[0] + "://localhost:" + parts[1]; - } - return address; - } - - private String parseVariables() { - StringBuilder parameters = new StringBuilder("sender=" + serverUUID + ";&variable;" + - "type=" + infoRequest.getClass().getSimpleName()); - - if (infoRequest instanceof InfoRequestWithVariables) { - Map variables = ((InfoRequestWithVariables) infoRequest).getVariables(); - for (Map.Entry entry : variables.entrySet()) { - parameters.append(";&variable;").append(entry.getKey()).append("=").append(entry.getValue()); - } - } - - return parameters.toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java deleted file mode 100644 index 5ecf6f907..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.connection; - -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.info.request.InfoRequests; -import com.djrapitops.plan.system.info.request.WideRequest; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import dagger.Lazy; - -import java.util.*; - -/** - * ConnectionSystem manages out- and inbound InfoRequest connections. - *

- * It decides what server to use for each request. - * - * @author Rsl1122 - */ -public abstract class ConnectionSystem implements SubSystem { - - protected final ConnectionLog connectionLog; - protected final InfoRequests infoRequests; - protected final Lazy infoSystem; - protected final ServerInfo serverInfo; - - protected Map dataServers; - private boolean setupAllowed; - - public ConnectionSystem( - ConnectionLog connectionLog, - InfoRequests infoRequests, - Lazy infoSystem, - ServerInfo serverInfo - ) { - this.connectionLog = connectionLog; - this.infoSystem = infoSystem; - this.serverInfo = serverInfo; - setupAllowed = false; - dataServers = new HashMap<>(); - this.infoRequests = infoRequests; - } - - public InfoRequest getInfoRequest(String name) { - return infoRequests.get(name.toLowerCase()); - } - - public void setSetupAllowed(boolean setupAllowed) { - this.setupAllowed = setupAllowed; - } - - protected abstract Server selectServerForRequest(InfoRequest infoRequest) throws NoServersException; - - public boolean isSetupAllowed() { - return setupAllowed; - } - - public void sendInfoRequest(InfoRequest infoRequest) throws WebException { - Server server = selectServerForRequest(infoRequest); - sendInfoRequest(infoRequest, server); - } - - public void sendInfoRequest(InfoRequest infoRequest, Server toServer) throws WebException { - UUID serverUUID = serverInfo.getServerUUID(); - if (serverUUID.equals(toServer.getUuid())) { - infoSystem.get().runLocally(infoRequest); - } else { - new ConnectionOut(toServer, serverUUID, infoRequest, connectionLog).sendRequest(); - } - } - - public ConnectionLog getConnectionLog() { - return connectionLog; - } - - public abstract boolean isServerAvailable(); - - public abstract String getMainAddress(); - - public abstract void sendWideInfoRequest(WideRequest infoRequest) throws NoServersException; - - public List getDataServers() { - return new ArrayList<>(dataServers.values()); - } - - @Override - public void enable() { - infoRequests.initializeRequests(); - } - - @Override - public void disable() { - setupAllowed = false; - dataServers.clear(); - infoRequests.clear(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/InfoRequestPageHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/InfoRequestPageHandler.java deleted file mode 100644 index 7e5da8f27..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/InfoRequestPageHandler.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.connection; - -import com.djrapitops.plan.api.exceptions.connection.NotFoundException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.pages.PageHandler; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; -import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * PageHandler for /info/requestclassname pages. - *

- * Used for answering info requests by other servers. - *

- * requestclassname should be replaced with lowercase version of {@code Class.getSimpleName()} - * - * @author Rsl1122 - */ -@Singleton -public class InfoRequestPageHandler implements PageHandler { - - private final DBSystem dbSystem; - private final ConnectionSystem connectionSystem; - private final ResponseFactory responseFactory; - private final PluginLogger logger; - - @Inject - public InfoRequestPageHandler( - DBSystem dbSystem, - ConnectionSystem connectionSystem, - ResponseFactory responseFactory, PluginLogger logger - ) { - this.dbSystem = dbSystem; - this.connectionSystem = connectionSystem; - this.responseFactory = responseFactory; - this.logger = logger; - } - - @Override - public Response getResponse(Request request, RequestTarget target) throws WebException { - int responseCode = 200; - - try { - if (target.isEmpty()) { - return responseFactory.pageNotFound404(); - } - - if (!request.getRequestMethod().equals("POST")) { - return new BadRequestResponse("POST should be used for Info calls."); - } - - String requestName = target.get(0); - InfoRequest infoRequest = connectionSystem.getInfoRequest(requestName); - - Verify.nullCheck(infoRequest, () -> new NotFoundException("Info Request has not been registered.")); - - logger.debug("ConnectionIn: " + infoRequest.getClass().getSimpleName()); - return new ConnectionIn(request, infoRequest, dbSystem.getDatabase(), connectionSystem).handleRequest(); - } catch (WebException e) { - responseCode = getResponseCodeFor(e); - throw e; - } finally { - connectionSystem.getConnectionLog().logConnectionFrom(request.getRemoteAddress(), request.getTargetString(), responseCode); - } - } - - private int getResponseCodeFor(WebException e) { - return e.getResponseCode().getCode(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ProxyConnectionSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ProxyConnectionSystem.java deleted file mode 100644 index 03c8dd92c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ProxyConnectionSystem.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.connection; - -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.request.*; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -/** - * ConnectionSystem for proxy servers. - * - * @author Rsl1122 - */ -@Singleton -public class ProxyConnectionSystem extends ConnectionSystem { - - private final DBSystem dbSystem; - private final Lazy webServer; - private final ErrorHandler errorHandler; - private final WebExceptionLogger webExceptionLogger; - - private long latestServerMapRefresh; - - @Inject - public ProxyConnectionSystem( - DBSystem dbSystem, - Lazy webServer, - ConnectionLog connectionLog, - InfoRequests infoRequests, - Lazy infoSystem, - ServerInfo serverInfo, - ErrorHandler errorHandler, - WebExceptionLogger webExceptionLogger - ) { - super(connectionLog, infoRequests, infoSystem, serverInfo); - this.dbSystem = dbSystem; - this.webServer = webServer; - this.errorHandler = errorHandler; - this.webExceptionLogger = webExceptionLogger; - latestServerMapRefresh = 0; - } - - private void refreshServerMap() { - if (latestServerMapRefresh < System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(15L)) { - try { - dataServers = dbSystem.getDatabase().query(ServerQueries.fetchPlanServerInformation()).entrySet().stream() - .filter(entry -> entry.getValue().isNotProxy()) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - latestServerMapRefresh = System.currentTimeMillis(); - } catch (DBOpException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } - } - - @Override - protected Server selectServerForRequest(InfoRequest infoRequest) throws NoServersException { - refreshServerMap(); - Server server = null; - if (infoRequest instanceof CacheRequest - || infoRequest instanceof GenerateInspectPageRequest - || infoRequest instanceof GenerateInspectPluginsTabRequest) { - // Run locally - return serverInfo.getServer(); - } else if (infoRequest instanceof GenerateAnalysisPageRequest) { - UUID serverUUID = ((GenerateAnalysisPageRequest) infoRequest).getServerUUID(); - server = dataServers.get(serverUUID); - } - if (server == null) { - throw new NoServersException("Proper server is not available to process request: " + infoRequest.getClass().getSimpleName()); - } - return server; - } - - @Override - public void sendWideInfoRequest(WideRequest infoRequest) throws NoServersException { - refreshServerMap(); - if (dataServers.isEmpty()) { - throw new NoServersException("No Servers available to make wide-request: " + infoRequest.getClass().getSimpleName()); - } - for (Server server : dataServers.values()) { - webExceptionLogger.logIfOccurs(this.getClass(), () -> sendInfoRequest(infoRequest, server)); - } - // Quick hack for Bungee Plugins Tab - if (infoRequest instanceof GenerateInspectPluginsTabRequest) { - webExceptionLogger.logIfOccurs(this.getClass(), infoRequest::runLocally); - } - } - - @Override - public boolean isServerAvailable() { - return true; - } - - @Override - public String getMainAddress() { - return webServer.get().getAccessAddress(); - } - - @Override - public void enable() { - super.enable(); - refreshServerMap(); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java deleted file mode 100644 index 87f3c8c41..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.connection; - -import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.request.*; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.WebserverSettings; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -/** - * Connection system for Bukkit servers. - * - * @author Rsl1122 - */ -@Singleton -public class ServerConnectionSystem extends ConnectionSystem { - - private final Locale locale; - private final PlanConfig config; - private final Processing processing; - private final DBSystem dbSystem; - private final Lazy webServer; - private final PluginLogger pluginLogger; - private final WebExceptionLogger webExceptionLogger; - - private long latestServerMapRefresh; - - private Server mainServer; - - @Inject - public ServerConnectionSystem( - Locale locale, - PlanConfig config, - Processing processing, - DBSystem dbSystem, - Lazy webServer, - ConnectionLog connectionLog, - InfoRequests infoRequests, - Lazy infoSystem, - ServerInfo serverInfo, - PluginLogger pluginLogger, - WebExceptionLogger webExceptionLogger - ) { - super(connectionLog, infoRequests, infoSystem, serverInfo); - this.locale = locale; - this.config = config; - this.processing = processing; - this.dbSystem = dbSystem; - this.webServer = webServer; - this.pluginLogger = pluginLogger; - this.webExceptionLogger = webExceptionLogger; - latestServerMapRefresh = 0; - } - - private void refreshServerMap() { - processing.submitNonCritical(() -> { - if (latestServerMapRefresh < System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(15L)) { - Database database = dbSystem.getDatabase(); - Map servers = database.query(ServerQueries.fetchPlanServerInformation()); - Optional proxy = servers.values().stream() - .filter(Server::isProxy) - .findFirst(); - mainServer = proxy.orElse(null); - - proxy.ifPresent(proxyServer -> servers.remove(proxyServer.getUuid())); - - dataServers = servers; - latestServerMapRefresh = System.currentTimeMillis(); - } - }); - } - - @Override - protected Server selectServerForRequest(InfoRequest infoRequest) throws NoServersException { - refreshServerMap(); - - if (mainServer == null && dataServers.isEmpty()) { - throw new NoServersException("Zero servers available to process requests."); - } - - Server server = null; - if (infoRequest instanceof CacheRequest || - infoRequest instanceof GenerateInspectPageRequest) { - server = mainServer; - } else if (infoRequest instanceof GenerateAnalysisPageRequest) { - UUID serverUUID = ((GenerateAnalysisPageRequest) infoRequest).getServerUUID(); - server = dataServers.get(serverUUID); - } - if (server == null) { - throw new NoServersException("Proper server is not available to process request: " + infoRequest.getClass().getSimpleName()); - } - return server; - } - - @Override - public void sendWideInfoRequest(WideRequest infoRequest) throws NoServersException { - if (dataServers.isEmpty()) { - throw new NoServersException("No Servers available to make wide-request: " + infoRequest.getClass().getSimpleName()); - } - for (Server server : dataServers.values()) { - webExceptionLogger.logIfOccurs(this.getClass(), () -> { - try { - sendInfoRequest(infoRequest, server); - } catch (ConnectionFailException ignored) { - /* Wide Requests are used when at least one result is wanted. */ - } - }); - } - } - - @Override - public boolean isServerAvailable() { - return mainServer != null; - } - - @Override - public String getMainAddress() { - return isServerAvailable() ? mainServer.getWebAddress() : serverInfo.getServer().getWebAddress(); - - } - - @Override - public void enable() { - super.enable(); - refreshServerMap(); - - boolean usingBungeeWebServer = isServerAvailable(); - boolean usingAlternativeIP = config.isTrue(WebserverSettings.SHOW_ALTERNATIVE_IP); - - if (!usingAlternativeIP && serverInfo.getServerProperties().getIp().isEmpty()) { - pluginLogger.log(L.INFO_COLOR, "§e" + locale.getString(PluginLang.ENABLE_NOTIFY_EMPTY_IP)); - } - if (usingBungeeWebServer && usingAlternativeIP) { - String webServerAddress = webServer.get().getAccessAddress(); - pluginLogger.info(locale.getString(PluginLang.ENABLE_NOTIFY_ADDRESS_CONFIRMATION, webServerAddress)); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/WebExceptionLogger.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/WebExceptionLogger.java deleted file mode 100644 index f86009702..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/connection/WebExceptionLogger.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.connection; - -import com.djrapitops.plan.api.exceptions.connection.*; -import com.djrapitops.plan.utilities.java.ThrowingVoidFunction; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * Class that decides what to do with WebExceptions. - * - * @author Rsl1122 - */ -@Singleton -public class WebExceptionLogger { - - private final ConnectionLog connectionLog; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - @Inject - public WebExceptionLogger( - ConnectionLog connectionLog, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.connectionLog = connectionLog; - this.logger = logger; - this.errorHandler = errorHandler; - } - - public void logIfOccurs(Class definingClass, ThrowingVoidFunction function) { - try { - function.apply(); - } catch (ConnectionFailException e) { - if (shouldLog(e)) { - logger.debug(e.getMessage()); - } - } catch (UnauthorizedServerException | NotFoundException | NoServersException e) { - logger.debug(e.getMessage()); - } catch (WebException e) { - errorHandler.log(L.WARN, definingClass, e); - } - } - - private boolean shouldLog(ConnectionFailException e) { - String address = getAddress(e); - if (address == null) { - return true; - } - Map> logEntries = connectionLog.getLogEntries(); - Map entries = logEntries.get("Out: " + address); - if (entries != null) { - List connections = new ArrayList<>(entries.values()); - Collections.sort(connections); - return connections.isEmpty() || connections.get(0).getResponseCode() != -1; - } - return true; - } - - private static String getAddress(ConnectionFailException e) { - if (e.getMessage().contains("to address")) { - String[] split = e.getMessage().split("to address: "); - if (split.length == 2) { - String[] split2 = split[1].split("
"); - if (split2.length == 2) { - return split2[0]; - } - } - } - return null; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheAnalysisPageRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheAnalysisPageRequest.java deleted file mode 100644 index 8ce23d583..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheAnalysisPageRequest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.export.HtmlExport; -import com.djrapitops.plan.system.export.JSONExport; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.ExportSettings; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse; -import com.djrapitops.plan.utilities.Base64Util; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.Map; -import java.util.UUID; - -/** - * InfoRequest used to place HTML of a server to ResponseCache. - * - * @author Rsl1122 - */ -public class CacheAnalysisPageRequest extends InfoRequestWithVariables implements CacheRequest { - - private final PlanConfig config; - private final Processing processing; - private final HtmlExport htmlExport; - private final JSONExport jsonExport; - - private final UUID networkUUID; - - private UUID serverUUID; - private String html; - - CacheAnalysisPageRequest( - PlanConfig config, - Processing processing, - HtmlExport htmlExport, - JSONExport jsonExport, - UUID networkUUID - ) { - this.config = config; - this.processing = processing; - this.jsonExport = jsonExport; - this.networkUUID = networkUUID; - this.htmlExport = htmlExport; - } - - CacheAnalysisPageRequest( - UUID serverUUID, String html, - PlanConfig config, - Processing processing, - HtmlExport htmlExport, - JSONExport jsonExport, - UUID networkUUID - ) { - this.config = config; - this.processing = processing; - this.jsonExport = jsonExport; - this.networkUUID = networkUUID; - this.htmlExport = htmlExport; - - Verify.nullCheck(serverUUID, html); - this.serverUUID = serverUUID; - variables.put("html", Base64Util.encode(html)); - this.html = html; - } - - @Override - public Response handleRequest(Map variables) throws WebException { - // Available variables: sender, html (Base64) - - UUID sender = UUID.fromString(variables.get("sender")); - - String sentHtml = variables.get("html"); - Verify.nullCheck(sentHtml, () -> new BadRequestException("HTML 'html' variable not supplied in the request")); - - cache(sender, Base64Util.decode(sentHtml)); - return DefaultResponses.SUCCESS.get(); - } - - private void cache(UUID serverUUID, String html) { - ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(html)); - if (!networkUUID.equals(serverUUID)) { - ResponseCache.clearResponse(PageId.SERVER.of(networkUUID)); - } - - if (config.get(ExportSettings.SERVER_PAGE)) { - processing.submitNonCritical(() -> { - htmlExport.exportNetworkPage(); - htmlExport.exportServer(serverUUID); - }); - } - if (config.get(ExportSettings.SERVER_JSON)) { - processing.submitNonCritical(() -> jsonExport.exportServerJSON(serverUUID)); - } - } - - @Override - public void runLocally() { - cache(serverUUID, html); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java deleted file mode 100644 index 1d1485b78..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.export.HtmlExport; -import com.djrapitops.plan.system.export.JSONExport; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.ExportSettings; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; -import com.djrapitops.plan.utilities.Base64Util; -import com.djrapitops.plugin.utilities.Verify; -import org.apache.commons.text.StringSubstitutor; - -import java.util.Collections; -import java.util.Map; -import java.util.UUID; - -/** - * InfoRequest used to place HTML of a player to ResponseCache. - * - * @author Rsl1122 - */ -public class CacheInspectPageRequest extends InfoRequestWithVariables implements CacheRequest { - - private final PlanConfig config; - private final Processing processing; - private final ServerInfo serverInfo; - private final HtmlExport htmlExport; - private final JSONExport jsonExport; - - private UUID player; - private String html; - - CacheInspectPageRequest( - PlanConfig config, - Processing processing, - ServerInfo serverInfo, - HtmlExport htmlExport, - JSONExport jsonExport - ) { - this.config = config; - this.processing = processing; - this.serverInfo = serverInfo; - this.htmlExport = htmlExport; - this.jsonExport = jsonExport; - } - - CacheInspectPageRequest( - UUID player, String html, - PlanConfig config, - Processing processing, - ServerInfo serverInfo, - HtmlExport htmlExport, - JSONExport jsonExport - ) { - this.config = config; - this.processing = processing; - this.serverInfo = serverInfo; - this.htmlExport = htmlExport; - this.jsonExport = jsonExport; - - Verify.nullCheck(player, html); - variables.put("player", player.toString()); - variables.put("html", Base64Util.encode(html)); - this.player = player; - this.html = html; - } - - @Override - public Response handleRequest(Map variables) throws WebException { - // Available variables: sender, player, html (Base64) - - String player = variables.get("player"); - Verify.nullCheck(player, () -> new BadRequestException("Player UUID 'player' variable not supplied in the request.")); - UUID uuid = UUID.fromString(player); - - String html = variables.get("html"); - Verify.nullCheck(html, () -> new BadRequestException("HTML 'html' variable not supplied in the request")); - - Map replace = Collections.singletonMap("networkName", serverInfo.getServer().getName()); - cache(uuid, StringSubstitutor.replace(Base64Util.decode(html), replace)); - - return DefaultResponses.SUCCESS.get(); - } - - private void cache(UUID playerUUID, String html) { - ResponseCache.cacheResponse(PageId.PLAYER.of(playerUUID), () -> new InspectPageResponse(playerUUID, html)); - if (config.get(ExportSettings.PLAYER_PAGES)) { - processing.submitNonCritical(() -> htmlExport.exportCachedPlayerPage(playerUUID)); - } - if (config.get(ExportSettings.PLAYER_JSON)) { - processing.submitNonCritical(() -> jsonExport.exportPlayerJSON(playerUUID)); - } - } - - @Override - public void runLocally() { - cache(player, html); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPluginsTabRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPluginsTabRequest.java deleted file mode 100644 index 3d4725ad0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPluginsTabRequest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.pages.parts.InspectPagePluginsContent; -import com.djrapitops.plan.utilities.Base64Util; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.Map; -import java.util.UUID; - -/** - * InfoRequest used to place HTML of player's Plugins Tab to ResponseCache. - * - * @deprecated Marked for removal when the connection system will be removed. - * @author Rsl1122 - */ -@Deprecated -public class CacheInspectPluginsTabRequest extends InfoRequestWithVariables implements CacheRequest { - - private UUID player; - private String html; - - CacheInspectPluginsTabRequest() { - } - - CacheInspectPluginsTabRequest(UUID player, String nav, String html) { - Verify.nullCheck(player, nav); - variables.put("player", player.toString()); - variables.put("nav", nav); - variables.put("html", Base64Util.encode(html)); - this.player = player; - this.html = html; - } - - @Override - public Response handleRequest(Map variables) throws WebException { - // Available variables: sender, player, nav, html - - String player = variables.get("player"); - Verify.nullCheck(player, () -> new BadRequestException("Player UUID 'player' variable not supplied in the request.")); - UUID uuid = UUID.fromString(player); - - String nav = variables.get("nav"); - String html = variables.get("html"); - Verify.nullCheck(nav, () -> new BadRequestException("Nav HTML 'nav' variable not supplied in the request")); - Verify.nullCheck(html, () -> new BadRequestException("HTML 'html' variable not supplied in the request")); - - InspectPagePluginsContent pluginsTab = getPluginsTab(uuid); - - pluginsTab.addTab(nav, Base64Util.decode(html)); - return DefaultResponses.SUCCESS.get(); - } - - private InspectPagePluginsContent getPluginsTab(UUID uuid) { - return (InspectPagePluginsContent) ResponseCache.loadResponse(PageId.PLAYER_PLUGINS_TAB.of(uuid), InspectPagePluginsContent::new); - } - - @Override - public void runLocally() { - getPluginsTab(player).addTab(variables.get("nav"), html); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheRequest.java deleted file mode 100644 index 36008c654..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheRequest.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -/** - * Interface for all InfoRequests that cache something into RequestCache. - * - * @author Rsl1122 - */ -public interface CacheRequest extends InfoRequest { -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java deleted file mode 100644 index 2aa60a8b6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; -import com.djrapitops.plan.api.exceptions.connection.GatewayException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.Map; -import java.util.UUID; - -/** - * InfoRequest used for Checking Bukkit-Bungee connections. - * - * @author Rsl1122 - */ -public class CheckConnectionRequest extends InfoRequestWithVariables { - - private final ServerInfo serverInfo; - private final ConnectionSystem connectionSystem; - - CheckConnectionRequest(String webServerAddress, ServerInfo serverInfo, ConnectionSystem connectionSystem) { - this.serverInfo = serverInfo; - this.connectionSystem = connectionSystem; - Verify.nullCheck(webServerAddress, () -> new IllegalArgumentException("webServerAddress can not be null.")); - - variables.put("address", webServerAddress); - variables.put("continue", "yes"); - } - - CheckConnectionRequest(ServerInfo serverInfo, ConnectionSystem connectionSystem) { - this.serverInfo = serverInfo; - this.connectionSystem = connectionSystem; - } - - @Override - public void runLocally() { - /* Won't be run */ - } - - @Override - public Response handleRequest(Map variables) throws WebException { - // Available variables: sender, address - - if (serverInfo.getServer().isProxy()) { - attemptConnection(variables); - } - - return DefaultResponses.SUCCESS.get(); - } - - private void attemptConnection(Map variables) throws WebException { - // Continue variable not present in rebound connection, leading to a single round ping. - boolean shouldNotContinue = variables.get("continue") == null; - if (shouldNotContinue) { - return; - } - - String address = variables.get("address"); - Verify.nullCheck(address, () -> new BadRequestException("WebServer Address ('address') not specified in the request.")); - - UUID serverUUID = UUID.fromString(variables.get("sender")); - - Server bukkit = new Server(-1, serverUUID, "", address, -1); - - try { - connectionSystem.sendInfoRequest(new CheckConnectionRequest(serverInfo, connectionSystem), bukkit); - } catch (ConnectionFailException e) { - throw new GatewayException(e.getMessage()); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java deleted file mode 100644 index 1e3b1637d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.InternalErrorException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.utilities.html.pages.PageFactory; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.Collections; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * InfoRequest to generate Analysis page HTML at the receiving end. - * - * @author Rsl1122 - */ -public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implements GenerateRequest { - - private final Processing processing; - private final WebExceptionLogger webExceptionLogger; - private final InfoRequestFactory infoRequestFactory; - private final ServerInfo serverInfo; - private final InfoSystem infoSystem; - private final PageFactory pageFactory; - - private AtomicBoolean runningAnalysis = new AtomicBoolean(false); - private UUID serverUUID; - - GenerateAnalysisPageRequest( - Processing processing, - WebExceptionLogger webExceptionLogger, - InfoRequestFactory infoRequestFactory, - ServerInfo serverInfo, - InfoSystem infoSystem, - PageFactory pageFactory - ) { - this.processing = processing; - this.webExceptionLogger = webExceptionLogger; - this.infoRequestFactory = infoRequestFactory; - this.serverInfo = serverInfo; - this.infoSystem = infoSystem; - this.pageFactory = pageFactory; - } - - GenerateAnalysisPageRequest( - UUID serverUUID, - Processing processing, - WebExceptionLogger webExceptionLogger, - InfoRequestFactory infoRequestFactory, - ServerInfo serverInfo, - InfoSystem infoSystem, - PageFactory pageFactory - ) { - this.processing = processing; - this.webExceptionLogger = webExceptionLogger; - this.infoRequestFactory = infoRequestFactory; - this.serverInfo = serverInfo; - this.infoSystem = infoSystem; - this.pageFactory = pageFactory; - - Verify.nullCheck(serverUUID); - this.serverUUID = serverUUID; - variables.put("server", serverUUID.toString()); - } - - @Override - public Response handleRequest(Map variables) throws WebException { - // Variables available: sender, server - - String server = variables.get("server"); - Verify.nullCheck(server, () -> new BadRequestException("Server UUID 'server' variable not supplied in the request.")); - - UUID serverUUID = UUID.fromString(server); - if (!serverInfo.getServerUUID().equals(serverUUID)) { - throw new BadRequestException("Requested Analysis page from wrong server."); - } - - if (!runningAnalysis.get()) { - runningAnalysis.set(true); - processing.submitNonCritical(() -> - webExceptionLogger.logIfOccurs(GenerateAnalysisPageRequest.class, () -> generateAndCache(serverUUID)) - ); - } - - return DefaultResponses.SUCCESS.get(); - } - - private void generateAndCache(UUID serverUUID) throws WebException { - infoSystem.sendRequest(infoRequestFactory.cacheAnalysisPageRequest(serverUUID, analyseAndGetHtml())); - } - - @Override - public void runLocally() throws WebException { - // Get the handler from ConnectionSystem and run the request. - // This is done to keep the concurrent analysis in check with runningAnalysis variable. - infoSystem.getConnectionSystem() - .getInfoRequest(this.getClass().getSimpleName()) - .handleRequest(Collections.singletonMap("server", serverUUID.toString())); - } - - private String analyseAndGetHtml() throws InternalErrorException { - try { - UUID serverUUID = serverInfo.getServerUUID(); - return pageFactory.analysisPage(serverUUID).toHtml(); - } catch (Exception e) { - throw new InternalErrorException("Analysis failed due to exception", e); - } finally { - runningAnalysis.set(false); - } - } - - public UUID getServerUUID() { - return serverUUID; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java deleted file mode 100644 index 7ce7c8854..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.api.exceptions.connection.*; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; -import com.djrapitops.plan.utilities.html.pages.PageFactory; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.Map; -import java.util.UUID; - -/** - * InfoRequest for Generating Inspect page on receiving WebServer. - * - * @author Rsl1122 - */ -public class GenerateInspectPageRequest extends InfoRequestWithVariables implements GenerateRequest { - - private final InfoRequestFactory infoRequestFactory; - private final ResponseFactory responseFactory; - private final PageFactory pageFactory; - private final InfoSystem infoSystem; - - private UUID playerUUID; - - GenerateInspectPageRequest( - InfoRequestFactory infoRequestFactory, - ResponseFactory responseFactory, PageFactory pageFactory, - InfoSystem infoSystem - ) { - this.infoRequestFactory = infoRequestFactory; - this.responseFactory = responseFactory; - this.pageFactory = pageFactory; - this.infoSystem = infoSystem; - } - - GenerateInspectPageRequest( - UUID uuid, - InfoRequestFactory infoRequestFactory, - ResponseFactory responseFactory, PageFactory pageFactory, - InfoSystem infoSystem - ) { - this.infoRequestFactory = infoRequestFactory; - this.responseFactory = responseFactory; - this.pageFactory = pageFactory; - this.infoSystem = infoSystem; - - Verify.nullCheck(uuid); - playerUUID = uuid; - variables.put("player", uuid.toString()); - } - - @Override - public Response handleRequest(Map variables) throws WebException { - // Available variables: sender, player - - String player = variables.get("player"); - Verify.nullCheck(player, () -> new BadRequestException("Player UUID 'player' variable not supplied in the request.")); - - UUID uuid = UUID.fromString(player); - - generateAndCache(uuid); - - return DefaultResponses.SUCCESS.get(); - } - - private void generateAndCache(UUID uuid) throws WebException { - String html; - try { - html = getHtml(uuid); - infoSystem.getConnectionSystem().sendWideInfoRequest(infoRequestFactory.generateInspectPluginsTabRequest(uuid)); - } catch (NotFoundException e) { - html = responseFactory.notFound404(e.getMessage()).getContent(); - } - infoSystem.sendRequest(infoRequestFactory.cacheInspectPageRequest(uuid, html)); - } - - @Override - public void runLocally() throws WebException { - generateAndCache(playerUUID); - } - - private String getHtml(UUID uuid) throws WebException { - try { - - return pageFactory.inspectPage(uuid).toHtml(); - - } catch (ParseException e) { - Throwable cause = e.getCause(); - if (cause instanceof DBOpException) { - throw new TransferDatabaseException((DBOpException) cause); - } else if (cause instanceof IllegalStateException && "Player profile was null!".equals(cause.getMessage())) { - throw new NotFoundException("Player has not played on this server."); - } else { - throw new WebFailException("Exception during HTML Parsing", cause); - } - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPluginsTabRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPluginsTabRequest.java deleted file mode 100644 index 2c0ae4166..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPluginsTabRequest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.utilities.html.pages.PageFactory; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.Map; -import java.util.UUID; - -/** - * InfoRequest for Generating Inspect page plugins tab on receiving WebServer. - * - * @deprecated Marked for removal when the connection system will be removed. - * @author Rsl1122 - */ -@Deprecated -public class GenerateInspectPluginsTabRequest extends InfoRequestWithVariables implements GenerateRequest, WideRequest { - - private final InfoSystem infoSystem; - private final InfoRequestFactory infoRequestFactory; - private final PageFactory pageFactory; - - private UUID playerUUID; - - GenerateInspectPluginsTabRequest( - InfoSystem infoSystem, - InfoRequestFactory infoRequestFactory, - PageFactory pageFactory - ) { - this.infoSystem = infoSystem; - this.infoRequestFactory = infoRequestFactory; - this.pageFactory = pageFactory; - } - - GenerateInspectPluginsTabRequest( - UUID uuid, - InfoSystem infoSystem, - InfoRequestFactory infoRequestFactory, - PageFactory pageFactory - ) { - this(infoSystem, infoRequestFactory, pageFactory); - Verify.nullCheck(uuid); - playerUUID = uuid; - variables.put("player", uuid.toString()); - } - - @Override - public Response handleRequest(Map variables) throws WebException { - // Available variables: sender, player - - String player = variables.get("player"); - Verify.nullCheck(player, () -> new BadRequestException("Player UUID 'player' variable not supplied in the request.")); - - UUID uuid = UUID.fromString(player); - - generateAndCache(uuid); - - return DefaultResponses.SUCCESS.get(); - } - - private void generateAndCache(UUID uuid) throws WebException { - String[] navAndHtml = pageFactory.inspectPagePluginsContent(uuid).getContents(); - infoSystem.sendRequest(infoRequestFactory.cacheInspectPluginsTabRequest(uuid, navAndHtml[0], navAndHtml[1])); - } - - @Override - public void runLocally() throws WebException { - generateAndCache(playerUUID); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateRequest.java deleted file mode 100644 index 783536132..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/GenerateRequest.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -/** - * Interface for all InfoRequests that generate something. - * - * @author Rsl1122 - */ -public interface GenerateRequest extends InfoRequest { -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequest.java deleted file mode 100644 index 75de0c1f3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.webserver.response.Response; - -import java.util.Map; - -/** - * Represents a request that Plan servers can send each other. - * - * @author Rsl1122 - */ -public interface InfoRequest { - - Response handleRequest(Map variables) throws WebException; - - void runLocally() throws WebException; - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestFactory.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestFactory.java deleted file mode 100644 index e7ef56a49..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestFactory.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.export.HtmlExport; -import com.djrapitops.plan.system.export.JSONExport; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; -import com.djrapitops.plan.utilities.html.pages.PageFactory; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.task.RunnableFactory; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.UUID; - -/** - * Factory for {@link InfoRequest} objects used for server-server communications. - * - * @author Rsl1122 - */ -@Singleton -public class InfoRequestFactory { - - private final Lazy plugin; - private final Lazy config; - private final Lazy processing; - private final Lazy infoSystem; - private final Lazy connectionSystem; - private final Lazy webExceptionLogger; - private final Lazy serverInfo; - private final Lazy responseFactory; - private final Lazy pageFactory; - private final Lazy htmlExport; - private final Lazy jsonExport; - private final Lazy logger; - private final Lazy runnableFactory; - - @Inject - public InfoRequestFactory( - Lazy plugin, - Lazy config, - Lazy processing, - Lazy infoSystem, - Lazy connectionSystem, - Lazy webExceptionLogger, - Lazy serverInfo, - Lazy responseFactory, - Lazy pageFactory, - Lazy htmlExport, - Lazy jsonExport, - Lazy logger, - Lazy runnableFactory - ) { - this.plugin = plugin; - this.config = config; - this.processing = processing; - this.infoSystem = infoSystem; - this.connectionSystem = connectionSystem; - this.webExceptionLogger = webExceptionLogger; - this.serverInfo = serverInfo; - this.responseFactory = responseFactory; - this.pageFactory = pageFactory; - this.htmlExport = htmlExport; - this.jsonExport = jsonExport; - this.logger = logger; - this.runnableFactory = runnableFactory; - } - - public CacheRequest cacheAnalysisPageRequest(UUID serverUUID, String html) { - return new CacheAnalysisPageRequest( - serverUUID, html, - config.get(), processing.get(), - htmlExport.get(), jsonExport.get(), - serverInfo.get().getServerUUID() - ); - } - - public CacheRequest cacheInspectPageRequest(UUID uuid, String html) { - return new CacheInspectPageRequest( - uuid, html, - config.get(), processing.get(), - serverInfo.get(), - htmlExport.get(), jsonExport.get() - ); - } - - @Deprecated - public CacheRequest cacheInspectPluginsTabRequest(UUID uuid, String nav, String html) { - return new CacheInspectPluginsTabRequest(uuid, nav, html); - } - - public GenerateRequest generateAnalysisPageRequest(UUID serverUUID) { - return new GenerateAnalysisPageRequest(serverUUID, processing.get(), webExceptionLogger.get(), this, serverInfo.get(), infoSystem.get(), pageFactory.get()); - } - - public GenerateRequest generateInspectPageRequest(UUID uuid) { - return new GenerateInspectPageRequest(uuid, this, responseFactory.get(), pageFactory.get(), infoSystem.get()); - } - - @Deprecated - public GenerateInspectPluginsTabRequest generateInspectPluginsTabRequest(UUID uuid) { - return new GenerateInspectPluginsTabRequest(uuid, infoSystem.get(), this, pageFactory.get()); - } - - public SaveDBSettingsRequest saveDBSettingsRequest() { - return new SaveDBSettingsRequest(plugin.get(), config.get(), serverInfo.get(), logger.get(), runnableFactory.get()); - } - - public SetupRequest sendDBSettingsRequest(String addressOfThisServer) { - return new SendDBSettingsRequest(addressOfThisServer, serverInfo.get(), this, connectionSystem.get()); - } - - public CheckConnectionRequest checkConnectionRequest(String webAddress) { - return new CheckConnectionRequest(webAddress, serverInfo.get(), connectionSystem.get()); - } - - @Singleton - public static class Handlers { - - private final InfoRequestFactory factory; - - @Inject - public Handlers(InfoRequestFactory factory) { - this.factory = factory; - } - - CacheRequest cacheAnalysisPageRequest() { - return new CacheAnalysisPageRequest( - factory.config.get(), - factory.processing.get(), - factory.htmlExport.get(), - factory.jsonExport.get(), - factory.serverInfo.get().getServerUUID() - ); - } - - CacheRequest cacheInspectPageRequest() { - return new CacheInspectPageRequest( - factory.config.get(), - factory.processing.get(), - factory.serverInfo.get(), - factory.htmlExport.get(), - factory.jsonExport.get() - ); - } - - CacheRequest cacheInspectPluginsTabRequest() { - return new CacheInspectPluginsTabRequest(); - } - - CheckConnectionRequest checkConnectionRequest() { - return new CheckConnectionRequest(factory.serverInfo.get(), factory.connectionSystem.get()); - } - - GenerateRequest generateAnalysisPageRequest() { - return new GenerateAnalysisPageRequest( - factory.processing.get(), - factory.webExceptionLogger.get(), - factory, - factory.serverInfo.get(), - factory.infoSystem.get(), - factory.pageFactory.get() - ); - } - - GenerateRequest generateInspectPageRequest() { - return new GenerateInspectPageRequest( - factory, - factory.responseFactory.get(), - factory.pageFactory.get(), - factory.infoSystem.get() - ); - } - - GenerateRequest generateInspectPluginsTabRequest() { - return new GenerateInspectPluginsTabRequest( - factory.infoSystem.get(), - factory, - factory.pageFactory.get() - ); - } - - SetupRequest saveDBSettingsRequest() { - return new SaveDBSettingsRequest( - factory.plugin.get(), - factory.config.get(), - factory.serverInfo.get(), - factory.logger.get(), - factory.runnableFactory.get() - ); - } - - SetupRequest sendDBSettingsRequest() { - return new SendDBSettingsRequest( - factory.serverInfo.get(), - factory, - factory.connectionSystem.get() - ); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestWithVariables.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestWithVariables.java deleted file mode 100644 index b7bb0a104..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestWithVariables.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import java.util.HashMap; -import java.util.Map; - -/** - * Abstract InfoRequest that contains variables in request body. - *

- * Used to send request differently. - * - * @author Rsl1122 - */ -public abstract class InfoRequestWithVariables implements InfoRequest { - - protected final Map variables; - - public InfoRequestWithVariables() { - this.variables = new HashMap<>(); - } - - public Map getVariables() { - return variables; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequests.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequests.java deleted file mode 100644 index bac4f52b3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/InfoRequests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.HashMap; -import java.util.Map; - -/** - * Map object that holds {@link InfoRequest} objects used for handling incoming requests. - *

- * Convenience class for Dagger injection. - * - * @author Rsl1122 - */ -@Singleton -public class InfoRequests { - - private final InfoRequestFactory.Handlers handlerFactory; - - private final Map requestHandlers; - - @Inject - public InfoRequests(InfoRequestFactory.Handlers handlerFactory) { - this.handlerFactory = handlerFactory; - this.requestHandlers = new HashMap<>(); - } - - public void initializeRequests() { - putRequest(handlerFactory.cacheAnalysisPageRequest()); - putRequest(handlerFactory.cacheInspectPageRequest()); - putRequest(handlerFactory.cacheInspectPluginsTabRequest()); - - putRequest(handlerFactory.generateAnalysisPageRequest()); - putRequest(handlerFactory.generateInspectPageRequest()); - putRequest(handlerFactory.generateInspectPluginsTabRequest()); - - putRequest(handlerFactory.saveDBSettingsRequest()); - putRequest(handlerFactory.sendDBSettingsRequest()); - putRequest(handlerFactory.checkConnectionRequest()); - } - - private void putRequest(InfoRequest request) { - requestHandlers.put(request.getClass().getSimpleName().toLowerCase(), request); - } - - public InfoRequest get(String name) { - return requestHandlers.get(name); - } - - public void clear() { - requestHandlers.clear(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java deleted file mode 100644 index 9c3f6716d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.InternalErrorException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DatabaseSettings; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; -import com.djrapitops.plugin.utilities.Verify; - -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -/** - * InfoRequest for sending Database config settings to Bukkit servers. - * - * @author Rsl1122 - */ -public class SaveDBSettingsRequest extends InfoRequestWithVariables implements SetupRequest { - - private final PlanPlugin plugin; - private final PlanConfig config; - private final ServerInfo serverInfo; - private final PluginLogger logger; - private final RunnableFactory runnableFactory; - - SaveDBSettingsRequest( - PlanPlugin plugin, - PlanConfig config, - ServerInfo serverInfo, PluginLogger logger, - RunnableFactory runnableFactory - ) { - this.plugin = plugin; - this.config = config; - this.serverInfo = serverInfo; - this.logger = logger; - this.runnableFactory = runnableFactory; - - variables.put("DB_TYPE", "mysql"); // DatabaseSettings.TYPE - variables.put("DB_HOST", config.get(DatabaseSettings.MYSQL_HOST)); - variables.put("DB_USER", config.get(DatabaseSettings.MYSQL_USER)); - variables.put("DB_PASS", config.get(DatabaseSettings.MYSQL_PASS)); - variables.put("DB_DATABASE", config.get(DatabaseSettings.MYSQL_DATABASE)); - variables.put("DB_PORT", config.get(DatabaseSettings.MYSQL_PORT)); - } - - @Override - public void runLocally() { - /* Won't be run */ - } - - @Override - public Response handleRequest(Map variables) throws WebException { - if (serverInfo.getServer().isProxy()) { - return new BadRequestResponse("Not supposed to be called on a proxy server"); - } - if (config.isFalse(PluginSettings.BUNGEE_COPY_CONFIG)) { - return new BadRequestResponse("Bungee config settings overridden on this server."); - } - - try { - setSettings(variables); - logger.info("----------------------------------"); - logger.info("The Received Bungee Database Settings, restarting Plan.."); - logger.info("----------------------------------"); - return DefaultResponses.SUCCESS.get(); - } finally { - runnableFactory.create("Bungee Setup Restart Task", new AbsRunnable() { - @Override - public void run() { - plugin.reloadPlugin(true); - } - }).runTaskLater(TimeAmount.toTicks(2L, TimeUnit.SECONDS)); - } - } - - private void setSettings(Map variables) throws BadRequestException, InternalErrorException { - String type = variables.get("DB_TYPE"); - String host = variables.get("DB_HOST"); - String user = variables.get("DB_USER"); - String pass = variables.get("DB_PASS"); - String database = variables.get("DB_DATABASE"); - String portS = variables.get("DB_PORT"); - - Verify.nullCheck(type, () -> new BadRequestException("DB_TYPE not specified in the request.")); - Verify.nullCheck(host, () -> new BadRequestException("DB_HOST not specified in the request.")); - Verify.nullCheck(user, () -> new BadRequestException("DB_USER not specified in the request.")); - Verify.nullCheck(pass, () -> new BadRequestException("DB_PASS not specified in the request.")); - Verify.nullCheck(database, () -> new BadRequestException("DB_DATABASE not specified in the request.")); - Verify.nullCheck(portS, () -> new BadRequestException("DB_PORT not specified in the request.")); - - config.set(DatabaseSettings.MYSQL_PORT, portS); - config.set(DatabaseSettings.TYPE, type); - config.set(DatabaseSettings.MYSQL_HOST, host); - config.set(DatabaseSettings.MYSQL_USER, user); - config.set(DatabaseSettings.MYSQL_PASS, pass); - config.set(DatabaseSettings.MYSQL_DATABASE, database); - try { - config.save(); - } catch (IOException e) { - throw new InternalErrorException("Failed to Save Config", e); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java deleted file mode 100644 index 50cd628d2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; -import com.djrapitops.plan.api.exceptions.connection.GatewayException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse; -import com.djrapitops.plugin.utilities.Verify; - -import java.net.SocketException; -import java.util.Map; -import java.util.UUID; - -/** - * InfoRequest used for requesting DB settings from Bungee. - * - * @author Rsl1122 - */ -public class SendDBSettingsRequest extends InfoRequestWithVariables implements SetupRequest { - - private final ServerInfo serverInfo; - private final InfoRequestFactory infoRequestFactory; - private final ConnectionSystem connectionSystem; - - SendDBSettingsRequest( - ServerInfo serverInfo, InfoRequestFactory infoRequestFactory, ConnectionSystem connectionSystem - ) { - this.serverInfo = serverInfo; - this.infoRequestFactory = infoRequestFactory; - this.connectionSystem = connectionSystem; - } - - SendDBSettingsRequest( - String webServerAddress, - ServerInfo serverInfo, InfoRequestFactory infoRequestFactory, ConnectionSystem connectionSystem - ) { - this.serverInfo = serverInfo; - this.infoRequestFactory = infoRequestFactory; - this.connectionSystem = connectionSystem; - - Verify.nullCheck(webServerAddress, () -> new IllegalArgumentException("webServerAddress can not be null.")); - variables.put("address", webServerAddress); - } - - @Override - public void runLocally() { - /* Won't be run */ - } - - @Override - public Response handleRequest(Map variables) throws WebException { - // Available variables: sender, address - if (serverInfo.getServer().isNotProxy()) { - return new BadRequestResponse("Not supposed to be called on a non proxy server"); - } - - String address = variables.get("address"); - Verify.nullCheck(address, () -> new BadRequestException("WebServer Address ('address') not specified in the request.")); - - UUID serverUUID = UUID.fromString(variables.get("sender")); - - Server bukkit = new Server(-1, serverUUID, null, address, -1); - - try { - connectionSystem.sendInfoRequest(infoRequestFactory.saveDBSettingsRequest(), bukkit); - } catch (ConnectionFailException e) { - Throwable cause = e.getCause(); - if (!(cause instanceof SocketException) || !cause.getMessage().contains("Unexpected end of file from server")) { - throw new GatewayException(e.getMessage()); - } - } - - return DefaultResponses.SUCCESS.get(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SetupRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SetupRequest.java deleted file mode 100644 index 90d7ee759..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/SetupRequest.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -/** - * InfoRequest that is related to initial communications. - * - * @author Rsl1122 - */ -public interface SetupRequest extends InfoRequest { - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/WideRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/WideRequest.java deleted file mode 100644 index f4d5781c4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/WideRequest.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.request; - -/** - * InfoRequest that should be relayed to all Bukkit servers. - * - * @author Rsl1122 - */ -public interface WideRequest extends InfoRequest { -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/Server.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/Server.java deleted file mode 100644 index 8444fda99..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/Server.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server; - -import java.util.Objects; -import java.util.UUID; - -/** - * Represents a Server that is running Plan. - * - * @author Rsl1122 - */ -public class Server implements Comparable { - private final UUID uuid; - private int id; - private String name; - private String webAddress; - private int maxPlayers; - - public Server(int id, UUID uuid, String name, String webAddress, int maxPlayers) { - this.id = id; - this.uuid = uuid; - this.name = name; - this.webAddress = webAddress; - this.maxPlayers = maxPlayers; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public UUID getUuid() { - return uuid; - } - - public String getName() { - return name; - } - - public String getIdentifiableName() { - return !"Plan".equalsIgnoreCase(name) ? name : "Server " + id; - } - - public void setName(String name) { - this.name = name; - } - - public String getWebAddress() { - return webAddress; - } - - public void setWebAddress(String webAddress) { - this.webAddress = webAddress; - } - - public int getMaxPlayers() { - return maxPlayers; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Server that = (Server) o; - return Objects.equals(uuid, that.uuid) && - Objects.equals(name, that.name) && - Objects.equals(webAddress, that.webAddress); - } - - @Override - public int hashCode() { - return Objects.hash(uuid, id, name, webAddress); - } - - @Override - public String toString() { - return "Server{" + - "uuid=" + uuid + - ", id=" + id + - ", name='" + name + '\'' + - ", webAddress='" + webAddress + '\'' + - ", maxPlayers=" + maxPlayers + - '}'; - } - - @Override - public int compareTo(Server other) { - return Integer.compare(this.id, other.id); - } - - public boolean isProxy() { - return "BungeeCord".equals(name); - } - - public boolean isNotProxy() { - return !isProxy(); - } - - public void setMaxPlayers(int maxPlayers) { - this.maxPlayers = maxPlayers; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java deleted file mode 100644 index 4bbb56980..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.UUID; - -/** - * SubSystem for managing Server information. - *

- * Most information is accessible via static methods. - * - * @author Rsl1122 - */ -public abstract class ServerInfo implements SubSystem { - - protected Server server; - protected ServerProperties serverProperties; - - public ServerInfo(ServerProperties serverProperties) { - this.serverProperties = serverProperties; - } - - public Server getServer() { - return server; - } - - public UUID getServerUUID() { - return getServer().getUuid(); - } - - public ServerProperties getServerProperties() { - return serverProperties; - } - - @Override - public void enable() throws EnableException { - loadServerInfo(); - Verify.nullCheck(server, () -> new EnableException("Server information did not load!")); - } - - protected abstract void loadServerInfo() throws EnableException; - - @Override - public void disable() { - - } - - protected UUID generateNewUUID() { - return UUID.randomUUID(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfoFile.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfoFile.java deleted file mode 100644 index 2018b23e2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfoFile.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.settings.config.Config; -import com.djrapitops.plan.system.settings.config.ConfigReader; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import java.io.IOException; -import java.util.Optional; -import java.util.UUID; - -/** - * Manages local server info file. - *

- * Server.yml contains current server's ID, UUID and Bungee WebServer connection information. - * It - * - * @author Rsl1122 - */ -public class ServerInfoFile extends Config { - - private final PlanFiles files; - - @Inject - public ServerInfoFile(PlanFiles files) { - super(files.getFileFromPluginFolder("ServerInfoFile.yml")); - this.files = files; - } - - public void prepare() throws IOException { - try (ConfigReader reader = new ConfigReader(files.getResourceFromJar("DefaultServerInfoFile.yml").asInputStream())) { - copyMissing(reader.read()); - } - save(); - } - - public void saveServerUUID(UUID serverUUID) throws IOException { - set("Server.UUID", serverUUID.toString()); - save(); - } - - public Optional getUUID() { - String uuidString = getString("Server.UUID"); - if (Verify.isEmpty(uuidString)) { - return Optional.empty(); - } - return Optional.of(UUID.fromString(uuidString)); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerServerInfo.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerServerInfo.java deleted file mode 100644 index c6e31ddf2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerServerInfo.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.transactions.StoreServerInformationTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.ExecutionException; - -/** - * Manages the Server UUID for Bukkit servers. - *

- * Also manages Server ID required for MySQL database independence. - * - * @author Rsl1122 - */ -@Singleton -public class ServerServerInfo extends ServerInfo { - - private final ServerInfoFile serverInfoFile; - - private final PlanConfig config; - private final Processing processing; - private final DBSystem dbSystem; - private final Lazy webServer; - private final ErrorHandler errorHandler; - - @Inject - public ServerServerInfo( - ServerProperties serverProperties, - ServerInfoFile serverInfoFile, - Processing processing, - PlanConfig config, - DBSystem dbSystem, - Lazy webServer, - ErrorHandler errorHandler - ) { - super(serverProperties); - this.serverInfoFile = serverInfoFile; - this.processing = processing; - this.dbSystem = dbSystem; - this.webServer = webServer; - this.config = config; - this.errorHandler = errorHandler; - } - - @Override - public void enable() throws EnableException { - try { - serverInfoFile.prepare(); - } catch (IOException e) { - throw new EnableException("Failed to read ServerInfoFile.yml", e); - } - super.enable(); - } - - @Override - protected void loadServerInfo() throws EnableException { - Optional serverUUID = serverInfoFile.getUUID(); - try { - if (serverUUID.isPresent()) { - server = createServerObject(serverUUID.get()); - processing.submitNonCritical(() -> updateDbInfo(serverUUID.get())); - } else { - server = registerServer(); - } - } catch (DBOpException e) { - String causeMsg = e.getMessage(); - throw new EnableException("Failed to read Server information from Database: " + causeMsg, e); - } catch (IOException e) { - throw new EnableException("Failed to read ServerInfoFile.yml", e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (Exception e) { - throw new EnableException("Failed to perform a database transaction to store the server information", e); - } - } - - private void updateDbInfo(UUID serverUUID) { - Database db = dbSystem.getDatabase(); - - Optional foundServer = db.query(ServerQueries.fetchServerMatchingIdentifier(serverUUID)); - if (!foundServer.isPresent()) { - try { - server = registerServer(serverUUID); - } catch (ExecutionException | IOException e) { - errorHandler.log(L.CRITICAL, this.getClass(), e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - return; - } - - server = foundServer.get(); - - // Update information - String name = config.get(PluginSettings.SERVER_NAME).replaceAll("[^a-zA-Z0-9_\\s]", "_"); - server.setName("plan".equalsIgnoreCase(name) ? "Server " + server.getId() : name); - - String webAddress = webServer.get().getAccessAddress(); - server.setWebAddress(webAddress); - - int maxPlayers = serverProperties.getMaxPlayers(); - server.setMaxPlayers(maxPlayers); - - // Save - db.executeTransaction(new StoreServerInformationTransaction(server)); - } - - private Server registerServer() throws ExecutionException, InterruptedException, IOException { - return registerServer(generateNewUUID()); - } - - private Server registerServer(UUID serverUUID) throws ExecutionException, InterruptedException, IOException { - Database db = dbSystem.getDatabase(); - - Server server = createServerObject(serverUUID); - - // Save - db.executeTransaction(new StoreServerInformationTransaction(server)) - .get(); // Wait until transaction has completed - - // Load from database - server = db.query(ServerQueries.fetchServerMatchingIdentifier(serverUUID)) - .orElseThrow(() -> new IllegalStateException("Failed to Register Server (ID not found)")); - - // Store the UUID in ServerInfoFile - serverInfoFile.saveServerUUID(serverUUID); - return server; - } - - private Server createServerObject(UUID serverUUID) { - String webAddress = webServer.get().getAccessAddress(); - String name = config.get(PluginSettings.SERVER_NAME).replaceAll("[^a-zA-Z0-9_\\s]", "_"); - int maxPlayers = serverProperties.getMaxPlayers(); - return new Server(-1, serverUUID, name, webAddress, maxPlayers); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/properties/ServerProperties.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/properties/ServerProperties.java deleted file mode 100644 index fc9855c00..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/properties/ServerProperties.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.info.server.properties; - -import java.util.function.IntSupplier; -import java.util.function.Supplier; - -/** - * Class responsible for holding server variable values that do not change - * without a reload. - * - * @author Rsl1122 - */ -public abstract class ServerProperties { - - private final String name; - private final int port; - private final String version; - private final String implVersion; - private final Supplier ip; - private final int maxPlayers; - - private final IntSupplier onlinePlayers; - - protected ServerProperties( - String name, - int port, - String version, - String implVersion, - Supplier ip, - int maxPlayers, - IntSupplier onlinePlayers - ) { - this.name = name; - this.port = port; - this.version = version; - this.implVersion = implVersion; - this.ip = ip; - this.maxPlayers = maxPlayers; - this.onlinePlayers = onlinePlayers; - } - - /** - * Ip string in server.properties. - * - * @return the ip. - */ - public String getIp() { - return ip.get(); - } - - public String getName() { - return name; - } - - public int getPort() { - return port; - } - - public String getVersion() { - return version; - } - - public String getImplVersion() { - return implVersion; - } - - public int getMaxPlayers() { - return maxPlayers; - } - - public int getOnlinePlayers() { - return onlinePlayers.getAsInt(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/listeners/ListenerSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/listeners/ListenerSystem.java deleted file mode 100644 index 8524de03f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/listeners/ListenerSystem.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.listeners; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.SubSystem; - -public abstract class ListenerSystem implements SubSystem { - - @Override - public void enable() { - registerListeners(); - } - - @Override - public void disable() { - unregisterListeners(); - } - - protected abstract void registerListeners(); - - protected abstract void unregisterListeners(); - - public abstract void callEnableEvent(PlanPlugin plugin); - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LangCode.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LangCode.java deleted file mode 100644 index 77b127077..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LangCode.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale; - -/** - * Language enum of supported languages, follows ISO 639-1 for language codes. - * - * @author Rsl1122 - */ -public enum LangCode { - - CUSTOM("Custom", ""), - EN("English", "Rsl1122"), - CN("Simplified Chinese", "f0rb1d (佛壁灯) & qsefthuopq"), - DE("Deutch", "Eyremba & fuzzlemann & Morsmorse"), - FI("Finnish", "Rsl1122"), - FR("French", "CyanTech & Aurelien"), - JA("Japanese", "yukieji"), - TR("Turkish", "TDJisvan"), - PT_BR("Portuguese (Brazil)", "jvmuller"); - - private final String name; - private final String authors; - - LangCode(String name, String authors) { - this.name = name; - this.authors = authors; - } - - public static LangCode fromString(String code) { - try { - return LangCode.valueOf(code.toUpperCase()); - } catch (IllegalArgumentException e) { - return LangCode.EN; - } - } - - public String getName() { - return name; - } - - public String getAuthors() { - return authors; - } - - public String getFileName() { - return "locale_" + name() + ".txt"; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/Locale.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/Locale.java deleted file mode 100644 index 0a3c95763..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/Locale.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale; - -import com.djrapitops.plan.system.file.FileResource; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.locale.lang.*; - -import java.io.File; -import java.io.IOException; -import java.io.Serializable; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * Represents loaded language information. - * - * @author Rsl1122 - */ -public class Locale extends HashMap { - - public static Locale forLangCodeString(PlanFiles files, String code) throws IOException { - return forLangCode(LangCode.fromString(code), files); - } - - private LangCode langCode; - - public Locale() { - this(LangCode.EN); - } - - public Locale(LangCode langCode) { - this.langCode = langCode; - } - - public static Locale forLangCode(LangCode code, PlanFiles files) throws IOException { - return new LocaleFileReader(files.getResourceFromJar("locale/" + code.getFileName())).load(code); - } - - public static Locale fromFile(File file) throws IOException { - return new LocaleFileReader(new FileResource(file.getName(), file)).load(LangCode.CUSTOM); - } - - public LangCode getLangCode() { - return langCode; - } - - @Override - public Message get(Object key) { - Message storedValue = super.get(key); - if (key instanceof Lang && storedValue == null) { - return new Message(((Lang) key).getDefault()); - } else { - return storedValue; - } - } - - public String getString(Lang key) { - return get(key).toString(); - } - - public String getString(Lang key, Serializable... values) { - return get(key).parse(values); - } - - public String[] getArray(Lang key) { - return get(key).toArray(); - } - - public String[] getArray(Lang key, Serializable... values) { - return get(key).toArray(values); - } - - public void loadFromAnotherLocale(Locale locale) { - putAll(locale); - this.langCode = locale.langCode; - } - - public String replaceMatchingLanguage(String from) { - if (isEmpty()) { - return from; - } - - String replaced = from; - - Lang[][] langs = new Lang[][]{ - NetworkPageLang.values(), - PlayerPageLang.values(), - ServerPageLang.values(), - CommonHtmlLang.values() - }; - - List> entries = Arrays.stream(langs) - .flatMap(Arrays::stream) - .collect(Collectors.toMap(Function.identity(), this::get)) - .entrySet().stream() - // Longest first so that entries that contain each other don't partially replace. - .sorted((one, two) -> Integer.compare( - two.getKey().getIdentifier().length(), - one.getKey().getIdentifier().length() - )).collect(Collectors.toList()); - - for (Entry entry : entries) { - String defaultValue = entry.getKey().getDefault(); - String replacement = entry.getValue().toString(); - - replaced = replaced.replace(defaultValue, replacement); - } - return replaced; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Locale)) return false; - if (!super.equals(o)) return false; - Locale locale = (Locale) o; - return langCode == locale.langCode; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), langCode); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleFileReader.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleFileReader.java deleted file mode 100644 index 1738c9e96..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleFileReader.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale; - -import com.djrapitops.plan.system.file.Resource; -import com.djrapitops.plan.system.locale.lang.Lang; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -/** - * Utility for reading locale files. - * - * @author Rsl1122 - */ -public class LocaleFileReader { - - private List lines; - - public LocaleFileReader(Resource resource) throws IOException { - lines = resource.asLines(); - } - - public Locale load(LangCode code) { - Locale locale = new Locale(code); - - Map identifiers = LocaleSystem.getIdentifiers(); - lines.forEach(line -> { - String[] split = line.split(" \\|\\| "); - if (split.length == 2) { - String identifier = split[0].trim(); - Lang msg = identifiers.get(identifier); - if (msg != null) { - locale.put(msg, new Message(split[1])); - } - } - }); - - return locale; - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleFileWriter.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleFileWriter.java deleted file mode 100644 index c9852d199..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleFileWriter.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale; - -import com.djrapitops.plan.system.locale.lang.Lang; -import com.djrapitops.plan.utilities.comparators.LocaleEntryComparator; -import com.djrapitops.plan.utilities.comparators.StringLengthComparator; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Utility for writing a Locale into a file. - * - * @author Rsl1122 - */ -public class LocaleFileWriter { - - private Locale locale; - - public LocaleFileWriter(Locale locale) { - this.locale = locale; - } - - public void writeToFile(File file) throws IOException { - // Find longest identifier length for spacing - int length = LocaleSystem.getIdentifiers().keySet().stream() - .min(new StringLengthComparator()) - .map(String::length).orElse(0) + 2; - - addMissingLang(); - - List lines = createLines(length); - - write(file, lines); - } - - private void write(File file, List lines) throws IOException { - if (!file.exists()) { - Files.createFile(file.toPath()); - } - Files.write(file.toPath(), lines, StandardCharsets.UTF_8); - } - - private List createLines(int length) { - return locale.entrySet().stream() - .sorted(new LocaleEntryComparator()) - .map(entry -> { - String value = entry.getValue() != null ? entry.getValue().toString() : entry.getKey().getDefault(); - return getSpacedIdentifier(entry.getKey().getIdentifier(), length) + "|| " + value; - }) - .collect(Collectors.toList()); - } - - private void addMissingLang() { - for (Lang lang : LocaleSystem.getIdentifiers().values()) { - if (!locale.containsKey(lang)) { - locale.put(lang, new Message(lang.getDefault())); - } - } - } - - private String getSpacedIdentifier(String identifier, int length) { - StringBuilder b = new StringBuilder(identifier); - while (b.length() < length) { - b.append(" "); - } - return b.toString(); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleSystem.java deleted file mode 100644 index 02a734c71..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/LocaleSystem.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.locale.lang.*; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.webserver.auth.FailReason; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * System in charge of {@link Locale}. - * - * @author Rsl1122 - */ -@Singleton -public class LocaleSystem implements SubSystem { - - private final PlanPlugin plugin; - private final PlanFiles files; - private final PlanConfig config; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - private final Locale locale; - - @Inject - public LocaleSystem( - PlanPlugin plugin, - PlanFiles files, - PlanConfig config, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.plugin = plugin; - this.files = files; - this.config = config; - this.logger = logger; - this.errorHandler = errorHandler; - this.locale = new Locale(); - } - - public static Map getIdentifiers() { - Lang[][] lang = new Lang[][]{ - CommandLang.values(), - CmdHelpLang.values(), - DeepHelpLang.values(), - PluginLang.values(), - ManageLang.values(), - GenericLang.values(), - CommonHtmlLang.values(), - PlayerPageLang.values(), - ServerPageLang.values(), - NetworkPageLang.values(), - ErrorPageLang.values(), - FailReason.values(), - HealthInfoLang.values() - }; - - return Arrays.stream(lang) - .flatMap(Arrays::stream) - .collect(Collectors.toMap(Lang::getIdentifier, Function.identity())); - } - - @Override - public void enable() { - File localeFile = files.getLocaleFile(); - - if (config.isTrue(PluginSettings.WRITE_NEW_LOCALE)) { - writeNewDefaultLocale(localeFile); - } - - Optional loaded; - if (localeFile.exists()) { - loaded = loadFromFile(localeFile); - } else { - loaded = loadSettingLocale(); - } - loaded.ifPresent(locale::loadFromAnotherLocale); - - LangCode langCode = locale.getLangCode(); - logger.info("Locale: '" + langCode.getName() + "' by " + langCode.getAuthors()); - } - - private void writeNewDefaultLocale(File localeFile) { - try { - new LocaleFileWriter(localeFile.exists() ? Locale.fromFile(localeFile) : locale).writeToFile(localeFile); - } catch (IOException | IllegalStateException e) { - logger.error("Failed to write new Locale file at " + localeFile.getAbsolutePath()); - errorHandler.log(L.WARN, this.getClass(), e); - } - resetWriteConfigSetting(); - } - - private void resetWriteConfigSetting() { - try { - config.set(PluginSettings.WRITE_NEW_LOCALE, false); - config.save(); - } catch (IOException | IllegalStateException e) { - logger.error("Failed set WriteNewLocaleFileOnEnable back to false"); - errorHandler.log(L.WARN, this.getClass(), e); - } - } - - private Optional loadSettingLocale() { - try { - String setting = config.get(PluginSettings.LOCALE); - if (!"default".equalsIgnoreCase(setting)) { - return Optional.of(Locale.forLangCodeString(files, setting)); - } - } catch (IOException e) { - logger.warn("Failed to read locale from jar: " + config.get(PluginSettings.LOCALE) + ", " + e.toString()); - logger.warn("Using Default Locale as a fallback (EN)"); - } - return Optional.empty(); - } - - private Optional loadFromFile(File localeFile) { - try { - return Optional.of(Locale.fromFile(localeFile)); - } catch (IOException e) { - logger.warn("Failed to read locale file at " + localeFile.getAbsolutePath() + ", " + e.toString()); - logger.warn("Using Default Locale as a fallback (EN)"); - } - return Optional.empty(); - } - - @Override - public void disable() { - // No action necessary on disable. - } - - public Locale getLocale() { - return locale; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/Message.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/Message.java deleted file mode 100644 index b78467126..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/Message.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale; - -import com.djrapitops.plugin.utilities.Verify; -import org.apache.commons.text.StringSubstitutor; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -/** - * Represents a Message that can be modified by the caller. - * - * @author Rsl1122 - */ -public class Message { - - private final String content; - - public Message(String content) { - this.content = content; - } - - public String parse(Serializable... p) { - Verify.nullCheck(p); - - Map replaceMap = new HashMap<>(); - - for (int i = 0; i < p.length; i++) { - replaceMap.put(String.valueOf(i), p[i].toString()); - } - - StringSubstitutor sub = new StringSubstitutor(replaceMap); - - return sub.replace(content); - } - - public String[] toArray() { - return content.split("\\\\"); - } - - public String[] toArray(Serializable... p) { - return parse(p).split("\\\\"); - } - - @Override - public String toString() { - return content; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java deleted file mode 100644 index 52291faef..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * Lang for short help messages in Commands. - * - * @author Rsl1122 - */ -public enum CmdHelpLang implements Lang { - ANALYZE("Command Help - /plan analyze", "View the Server Page"), - HELP("Command Help - /plan help", "Show command list"), - INFO("Command Help - /plan info", "Check the version of Plan"), - INSPECT("Command Help - /plan inspect", "View a Player Page"), - QINSPECT("Command Help - /plan qinspect", "View Player info in game"), - SEARCH("Command Help - /plan search", "Search for a player name"), - PLAYERS("Command Help - /plan players", "View the Players Page"), - SERVERS("Command Help - /plan servers", "List servers in Database"), - NETWORK("Command Help - /plan network", "View the Network Page"), - RELOAD("Command Help - /plan reload", "Restart Plan"), - MANAGE("Command Help - /plan manage", "Manage Plan Database"), - WEB_REGISTER("Command Help - /plan register", "Register a Web User"), - WEB("Command Help - /plan webuser", "Manage Web Users"), - DEV("Command Help - /plan dev", "Development mode command"), - SETUP("Command Help - /planbungee setup", "Toggle set-up mode"), - CON("Command Help - /planbungee con", "Debug Proxy-Server connections"), - DISABLE("Command Help - /planbungee disable", "Disable the plugin temporarily"), - - MANAGE_MOVE("Command Help - /plan manage move", "Move data between Databases"), - MANAGE_BACKUP("Command Help - /plan manage backup", "Backup a Database"), - MANAGE_RESTORE("Command Help - /plan manage restore", "Restore a previous Backup"), - MANAGE_REMOVE("Command Help - /plan manage remove", "Remove Player's data"), - MANAGE_HOTSWAP("Command Help - /plan manage hotswap", "Change Database quickly"), - MANAGE_CLEAR("Command Help - /plan manage clear", "Clear a Database"), - MANAGE_CON("Command Help - /plan manage con", "Debug Server-Proxy connections"), - MANAGE_IMPORT("Command Help - /plan manage import", "Import data from elsewhere"), - MANAGE_EXPORT("Command Help - /plan manage export", "Trigger export manually"), - MANAGE_DISABLE("Command Help - /plan manage disable", "Disable a feature temporarily"), - MANAGE_SETUP("Command Help - /plan manage setup", "Set-up Server-Proxy connection"), - - WEB_LEVEL("Command Help - /plan web level", "Information about permission levels"), - WEB_LIST("Command Help - /plan web list", "List Web Users"), - WEB_CHECK("Command Help - /plan web check", "Inspect a Web User"), - WEB_DELETE("Command Help - /plan web delete", "Delete a Web User"), - MANAGE_RAW_DATA("Command Help - /plan manage raw", "View raw JSON of player data"), - MANAGE_UNINSTALLED("Command Help - /plan manage uninstalled", "Mark a server as uninstalled in the database."); - - private final String identifier; - private final String defaultValue; - - CmdHelpLang(String identifier, String defaultValue) { - this.identifier = identifier; - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CommandLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CommandLang.java deleted file mode 100644 index 52a1f29b3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CommandLang.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for general command language. - * - * @author Rsl1122 - */ -public enum CommandLang implements Lang { - FAIL_REQ_ARGS("Cmd FAIL - Requires Arguments", "§cArguments required (${0}) ${1}"), - FAIL_REQ_ONE_ARG("Cmd FAIL - Require only one Argument", "§cSingle Argument required ${1}"), - FAIL_NO_PERMISSION("Cmd FAIL - No Permission", "§cYou do not have the required permission."), - FAIL_USERNAME_NOT_VALID("Cmd FAIL - Invalid Username", "§cUser does not have an UUID."), - FAIL_USERNAME_NOT_KNOWN("Cmd FAIL - Unknown Username", "§cUser has not been seen on this server"), - FAIL_DATABASE_NOT_OPEN("Cmd FAIL - Database not open", "§cDatabase is ${0} - Please try again a bit later."), - WARN_DATABASE_NOT_OPEN("Cmd WARN - Database not open", "§eDatabase is ${0} - This might take longer than expected.."), - - FAIL_WEB_USER_EXISTS("Cmd FAIL - WebUser exists", "§cUser already exists!"), - FAIL_WEB_USER_NOT_EXISTS("Cmd FAIL - WebUser does not exists", "§cUser does not exists!"), - FAIL_NO_SUCH_FEATURE("Cmd FAIL - No Feature", "§eDefine a feature to disable! (currently supports ${0})"), - - FEATURE_DISABLED("Cmd SUCCESS - Feature disabled", "§aDisabled '${0}' temporarily until next plugin reload."), - - WEB_USER_REGISTER_SUCCESS("Cmd SUCCESS - WebUser register", "§aAdded a new user (${0}) successfully! You can view the web panel in the following link."), - WEB_USER_REGISTER_NOTIFY("Cmd Notify - WebUser register", "Registered new user: '${0}' Perm level: ${1}"), - WEB_USER_LIST("Web User Listing", " §2${0} §7: §f${1}"), - NO_WEB_USER_NOTIFY("Cmd Notify - No WebUser", "You might not have a web user, use /plan register "), - WEB_PERMISSION_LEVELS("Cmd Web - Permission Levels", ">\\§70: Access all pages\\§71: Access '/players' and all player pages\\§72: Access player page with the same username as the webuser\\§73+: No permissions"), - - CONNECT_SUCCESS("Cmd Setup - Success", "§aConnection successful, Plan may restart in a few seconds.."), - CONNECT_FORBIDDEN("Cmd Setup - Forbidden", "§eConnection succeeded, but Proxy has set-up mode disabled - use 'planbungee setup' on the proxy to enable it."), - CONNECT_BAD_REQUEST("Cmd Setup - Bad Request", "§eConnection succeeded, but Receiving server was a Bukkit or Sponge server. Use another address instead."), - CONNECT_UNAUTHORIZED("Cmd Setup - Unauthorized", "§eConnection succeeded, but Receiving server didn't authorize this server. Contact Discord for support"), - CONNECT_FAIL("Cmd Setup - Generic Fail", "§eConnection failed: ${0}"), - CONNECT_INTERNAL_ERROR("Cmd Setup - Internal Error", "§eConnection succeeded. ${0}, check possible ErrorLog on receiving server's debug page."), - CONNECT_GATEWAY("Cmd Setup - Gateway Error", "§eConnection succeeded, but Proxy failed to connect to this server (Did current web server restart?). Use /plan m con & /planbungee con to debug."), - CONNECT_WEBSERVER_NOT_ENABLED("Cmd Setup - WebServer not Enabled", "§cWebServer is not enabled on this server! Make sure it enables on boot!"), - CONNECT_URL_MISTAKE("Cmd Setup - Url mistake", "§cMake sure you're using the full address (Starts with http:// or https://) - Check Proxy enable log for the full address."), - - SETUP_ALLOWED("Cmd Setup - Allowed", "§aSet-up is now Allowed"), - SETUP_FORBIDDEN("Cmd Setup - Disallowed", "§cSet-up is now Forbidden"), - - LINK_CLICK_ME("Cmd - Click Me", "Click me"), - LINK_PREFIX("Cmd - Link", " §2Link: §f"), - - HEADER_SEARCH("Cmd Header - Search", "> §2${0} Results for §f${1}§2:"), - HEADER_ANALYSIS("Cmd Header - Analysis", "> §2Analysis Results"), - HEADER_INFO("Cmd Header - Info", "> §2Player Analytics"), - HEADER_INSPECT("Cmd Header - Inspect", "> §2Player: §f${0}"), - HEADER_SERVERS("Cmd Header - Servers", "> §2Servers"), - HEADER_PLAYERS("Cmd Header - Players", "> §2Players"), - HEADER_WEB_USERS("Cmd Header - Web Users", "> §2${0} Web Users"), - HEADER_NETWORK("Cmd Header - Network", "> §2Network Page"), - - INFO_VERSION("Cmd Info - Version", " §2Version: §f${0}"), - INFO_UPDATE("Cmd Info - Update", " §2Update Available: §f${0}"), - INFO_DATABASE("Cmd Info - Database", " §2Active Database: §f${0}"), - INFO_PROXY_CONNECTION("Cmd Info - Bungee Connection", " §2Connected to Proxy: §f${0}"), - - QINSPECT_ACTIVITY_INDEX("Cmd Qinspect - Activity Index", " §2Activity Index: §f${0} | ${1}"), - QINSPECT_REGISTERED("Cmd Qinspect - Registered", " §2Registered: §f${0}"), - QINSPECT_LAST_SEEN("Cmd Qinspect - Last Seen", " §2Last Seen: §f${0}"), - QINSPECT_GEOLOCATION("Cmd Qinspect - Geolocation", " §2Logged in from: §f${0}"), - QINSPECT_PLAYTIME("Cmd Qinspect - Playtime", " §2Playtime: §f${0}"), - QINSPECT_LONGEST_SESSION("Cmd Qinspect - Longest Session", " §2Longest Session: §f${0}"), - QINSPECT_TIMES_KICKED("Cmd Qinspect - Times Kicked", " §2Times Kicked: §f${0}"), - QINSPECT_PLAYER_KILLS("Cmd Qinspect - Player Kills", " §2Player Kills: §f${0}"), - QINSPECT_MOB_KILLS("Cmd Qinspect - Mob Kills", " §2Mob Kills: §f${0}"), - QINSPECT_DEATHS("Cmd Qinspect - Deaths", " §2Deaths: §f${0}"), - - DISABLE_DISABLED("Cmd Disable - Disabled", "§aPlan systems are now disabled. You can still use /planbungee reload to restart the plugin."), - - RELOAD_COMPLETE("Cmd Info - Reload Complete", "§aReload Complete"), - RELOAD_FAILED("Cmd Info - Reload Failed", "§cSomething went wrong during reload of the plugin, a restart is recommended."); - - private final String identifier; - private final String defaultValue; - - CommandLang(String identifier, String defaultValue) { - this.identifier = identifier; - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CommonHtmlLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CommonHtmlLang.java deleted file mode 100644 index f4849379d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CommonHtmlLang.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for commonly used .html replacement values. - * - * @author Rsl1122 - */ -public enum CommonHtmlLang implements Lang { - PLEASE_WAIT("Please wait..."), - - NAV_INFORMATION("Information"), - NAV_SESSIONS("Sessions"), - NAV_OVERVIEW("Overview"), - NAV_PLUGINS("Plugins"), - NAV_ONLINE_ACTIVITY("Online Activity"), - NAV_SEVER_HEALTH("Server Health"), - NAV_PERFORMANCE("Performance"), - NAV_PLAYERS("Players"), - NAV_GEOLOCATIONS("Geolocations"), - NAV_COMMAND_USAGE("Command Usage"), - NAV_NETWORK_PLAYERS("Network Players"), - - AVERAGE_PING("Average Ping"), - BEST_PING("Best Ping"), - WORST_PING("Worst Ping"), - PLAYERS_ONLINE_TEXT("Players Online"); - - private final String defaultValue; - - CommonHtmlLang(String defaultValue) { - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return "HTML - " + name(); - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java deleted file mode 100644 index 0ad3b310f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for in depth help language when /command ? is used. - * - * @author Rsl1122 - */ -public enum DeepHelpLang implements Lang { - PLAN("In Depth Help - /plan ?", "> §2Main Command\\ Access to subcommands and help\\ §2/plan §fList subcommands\\ §2/plan ? §fIn depth help"), - ANALYZE("In Depth Help - /plan analyze ?", "> §2Analysis Command\\ Refreshes server page and displays link to the web page."), - SETUP("In Depth Help - /planbungee setup ?", "> §2Set-up toggle Command\\ Toggles set-up mode on Proxy.\\ Safeguard against unauthorized MySQL snooping with another server."), - DISABLE("In Depth Help - /planbungee disable ?", "> §2Disable Command\\ Runs Plan onDisable on Proxy.\\ Plugin can be enabled with /planbungee reload afterwards.\\ §bDoes not support swapping jar on the fly"), - INSPECT("In Depth Help - /plan inspect ?", "> §2Inspect Command\\ Refreshes player page and displays link to the web page."), - PLAYERS("In Depth Help - /plan players ?", "> §2Players Command\\ Displays link to the players page."), - SERVERS("In Depth Help - /plan servers ?", "> §2Servers Command\\ Displays list of Plan servers in the Database.\\ Can be used to debug issues with database registration on a network."), - MANAGE("In Depth Help - /plan manage ?", "> §2Manage Command\\ Manage MySQL and SQLite database of Plan.\\ §2/plan m §fList subcommands\\ §2/plan m ? §fIn depth help"), - NETWORK("In Depth Help - /plan network ?", "> §2Network Command\\ Displays link to the network page.\\ If not on a network, this page displays the server page."), - QINSPECT("In Depth Help - /plan qinspect ?", "> §2Quick Inspect Command\\ Displays some information about the player in game."), - RELOAD("In Depth Help - /plan reload ?", "> §2Reload Command\\ Restarts the plugin using onDisable and onEnable.\\ §bDoes not support swapping jar on the fly"), - SEARCH("In Depth Help - /plan search ?", "> §2Search Command\\ Get a list of Player names that match the given argument.\\§7 Example: /plan search 123 - Finds all users with 123 in their name."), - WEB("In Depth Help - /plan web ?", "< §2Web User Manage Command.\\ §2/plan web §fList subcommands\\ §2/plan web ? §fIn Depth help"), - - MANAGE_BACKUP("In Depth Help - /plan manage backup ?", "> §2Backup Subcommand\\ Creates a new SQLite database (.db file) with contents of currently active database in the Plan plugin folder."), - MANAGE_CLEAR("In Depth Help - /plan manage clear ?", "> §2Clear Subcommand\\ Removes everything in the active database. Use with caution."), - MANAGE_CON("In Depth Help - /plan manage con ?", "> §2Connection Debug Subcommand\\ Used to debug connections in the network.\\ Sends a request to each server in the database."), - MANAGE_DISABLE("In Depth Help - /plan manage disable ?", "> §2Disable Subcommand\\ Can disable parts of the plugin until next reload.\\ Accepted arguments:\\ §2kickcount §fDisables kick counts in case /kickall is used on shutdown macro."), - MANAGE_IMPORT("In Depth Help - /plan manage import ?", "> §2Import Subcommand\\ Import data from other sources.\\ Accepted Arguments:\\ §2offline §fBukkit player data, only register date and name."), - MANAGE_EXPORT("In Depth Help - /plan manage export ?", "> §2Export Subcommand\\ Trigger export to result folders.\\ Accepted Arguments:\\ §2list §fList possible arguments.\\ §2players §fExport /players, /player pages + /player/raw json depending on config values.\\ §2server_json §fExport /server/raw JSON if enabled in config."), - MANAGE_MOVE("In Depth Help - /plan manage move ?", "> §2Move Subcommand\\ Move data from SQLite to MySQL or other way around.\\ Target database is cleared before transfer."), - MANAGE_REMOVE("In Depth Help - /plan manage remove ?", "> §2Remove Subcommand\\ Remove player's data from the active database."), - MANAGE_RESTORE("In Depth Help - /plan manage restore ?", "> §2Restore Subcommand\\ Restore a previous backup SQLite database (.db file)\\ You can also restore database.db from another server to MySQL.\\ Target database is cleared before transfer."), - MANAGE_SETUP("In Depth Help - /plan manage setup ?", "> §2Setup Subcommand\\ Set-up a connection between Bungee and this server for network functionality.\\ BungeeAddress can be found in the enable log on console when Plan enables on Bungee."), - - WEB_REGISTER("In Depth Help - /plan web register ?", "> §2Register Subcommand\\ Registers a new Web User.\\ Registering a user for another player requires plan.webmanage permission.\\ Passwords are hashed with PBKDF2 (64,000 iterations of SHA1) using a cryptographically-random salt."), - MANAGE_RAW_DATA("In Depth Help - /plan manage raw ?", "> §2Raw Data Subcommand\\ Displays link to raw JSON data page.\\ Not available if Plan webserver is not enabled."), - MANAGE_UNINSTALLED("In Depth Help - /plan manage uninstalled ?", "> §2Uninstalled Server Subcommand\\ Marks a server as uninstalled in the database.\\ Can not mark the server the command is being used on as uninstalled.\\ Will affect ConnectionSystem."); - - private final String identifier; - private final String defaultValue; - - DeepHelpLang(String identifier, String defaultValue) { - this.identifier = identifier; - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public String getDefault() { - return defaultValue; - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ErrorPageLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ErrorPageLang.java deleted file mode 100644 index eb2270d64..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ErrorPageLang.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for all error pages. - * - * @author Rsl1122 - */ -public enum ErrorPageLang implements Lang { - UUID_404("Player UUID was not found in the database."), - NO_SERVERS_404("No Servers online to perform the request."), - NOT_PLAYED_404("Player has not played on this server."), - UNKNOWN_PAGE_404("Make sure you're accessing a link given by a command, Examples:

/player/PlayerName
/server/ServerName

"), - UNAUTHORIZED_401("Unauthorized"), - AUTHENTICATION_FAILED_401("Authentication Failed."), - AUTH_FAIL_TIPS_401("- Ensure you have registered a user with /plan register
- Check that the username and password are correct
- Username and password are case-sensitive

If you have forgotten your password, ask a staff member to delete your old user and re-register."), - FORBIDDEN_403("Forbidden"), - ACCESS_DENIED_403("Access Denied"), - NOT_FOUND_404("Not Found"), - PAGE_NOT_FOUND_404("Page does not exist."), - ANALYSIS_REFRESH("Analysis is being refreshed.."), - ANALYSIS_REFRESH_LONG("Analysis is being run, refresh the page after a few seconds.."), - INSPECT_REFRESH("Player page request is being processed.."), - INSPECT_REFRESH_LONG("Page will refresh automatically.."), - PLUGIN_TAB_REFRESH("Calculating..."); - - private final String defaultValue; - - ErrorPageLang(String defaultValue) { - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return "HTML ERRORS - " + name(); - } - - @Override - public String getDefault() { - return defaultValue; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/GenericLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/GenericLang.java deleted file mode 100644 index 8d48f0e66..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/GenericLang.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for single words. - * - * @author Rsl1122 - */ -public enum GenericLang implements Lang { - YES("Positive", "Yes"), - NO("Negative", "No"), - UNKNOWN("Unknown", "Unknown"), - TODAY("Today", "'Today'"), - YESTERDAY("Yesterday", "'Yesterday'"); - - private final String identifier; - private final String defaultValue; - - GenericLang(String identifier, String defaultValue) { - this.identifier = identifier; - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/HealthInfoLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/HealthInfoLang.java deleted file mode 100644 index bc5698c44..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/HealthInfoLang.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} enum for {@link com.djrapitops.plan.data.store.mutators.health.AbstractHealthInfo} related language. - * - * @author Rsl1122 - */ -public enum HealthInfoLang implements Lang { - REGULAR_ACTIVITY_REMAIN("Regular Activity Remain", " ${0} of regular players have remained active (${1}/${2})"), - REGULAR_CHANGE("Regular Activity Change", " Number of regular players has "), - REGULAR_CHANGE_INCREASE("Regular Activity Change Increase", "increased (+${0})"), - REGULAR_CHANGE_ZERO("Regular Activity Change Zero", "stayed the same (+${0})"), - REGULAR_CHANGE_DECREASE("Regular Activity Change Decrease", "decreased (${0})"), - ACTIVE_PLAY_COMPARISON_INCREASE("Active Playtime Comparison Increase", " Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4)"), - ACTIVE_PLAY_COMPARISON_DECREASE("Active Playtime Comparison Decrease", " Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4)"), - NEW_PLAYER_JOIN_PLAYERS_GOOD("New Player Join Players, Yes", " New Players have players to play with when they join (${0} on average)"), - NEW_PLAYER_JOIN_PLAYERS_BAD("New Player Join Players, No", " New Players may not have players to play with when they join (${0} on average)"), - NEW_PLAYER_STICKINESS("New Player Stickiness", " ${0} of new players have stuck around (${1}/${2})"), - TPS_ABOVE_LOW_THERSHOLD("TPS Above Low Threshold", " Average TPS was above Low Threshold ${0} of the time"), - TPS_LOW_DIPS("TPS Low Dips", " Average TPS dropped below Low Threshold (${0}) ${1} times"), - DOWNTIME("Downtime", " Total Server downtime (No Data) was ${0}"), - NO_SERVERS_INACCURACY("No Servers Inaccuracy", " No Bukkit/Sponge servers to gather session data - These measures are inaccurate."), - SINGLE_SERVER_INACCURACY("Single Servers Inaccuracy", " Single Bukkit/Sponge server to gather session data."), - PLAYER_VISIT_PER_SERVER("Player Visit Server", " players visit on servers per day/server on average."), - PLAYER_REGISTER_PER_SERVER("Player Register Server", " players register on servers per day/server on average."), - PLAYER_PLAY_ON_NETWORK("Player Play on Network", " players played on the network:"); - - private final String identifier; - private final String defaultValue; - - HealthInfoLang(String identifier, String defaultValue) { - this.identifier = identifier; - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return "Health - " + identifier; - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/Lang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/Lang.java deleted file mode 100644 index 41c9a5dbb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/Lang.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * Interface for splitting different Language categories into different classes. - * - * @author Rsl1122 - */ -public interface Lang { - - String getIdentifier(); - - String getDefault(); - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ManageLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ManageLang.java deleted file mode 100644 index 7d706ef11..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ManageLang.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for Manage command related subcommand language. - * - * @author Rsl1122 - */ -public enum ManageLang implements Lang { - - HOTSWAP_REMINDER("Manage - Remind HotSwap", "§eRemember to swap to the new database (/plan m hotswap ${0}) & reload the plugin."), - PROGRESS_START("Manage - Start", "> §2Processing data.."), - PROGRESS_SUCCESS("Manage - Success", "> §aSuccess!"), - PROGRESS_FAIL("Manage - Fail", "> §cSomething went wrong: ${0}"), - - CONFIRMATION("Manage - Fail, Confirmation", "> §cAdd '-a' argument to confirm execution: ${0}"), - IMPORTERS("Manage - List Importers", "Importers: "), - - CON_NO_SERVERS("Manage - Fail, No Servers", "§cNo Servers found in the database."), - CON_EXCEPTION("Manage - Fail, Unexpected Exception", "§eOdd Exception: ${0}"), - CON_UNAUTHORIZED("Manage - Fail, Unauthorized", "§eFail reason: Unauthorized. Server might be using different database."), - CON_GENERIC_FAIL("Manage - Fail, Connection Exception", "§eFail reason: "), - CON_EXTERNAL_URL("Manage - Notify External Url", "§eNon-local address, check that port is open"), - CON_OLD_VERSION("Manage - Fail, Old version", "§eFail reason: Older Plan version on receiving server"), - - CONFIRM_OVERWRITE("Manage - Confirm Overwrite", "Data in ${0} will be overwritten!"), - CONFIRM_REMOVAL("Manage - Confirm Removal", "Data in ${0} will be removed!"), - - FAIL_SAME_DB("Manage - Fail Same Database", "> §cCan not operate on to and from the same database!"), - FAIL_INCORRECT_DB("Manage - Fail Incorrect Database", "> §c'${0}' is not a supported database."), - FAIL_FILE_NOT_FOUND("Manage - Fail File not found", "> §cNo File found at ${0}"), - FAIL_IMPORTER_NOT_FOUND("Manage - Fail No Importer", "§eImporter '${0}' doesn't exist"), - FAIL_EXPORTER_NOT_FOUND("Manage - Fail No Exporter", "§eExporter '${0}' doesn't exist"), - NO_SERVER("Manage - Fail No Server", "No server found with given parameters."), - UNINSTALLING_SAME_SERVER("Manage - Fail Same server", "Can not mark this server as uninstalled (You are on it)"); - - private final String identifier; - private final String defaultValue; - - ManageLang(String identifier, String defaultValue) { - this.identifier = identifier; - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/NetworkPageLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/NetworkPageLang.java deleted file mode 100644 index 2af6e06f3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/NetworkPageLang.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for player.html replacement values. - * - * @author Rsl1122 - */ -public enum NetworkPageLang implements Lang { - NETWORK("Network"), - NETWORK_INFORMATION("NETWORK INFORMATION"), - PLAYERS_TEXT("Players"), - PLAYERS("PLAYERS"), - NEW_TEXT("New"), - HEALTH_ESTIMATE("Health Estimate"); - - private final String defaultValue; - - NetworkPageLang(String defaultValue) { - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return "HTML - " + name(); - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/PlayerPageLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/PlayerPageLang.java deleted file mode 100644 index 9c36cdeb8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/PlayerPageLang.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for player.html replacement values. - * - * @author Rsl1122 - */ -public enum PlayerPageLang implements Lang { - ONLINE(" Online"), - OFFLINE(" Offline"), - TIMES_KICKED("Times Kicked"), - PLAYER_KILLS("Player Kills"), - MOB_KILLS("Mob Kills"), - DEATHS("Deaths"), - SESSIONS("Sessions"), - TOTAL_PLAYTIME("Total Playtime"), - PLAYTIME("Playtime"), - TOTAL_ACTIVE_TEXT("Total Active"), - TOTAL_AFK("Total AFK"), - SESSION_MEDIAN("Session Median"), - LONGEST("Longest"), - SESSION("Session"), - ACTIVITY_INDEX("Activity Index"), - INDEX_ACTIVE("Active"), - INDEX_VERY_ACTIVE("Very Active"), - INDEX_REGULAR("Regular"), - INDEX_IRREGULAR("Irregular"), - INDEX_INACTIVE("Inactive"), - FAVORITE_SERVER("Favorite Server"), - REGISTERED("REGISTERED"), - LAST_SEEN("LAST SEEN"), - PUNCH_CARD("Punchcard"), - SEEN_NICKNAMES("Seen Nicknames"), - NICKNAME("Nickname"), - SERVER("Server"), - LAST_SEEN_TEXT("Last Seen"), - CONNECTION_INFORMATION("Connection Information"), - IP_ADDRESS("IP-address"), - GEOLOCATION("Geolocation"), - LAST_CONNECTED("Last Connected"), - LOCAL_MACHINE("Local Machine"), - CALENDAR_TEXT(" Calendar"), - MOST_RECENT_SESSIONS("Most Recent Sessions"), - SESSION_ENDED("Session Ended"), - SESSION_LENGTH("Session Lenght"), - - WORLD(" World"), - SERVER_PREFERENCE("Server Preference"), - LAST_30_DAYS("LAST 30 DAYS"), - LAST_7_DAYS("LAST 7 DAYS"), - LAST_24_HOURS("LAST 24 HOURS"), - SERVERS("Servers"), - OPERATOR("Operator"), - BANNED("Banned"), - OVERVIEW("OVERVIEW"), - PLAYER_CAUSED_DEATHS("Player caused Deaths"), - MOB_CAUSED_DEATHS("Mob caused Deaths"), - MOB_KDR("Mob KDR"), - TIME(" Time"), - KILLED("Killed"), - WITH("

With"), - KILLED_BY("Killed by"), - NO_KILLS("No Kills"), - NO_PLAYER_CAUSED_DEATHS("No Player caused Deaths"); - - private final String defaultValue; - - PlayerPageLang(String defaultValue) { - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return "HTML - " + name(); - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/PluginLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/PluginLang.java deleted file mode 100644 index 931b80b34..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/PluginLang.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for Language that is logged when the plugin enables or disables. - * - * @author Rsl1122 - */ -public enum PluginLang implements Lang { - ENABLED("Enable", "Player Analytics Enabled."), - ENABLED_WEB_SERVER("Enable - WebServer", "Webserver running on PORT ${0} (${1})"), - ENABLED_DATABASE("Enable - Database", "${0}-database connection established."), - - ENABLE_NOTIFY_EMPTY_IP("Enable - Notify Empty IP", "IP in server.properties is empty & AlternativeIP is not in use. Incorrect links will be given!"), - ENABLE_NOTIFY_WEB_SERVER_DISABLED("Enable - Notify Webserver disabled", "WebServer was not initialized. (WebServer.DisableWebServer: true)"), - ENABLE_NOTIFY_GEOLOCATIONS_INTERNET_REQUIRED("Enable - Notify Geolocations Internet Required", "Plan Requires internet access on first run to download GeoLite2 Geolocation database."), - ENABLE_NOTIFY_GEOLOCATIONS_DISABLED("Enable - Notify Geolocations disabled", "Geolocation gathering is not active. (Data.Geolocations: false)"), - ENABLE_NOTIFY_ADDRESS_CONFIRMATION("Enable - Notify Address Confirmation", "Make sure that this address points to THIS Server: ${0}"), - - ENABLE_FAIL_DB("Enable FAIL - Database", "${0}-Database Connection failed: ${1}"), - ENABLE_FAIL_WRONG_DB("Enable FAIL - Wrong Database Type", "${0} is not a supported Database"), - ENABLE_FAIL_DB_PATCH("Enable FAIL - Database Patch", "Database Patching failed, plugin has to be disabled. Please report this issue"), - ENABLE_FAIL_NO_WEB_SERVER_PROXY("Enable FAIL - WebServer (Proxy)", "WebServer did not initialize!"), - ENABLE_FAIL_GEODB_WRITE("Enable FAIL - GeoDB Write", "Something went wrong saving the downloaded GeoLite2 Geolocation database"), - - WEB_SERVER_FAIL_PORT_BIND("WebServer FAIL - Port Bind", "WebServer was not initialized successfully. Is the port (${0}) in use?"), - WEB_SERVER_FAIL_SSL_CONTEXT("WebServer FAIL - SSL Context", "WebServer: SSL Context Initialization Failed."), - WEB_SERVER_FAIL_STORE_LOAD("WebServer FAIL - Store Load", "WebServer: SSL Certificate loading Failed."), - WEB_SERVER_NOTIFY_NO_CERT_FILE("WebServer - Notify no Cert file", "WebServer: Certificate KeyStore File not Found: ${0}"), - WEB_SERVER_NOTIFY_HTTP("WebServer - Notify HTTP", "WebServer: No Certificate -> Using HTTP-server for Visualization."), - WEB_SERVER_NOTIFY_HTTP_USER_AUTH("WebServer - Notify HTTP User Auth", "WebServer: User Authorization Disabled! (Not secure over HTTP)"), - - DISABLED("Disable", "Player Analytics Disabled."), - DISABLED_WEB_SERVER("Disable - WebServer", "Webserver has been disabled."), - DISABLED_PROCESSING("Disable - Processing", "Processing critical unprocessed tasks. (${0})"), - DISABLED_PROCESSING_COMPLETE("Disable - Processing Complete", "Processing complete."), - DISABLED_UNSAVED_SESSIONS("Disable - Unsaved Session Save", "Saving unfinished sessions.."), - - VERSION_NEWEST("Version - Latest", "You're using the latest version."), - VERSION_AVAILABLE("Version - New", "New Release (${0}) is available ${1}"), - VERSION_AVAILABLE_SPIGOT("Version - New (old)", "New Version is available at ${0}"), - VERSION_AVAILABLE_DEV("Version - DEV", " This is a DEV release."), - VERSION_FAIL_READ_VERSIONS("Version FAIL - Read versions.txt", "Version information could not be loaded from Github/versions.txt"), - VERSION_FAIL_READ_OLD("Version FAIL - Read info (old)", "Failed to check newest version number"), - - DB_APPLY_PATCH("Database - Apply Patch", "Applying Patch: ${0}.."), - DB_APPLIED_PATCHES("Database - Patches Applied", "All database patches applied successfully."), - DB_APPLIED_PATCHES_ALREADY("Database - Patches Applied Already", "All database patches already applied."), - DB_NOTIFY_CLEAN("Database Notify - Clean", "Removed data of ${0} players."), - DB_NOTIFY_SQLITE_WAL("Database Notify - SQLite No WAL", "SQLite WAL mode not supported on this server version, using default. This may or may not affect performance."), - DB_MYSQL_LAUNCH_OPTIONS_FAIL("Database MySQL - Launch Options Error", "Launch Options were faulty, using default (${0})"); - - private final String identifier; - private final String defaultValue; - - PluginLang(String identifier, String defaultValue) { - this.identifier = identifier; - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return identifier; - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ServerPageLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ServerPageLang.java deleted file mode 100644 index 1c0642eb0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ServerPageLang.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.locale.lang; - -/** - * {@link Lang} implementation for player.html replacement values. - * - * @author Rsl1122 - */ -public enum ServerPageLang implements Lang { - SERVER_ANALYSIS("Server Analysis"), - PLAYERS_ONLINE("PLAYERS ONLINE"), - UNIQUE("UNIQUE"), - NEW("NEW"), - REGULAR("REGULAR"), - TOTAL_PLAYERS("Total Players"), - UNIQUE_PLAYERS_TEXT("Unique Players"), - NEW_PLAYERS_TEXT("New Players"), - PER_DAY("/ Day"), - LAST_PEAK("Last Peak"), - ALL_TIME_PEAK("All Time Peak"), - SERVER_INFORMATION("SERVER INFORMATION"), - USER_INFORMATION("USER INFORMATION"), - RECENT_LOGINS("RECENT LOGINS"), - ONLINE_ACTIVITY("ONLINE ACTIVITY"), - UNIQUE_PLAYERS("UNIQUE PLAYERS"), - CALENDAR("CALENDAR"), - PUNCHCARD("PUNCHCARD"), - UNIQUE_CALENDAR("Unique:"), - NEW_CALENDAR("New:"), - NEW_RETENTION("New Player Retention"), - PREDICETED_RETENTION("Predicted Retention"), - SERVER_HEALTH_ESTIMATE("Server Health Estimate"), - LAST_30_DAYS_TEXT("Last 30 Days"), - PLAYERBASE_DEVELOPMENT("Playerbase Development"), - CURRENT_PLAYERBASE("Current Playerbase"), - WORLD_PLAYTIME("World Playtime"), - WORLD_LOAD("WORLD LOAD"), - ALL("ALL"), - LOW_TPS_SPIKES("Low TPS Spikes"), - USAGE(" Usage"), - LOADED_ENTITIES("Loaded Entities"), - LOADED_CHUNKS("Loaded Chunks"), - ENTITIES("Entities"), - CHUNKS("Chunks"), - AVG("AVG"), - PLAYER_LIST("Player List"), - NAME(" Name"), - REGISTERED_TEXT("Registered"), - GEOLOCATION_TEXT("Geolocation"), - COUNTRY("Country"), - COMMNAND_USAGE("Command Usage"), - USED_COMMANDS("Used Commands"), - UNIQUE_TEXT("Unique"), - COMMAND(" Command"), - TIMES_USED("Times Used"), - FREE_DISK_SPACE("Free Disk Space"), - DISK_SPACE("DISK SPACE"), - ; - - private final String defaultValue; - - ServerPageLang(String defaultValue) { - this.defaultValue = defaultValue; - } - - @Override - public String getIdentifier() { - return "HTML - " + name(); - } - - @Override - public String getDefault() { - return defaultValue; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/CriticalCallable.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/CriticalCallable.java deleted file mode 100644 index 073ed62ba..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/CriticalCallable.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.processing; - -import java.util.concurrent.Callable; - -public interface CriticalCallable extends Callable { -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/CriticalRunnable.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/CriticalRunnable.java deleted file mode 100644 index 3a61079ec..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/CriticalRunnable.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.processing; - -public interface CriticalRunnable extends Runnable { -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/Processing.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/Processing.java deleted file mode 100644 index ca08796ee..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/Processing.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.processing; - -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.List; -import java.util.concurrent.*; - -@Singleton -public class Processing implements SubSystem { - - private final Lazy locale; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - private ExecutorService nonCriticalExecutor; - private ExecutorService criticalExecutor; - - @Inject - public Processing( - Lazy locale, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.locale = locale; - this.logger = logger; - this.errorHandler = errorHandler; - nonCriticalExecutor = createExecutor(6, "Plan Non critical-pool-%d"); - criticalExecutor = createExecutor(2, "Plan Critical-pool-%d"); - } - - protected ExecutorService createExecutor(int i, String s) { - return Executors.newFixedThreadPool(i, new ThreadFactoryBuilder().setNameFormat(s).build()); - } - - public void submit(Runnable runnable) { - if (runnable instanceof CriticalRunnable) { - submitCritical(runnable); - return; - } - submitNonCritical(runnable); - } - - public void submitNonCritical(Runnable runnable) { - if (runnable == null || nonCriticalExecutor.isShutdown()) { - return; - } - CompletableFuture.supplyAsync(() -> { - runnable.run(); - return true; - }, nonCriticalExecutor).handle(this::exceptionHandlerNonCritical); - } - - public void submitCritical(Runnable runnable) { - if (runnable == null) return; - CompletableFuture.supplyAsync(() -> { - runnable.run(); - return true; - }, criticalExecutor).handle(this::exceptionHandlerCritical); - } - - public Future submit(Callable task) { - if (task instanceof CriticalCallable) { - return submitCritical(task); - } - return submitNonCritical(task); - } - - public Future submitNonCritical(Callable task) { - if (task == null || nonCriticalExecutor.isShutdown()) { - return null; - } - return CompletableFuture.supplyAsync(() -> { - try { - return task.call(); - } catch (Exception e) { - throw new IllegalStateException(e); - } - }, nonCriticalExecutor).handle(this::exceptionHandlerNonCritical); - } - - private T exceptionHandlerNonCritical(T t, Throwable throwable) { - if (throwable != null) { - errorHandler.log(L.WARN, Processing.class, throwable.getCause()); - } - return t; - } - - private T exceptionHandlerCritical(T t, Throwable throwable) { - if (throwable != null) { - errorHandler.log(L.ERROR, Processing.class, throwable.getCause()); - } - return t; - } - - public Future submitCritical(Callable task) { - if (task == null) return null; - return CompletableFuture.supplyAsync(() -> { - try { - return task.call(); - } catch (Exception e) { - throw new IllegalStateException(e); - } - }, criticalExecutor).handle(this::exceptionHandlerCritical); - } - - @Override - public void enable() { - if (nonCriticalExecutor.isShutdown()) { - nonCriticalExecutor = createExecutor(6, "Plan Non critical-pool-%d"); - } - if (criticalExecutor.isShutdown()) { - criticalExecutor = createExecutor(2, "Plan Critical-pool-%d"); - } - } - - @Override - public void disable() { - shutdownNonCriticalExecutor(); - shutdownCriticalExecutor(); - ensureShutdown(); - logger.info(locale.get().getString(PluginLang.DISABLED_PROCESSING_COMPLETE)); - } - - private void shutdownNonCriticalExecutor() { - nonCriticalExecutor.shutdown(); - } - - private void shutdownCriticalExecutor() { - List criticalTasks = criticalExecutor.shutdownNow(); - logger.info(locale.get().getString(PluginLang.DISABLED_PROCESSING, criticalTasks.size())); - for (Runnable runnable : criticalTasks) { - if (runnable == null) continue; - try { - runnable.run(); - } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { - errorHandler.log(L.WARN, this.getClass(), e); - } - } - } - - private void ensureShutdown() { - try { - if (!nonCriticalExecutor.isTerminated() && !nonCriticalExecutor.awaitTermination(1, TimeUnit.SECONDS)) { - nonCriticalExecutor.shutdownNow(); - } - if (!criticalExecutor.isTerminated()) { - criticalExecutor.shutdownNow(); - } - } catch (InterruptedException e) { - logger.error("Processing shutdown thread interrupted: " + e.getMessage()); - nonCriticalExecutor.shutdownNow(); - criticalExecutor.shutdownNow(); - Thread.currentThread().interrupt(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/Processors.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/Processors.java deleted file mode 100644 index 2bc0341d7..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/Processors.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.processing.processors; - -import com.djrapitops.plan.system.processing.processors.info.InfoProcessors; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Factory for creating Runnables to run with {@link com.djrapitops.plan.system.processing.Processing}. - * - * @author Rsl1122 - */ -@Singleton -public class Processors { - - private final InfoProcessors infoProcessors; - - @Inject - public Processors( - InfoProcessors infoProcessors - ) { - this.infoProcessors = infoProcessors; - } - - public InfoProcessors info() { - return infoProcessors; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java deleted file mode 100644 index 4331bb963..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.processing.processors.info; - -import com.djrapitops.plan.system.export.HtmlExport; -import com.djrapitops.plan.system.export.JSONExport; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plugin.command.Sender; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.UUID; -import java.util.function.BiConsumer; - -/** - * Factory for creating Runnables related to {@link InfoSystem} to run with {@link com.djrapitops.plan.system.processing.Processing}. - * - * @author Rsl1122 - */ -@Singleton -public class InfoProcessors { - - private final Lazy config; - private final Lazy htmlExport; - private final Lazy jsonExport; - private final Lazy infoSystem; - private final Lazy webExceptionLogger; - - @Inject - public InfoProcessors( - Lazy config, - Lazy htmlExport, - Lazy jsonExport, - Lazy infoSystem, - Lazy webExceptionLogger - ) { - this.config = config; - this.htmlExport = htmlExport; - this.jsonExport = jsonExport; - this.infoSystem = infoSystem; - this.webExceptionLogger = webExceptionLogger; - } - - public InspectCacheRequestProcessor inspectCacheRequestProcessor( - UUID uuid, - Sender sender, - String playerName, - BiConsumer msgSender - ) { - return new InspectCacheRequestProcessor(uuid, sender, playerName, msgSender, - infoSystem.get(), webExceptionLogger.get() - ); - } - - public PlayerPageUpdateProcessor playerPageUpdateProcessor(UUID uuid) { - return new PlayerPageUpdateProcessor(uuid, config.get(), htmlExport.get(), jsonExport.get()); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InspectCacheRequestProcessor.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InspectCacheRequestProcessor.java deleted file mode 100644 index 3a4c46d7d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InspectCacheRequestProcessor.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.processing.processors.info; - -import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.NotFoundException; -import com.djrapitops.plan.api.exceptions.connection.UnauthorizedServerException; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plugin.command.Sender; - -import java.util.UUID; -import java.util.function.BiConsumer; - -/** - * Sends a request to cache players inspect page to the ResponseCache on the appropriate WebServer. - * - * @author Rsl1122 - */ -public class InspectCacheRequestProcessor implements Runnable { - - private final UUID uuid; - private final Sender sender; - private final String playerName; - private final BiConsumer msgSender; - - private final InfoSystem infoSystem; - private final WebExceptionLogger webExceptionLogger; - - InspectCacheRequestProcessor( - UUID uuid, - Sender sender, - String playerName, - BiConsumer msgSender, - InfoSystem infoSystem, - WebExceptionLogger webExceptionLogger - ) { - this.uuid = uuid; - this.sender = sender; - this.playerName = playerName; - this.msgSender = msgSender; - this.infoSystem = infoSystem; - this.webExceptionLogger = webExceptionLogger; - } - - @Override - public void run() { - SessionCache.refreshActiveSessionsState(); - webExceptionLogger.logIfOccurs(this.getClass(), () -> { - try { - infoSystem.generateAndCachePlayerPage(uuid); - msgSender.accept(sender, playerName); - } catch (ConnectionFailException | UnauthorizedServerException - | NotFoundException | NoServersException e) { - sender.sendMessage("§c" + e.getMessage()); - } - }); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java deleted file mode 100644 index 0f80614d9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.processing.processors.info; - -import com.djrapitops.plan.system.export.HtmlExport; -import com.djrapitops.plan.system.export.JSONExport; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.ExportSettings; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; - -import java.util.UUID; - -public class PlayerPageUpdateProcessor implements Runnable { - - private final UUID playerUUID; - - private final PlanConfig config; - private final HtmlExport htmlExport; - private final JSONExport jsonExport; - - PlayerPageUpdateProcessor( - UUID playerUUID, - PlanConfig config, - HtmlExport htmlExport, - JSONExport jsonExport - ) { - this.playerUUID = playerUUID; - this.config = config; - this.htmlExport = htmlExport; - this.jsonExport = jsonExport; - } - - @Override - public void run() { - ResponseCache.clearResponse(PageId.PLAYER.of(playerUUID)); - - if (config.get(ExportSettings.EXPORT_ON_ONLINE_STATUS_CHANGE)) { - if (config.get(ExportSettings.PLAYER_JSON)) { - jsonExport.exportPlayerJSON(playerUUID); - } - if (config.get(ExportSettings.PLAYER_PAGES)) { - htmlExport.exportPlayerPage(playerUUID); - } - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/player/MobKillProcessor.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/player/MobKillProcessor.java deleted file mode 100644 index 5199d641b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/player/MobKillProcessor.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.processing.processors.player; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.processing.CriticalRunnable; - -import java.util.Optional; -import java.util.UUID; - -/** - * Processor Class for KillEvent information when the killer is a - * player. - *

- * Adds PlayerKill or a Mob kill to the active Session. - * - * @author Rsl1122 - */ -public class MobKillProcessor implements CriticalRunnable { - - private final UUID uuid; - - /** - * Constructor. - * - * @param uuid UUID of the killer. - */ - public MobKillProcessor(UUID uuid) { - this.uuid = uuid; - } - - @Override - public void run() { - Optional cachedSession = SessionCache.getCachedSession(uuid); - if (!cachedSession.isPresent()) { - return; - } - Session session = cachedSession.get(); - - session.mobKilled(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerKillProcessor.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerKillProcessor.java deleted file mode 100644 index 44930fd85..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerKillProcessor.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.processing.processors.player; - -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.processing.CriticalRunnable; - -import java.util.Optional; -import java.util.UUID; - -/** - * Processor Class for KillEvent information when the killer is a - * player. - *

- * Adds PlayerKill or a Mob kill to the active Session. - * - * @author Rsl1122 - */ -public class PlayerKillProcessor implements CriticalRunnable { - - private final UUID killer; - private final UUID victim; - private final String weaponName; - private final long time; - - /** - * Constructor. - * - * @param killer UUID of the killer. - * @param time Epoch ms the event occurred. - * @param victim Dead entity (Mob or Player) - * @param weaponName Weapon used. - */ - public PlayerKillProcessor(UUID killer, long time, UUID victim, String weaponName) { - this.killer = killer; - this.time = time; - this.victim = victim; - this.weaponName = weaponName; - } - - @Override - public void run() { - Optional cachedSession = SessionCache.getCachedSession(killer); - if (!cachedSession.isPresent()) { - return; - } - Session session = cachedSession.get(); - - session.playerKilled(new PlayerKill(victim, weaponName, time)); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/BukkitConfigSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/BukkitConfigSystem.java deleted file mode 100644 index 6cc19dc24..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/BukkitConfigSystem.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.settings.changes.ConfigUpdater; -import com.djrapitops.plan.system.settings.config.ConfigReader; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.network.ServerSettingsManager; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; - -/** - * ConfigSystem for Bukkit. - *

- * Bukkit and Bungee have different default config file inside the jar. - * - * @author Rsl1122 - */ -@Singleton -public class BukkitConfigSystem extends ConfigSystem { - - private final ConfigUpdater configUpdater; - private final ServerSettingsManager serverSettingsManager; - - @Inject - public BukkitConfigSystem( - PlanFiles files, - PlanConfig config, - ConfigUpdater configUpdater, - ServerSettingsManager serverSettingsManager, - Theme theme, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(files, config, theme, logger, errorHandler); - this.configUpdater = configUpdater; - this.serverSettingsManager = serverSettingsManager; - } - - @Override - public void enable() throws EnableException { - super.enable(); - if (config.isTrue(PluginSettings.BUNGEE_COPY_CONFIG)) { - serverSettingsManager.enable(); - } - } - - @Override - public void disable() { - serverSettingsManager.disable(); - super.disable(); - } - - @Override - protected void copyDefaults() throws IOException { - configUpdater.applyConfigUpdate(config); - try (ConfigReader reader = new ConfigReader(files.getResourceFromJar("config.yml").asInputStream())) { - config.copyMissing(reader.read()); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/ConfigSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/ConfigSystem.java deleted file mode 100644 index 128dd0171..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/ConfigSystem.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.debug.*; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Singleton; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * System for Config and other user customizable options. - * - * @author Rsl1122 - */ -@Singleton -public abstract class ConfigSystem implements SubSystem { - - protected final PlanFiles files; - protected final PlanConfig config; - protected final Theme theme; - protected final PluginLogger logger; - protected final ErrorHandler errorHandler; - - public ConfigSystem( - PlanFiles files, - PlanConfig config, - Theme theme, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.files = files; - this.config = config; - this.theme = theme; - this.logger = logger; - this.errorHandler = errorHandler; - } - - public PlanConfig getConfig() { - return config; - } - - public Theme getTheme() { - return theme; - } - - @Override - public void enable() throws EnableException { - try { - copyDefaults(); - config.reorder(Arrays.asList( - "Server", "Network", "Plugin", "Database", "Webserver", - "Data_gathering", "Time", "Display_options", "Formatting", "World_aliases", "Export", "Plugins" - )); - config.save(); - - if (logger.getDebugLogger() instanceof CombineDebugLogger) { - setDebugMode(); - } - } catch (IOException e) { - throw new EnableException("Failed to save default config: " + e.getMessage(), e); - } - theme.enable(); - } - - private void setDebugMode() { - CombineDebugLogger debugLogger = (CombineDebugLogger) logger.getDebugLogger(); - - String debugMode = config.get(PluginSettings.DEBUG); - - List loggers = new ArrayList<>(); - if (Verify.containsOne(debugMode, "true", "both", "all", "console")) { - loggers.add(new ConsoleDebugLogger(logger)); - } - if (Verify.containsOne(debugMode, "true", "both", "all", "file")) { - loggers.add(new FolderTimeStampFileDebugLogger(files.getLogsFolder(), () -> errorHandler)); - } - if (Verify.containsOne(debugMode, "true", "both", "all", "memory")) { - loggers.add(debugLogger.getDebugLogger(MemoryDebugLogger.class).orElse(new MemoryDebugLogger())); - } - debugLogger.setDebugLoggers(loggers.toArray(new DebugLogger[0])); - } - - /** - * Copies default values from file in jar to Config. - * - * @throws IOException If file can't be read or written. - */ - protected abstract void copyDefaults() throws IOException; - - @Override - public void disable() { - theme.disable(); - } - - public void reload() { - try { - config.read(); - } catch (IOException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/Permissions.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/Permissions.java deleted file mode 100644 index 02d5e43b3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/Permissions.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings; - -/** - * Permissions class is used easily check every permission node. - * - * @author Rsl1122 - */ -public enum Permissions { - - HELP("plan.?"), - - INSPECT("plan.inspect.base"), - QUICK_INSPECT("plan.qinspect.base"), - INSPECT_OTHER("plan.inspect.other"), - QUICK_INSPECT_OTHER("plan.qinspect.other"), - - ANALYZE("plan.analyze"), - - SEARCH("plan.search"), - - RELOAD("plan.reload"), - INFO("plan.info"), - MANAGE("plan.manage"), - MANAGE_WEB("plan.webmanage"), - - IGNORE_COMMAND_USE("plan.ignore.commanduse"), - IGNORE_AFK("plan.ignore.afk"); - - private final String permission; - - Permissions(String permission) { - this.permission = permission; - } - - /** - * Returns the permission node in plugin.yml. - * - * @return permission node eg. plan.inspect.base - */ - public String getPermission() { - return permission; - } - - /** - * Same as {@link #getPermission()}. - * - * @return permission node eg. plan.inspect.base - */ - public String getPerm() { - return getPermission(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/ProxyConfigSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/ProxyConfigSystem.java deleted file mode 100644 index ef4369e10..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/ProxyConfigSystem.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.settings.changes.ConfigUpdater; -import com.djrapitops.plan.system.settings.config.ConfigReader; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.network.NetworkSettingManager; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; - -/** - * ConfigSystem for Bungee. - *

- * Bukkit and Bungee have different default config file inside the jar. - * - * @author Rsl1122 - */ -@Singleton -public class ProxyConfigSystem extends ConfigSystem { - - private final ConfigUpdater configUpdater; - private final NetworkSettingManager networkSettingManager; - - @Inject - public ProxyConfigSystem( - PlanFiles files, - PlanConfig config, - ConfigUpdater configUpdater, - NetworkSettingManager networkSettingManager, - Theme theme, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(files, config, theme, logger, errorHandler); - this.configUpdater = configUpdater; - this.networkSettingManager = networkSettingManager; - } - - @Override - public void enable() throws EnableException { - super.enable(); - networkSettingManager.enable(); - } - - @Override - public void disable() { - networkSettingManager.disable(); - super.disable(); - } - - @Override - protected void copyDefaults() throws IOException { - configUpdater.applyConfigUpdate(config); - try (ConfigReader reader = new ConfigReader(files.getResourceFromJar("bungeeconfig.yml").asInputStream())) { - config.copyMissing(reader.read()); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/SpongeConfigSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/SpongeConfigSystem.java deleted file mode 100644 index 8ed90a2cc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/SpongeConfigSystem.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.settings.changes.ConfigUpdater; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.network.ServerSettingsManager; -import com.djrapitops.plan.system.settings.paths.DataGatheringSettings; -import com.djrapitops.plan.system.settings.paths.WebserverSettings; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; - -/** - * Sponge ConfigSystem that disables WebServer and Geolocations on first enable. - * - * @author Rsl1122 - */ -@Singleton -public class SpongeConfigSystem extends BukkitConfigSystem { - - private boolean firstInstall; - - @Inject - public SpongeConfigSystem( - PlanFiles files, - PlanConfig config, - ConfigUpdater configUpdater, - ServerSettingsManager serverSettingsManager, - Theme theme, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(files, config, configUpdater, serverSettingsManager, theme, logger, errorHandler); - } - - @Override - public void enable() throws EnableException { - firstInstall = !files.getConfigFile().exists(); - super.enable(); - } - - @Override - protected void copyDefaults() throws IOException { - super.copyDefaults(); - if (firstInstall) { - logger.info("§eWebServer and Geolocations disabled by default on Sponge servers. You can enable them in the config:"); - logger.info("§e " + WebserverSettings.DISABLED.getPath()); - logger.info("§e " + DataGatheringSettings.GEOLOCATIONS.getPath()); - - config.set(WebserverSettings.DISABLED, true); - config.set(DataGatheringSettings.GEOLOCATIONS, false); - config.save(); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/changes/ConfigChange.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/changes/ConfigChange.java deleted file mode 100644 index 32048a335..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/changes/ConfigChange.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.changes; - -import com.djrapitops.plan.system.settings.config.Config; - -/** - * Represents a change made to the config structure. - * - * @author Rsl1122 - */ -public interface ConfigChange { - - boolean hasBeenApplied(Config config); - - void apply(Config config); - - String getAppliedMessage(); - - class Moved extends Removed { - - final String newPath; - - public Moved(String oldPath, String newPath) { - super(oldPath); - this.newPath = newPath; - } - - @Override - public synchronized void apply(Config config) { - if (!config.moveChild(oldPath, newPath)) { - throw new IllegalStateException("Failed to move config node from '" + oldPath + "' to '" + newPath + "'"); - } - } - - @Override - public String getAppliedMessage() { - return "Moved " + oldPath + " to " + newPath; - } - } - - class Copied extends Removed { - - final String newPath; - - public Copied(String oldPath, String newPath) { - super(oldPath); - this.newPath = newPath; - } - - @Override - public synchronized void apply(Config config) { - config.getNode(oldPath).ifPresent(oldNode -> config.addNode(newPath).copyAll(oldNode)); - } - - @Override - public String getAppliedMessage() { - return "Copied value of " + oldPath + " to " + newPath; - } - } - - class Removed implements ConfigChange { - String oldPath; - - public Removed(String oldPath) { - this.oldPath = oldPath; - } - - @Override - public boolean hasBeenApplied(Config config) { - return !config.getNode(oldPath).isPresent(); - } - - @Override - public synchronized void apply(Config config) { - if (!config.removeNode(oldPath)) { - throw new IllegalStateException("Failed to remove config node from '" + oldPath + "'"); - } - } - - @Override - public String getAppliedMessage() { - return "Removed " + oldPath; - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/changes/ConfigUpdater.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/changes/ConfigUpdater.java deleted file mode 100644 index a58a183a4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/changes/ConfigUpdater.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.changes; - -import com.djrapitops.plan.system.settings.config.Config; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.google.common.annotations.VisibleForTesting; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; - -/** - * Class in charge of updating config.yml. - * - * @author Rsl1122 - */ -@Singleton -public class ConfigUpdater { - - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - @Inject - public ConfigUpdater( - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.logger = logger; - this.errorHandler = errorHandler; - } - - public void applyConfigUpdate(Config config) throws IOException { - ConfigChange[] configEnhancementsPatch = configEnhancementPatch(); - applyChanges(config, configEnhancementsPatch); - config.save(); - } - - @VisibleForTesting - ConfigChange[] configEnhancementPatch() { - return new ConfigChange[]{ - new ConfigChange.Moved("Plugin.Locale", "Plugin.Logging.Locale"), - new ConfigChange.Moved("Plugin.WriteNewLocaleFileOnEnable", "Plugin.Logging.Create_new_locale_file_on_next_enable"), - new ConfigChange.Moved("Plugin.Debug", "Plugin.Logging.Debug"), - new ConfigChange.Moved("Plugin.Dev", "Plugin.Logging.Dev"), - new ConfigChange.Moved("Plugin.KeepLogsForXDays", "Plugin.Logging.Delete_logs_after_days"), - - new ConfigChange.Moved("Plugin.Check-for-updates", "Plugin.Update_notifications.Check_for_updates"), - new ConfigChange.Moved("Plugin.Notify-About-DEV-Releases", "Plugin.Update_notifications.Notify_about_DEV_releases"), - new ConfigChange.Removed("Plugin.Allow-Update-Command"), - - new ConfigChange.Moved("Plugin.Bungee-Override.CopyBungeeConfig", "Plugin.Configuration.Allow_bungeecord_to_manage_settings"), - new ConfigChange.Removed("Plugin.Bungee-Override"), - new ConfigChange.Moved("Database.MySQL.LaunchOptions", "Database.MySQL.Launch_options"), - - new ConfigChange.Moved("WebServer.InternalIP", "WebServer.Internal_IP"), - new ConfigChange.Moved("WebServer.Security.SSL-Certificate.KeyStorePath", "WebServer.Security.SSL-Certificate.KeyStore_path"), - new ConfigChange.Moved("WebServer.Security.SSL-Certificate.KeyPass", "WebServer.Security.SSL-Certificate.Key_pass"), - new ConfigChange.Moved("WebServer.Security.SSL-Certificate.StorePass", "WebServer.Security.SSL-Certificate.Store_pass"), - new ConfigChange.Moved("WebServer.Security.SSL-Certificate", "WebServer.Security.SSL_certificate"), - new ConfigChange.Moved("WebServer.DisableWebServer", "WebServer.Disable_Webserver"), - new ConfigChange.Moved("WebServer.ExternalWebServerAddress", "WebServer.External_Webserver_address"), - new ConfigChange.Moved("WebServer", "Webserver"), - new ConfigChange.Moved("Commands.AlternativeIP.Enabled", "Webserver.Alternative_IP"), - new ConfigChange.Moved("Commands.AlternativeIP.Link", "Webserver.Alternative_IP.Address"), - - new ConfigChange.Moved("Data.Geolocations", "Data_gathering.Geolocations"), - new ConfigChange.Moved("Data.Commands.LogUnknownCommands", "Data_gathering.Commands.Log_unknown"), - new ConfigChange.Moved("Data.Commands.CombineCommandAliases", "Data_gathering.Commands.Log_aliases_as_main_command"), - - new ConfigChange.Moved("Customization.UseServerTime", "Time.Use_server_timezone"), - new ConfigChange.Moved("Data.Ping.ServerEnableDelaySeconds", "Time.Delays.Ping_server_enable_delay"), - new ConfigChange.Moved("Data.Ping.PlayerLoginDelaySeconds", "Time.Delays.Ping_player_join_delay"), - new ConfigChange.Moved("Data.AFKThresholdMinutes", "Time.Thresholds.AFK_threshold"), - new ConfigChange.Moved("Analysis.Active.LoginThreshold", "Time.Thresholds.Activity_index.Login_threshold"), - new ConfigChange.Moved("Analysis.Active.PlaytimeThreshold", "Time.Thresholds.Activity_index.Playtime_threshold"), - new ConfigChange.Moved("Data.KeepInactivePlayerDataForDays", "Time.Thresholds.Remove_inactive_player_data_after"), - new ConfigChange.Removed("Analysis.LogProgress"), - new ConfigChange.Moved("Analysis.AutoRefreshPeriod", "Time.Periodic_tasks.Analysis_refresh_every"), - - new ConfigChange.Moved("Theme.Base", "Display_options.Theme"), - new ConfigChange.Moved("Customization.Display.SessionsAsTable", "Display_options.Sessions.Replace_accordion_with_table"), - new ConfigChange.Moved("Customization.Display.LargestWorldPercInSessionTitle", "Display_options.Sessions.Show_most_played_world_in_title"), - new ConfigChange.Moved("Customization.Display.MaxSessions", "Display_options.Sessions.Show_on_page"), - new ConfigChange.Moved("Customization.Display.OrderWorldPieByPercentage", "Display_options.Sessions.Order_world_pies_by_percentage"), - new ConfigChange.Moved("Customization.Display.MaxPlayers", "Display_options.Players_table.Show_on_server_page"), - new ConfigChange.Moved("Customization.Display.MaxPlayersPlayersPage", "Display_options.Players_table.Show_on_players_page"), - new ConfigChange.Removed("Customization.Display.PlayerTableFooter"), - new ConfigChange.Moved("Customization.Display.PlayerIPs", "Display_options.Show_player_IPs"), - new ConfigChange.Moved("Customization.Display.GapsInGraphData", "Display_options.Graphs.Show_gaps_in_data"), - new ConfigChange.Moved("Theme.Graphs.TPS.High-Threshold", "Display_options.Graphs.TPS.High_threshold"), - new ConfigChange.Moved("Theme.Graphs.TPS.Medium-Threshold", "Display_options.Graphs.TPS.Medium_threshold"), - new ConfigChange.Moved("Theme.Graphs.Disk.High-Threshold", "Display_options.Graphs.Disk_space.High_threshold"), - new ConfigChange.Moved("Theme.Graphs.Disk.Medium-Threshold", "Display_options.Graphs.Disk_space.Medium_threshold"), - new ConfigChange.Moved("Commands.Colors", "Display_options.Command_colors"), - - new ConfigChange.Moved("Customization.Formatting.DecimalPoints", "Customization.Formatting.Decimal_points"), - new ConfigChange.Moved("Customization.Formatting.TimeAmount", "Customization.Formatting.Time_amount"), - new ConfigChange.Moved("Customization.Formatting.Dates.RecentDays", "Customization.Formatting.Dates.Show_recent_day_names"), - new ConfigChange.Moved("Customization.Formatting", "Formatting"), - - new ConfigChange.Moved("Customization.WorldAliases", "World_aliases"), - new ConfigChange.Moved("Analysis.Export.DestinationFolder", "Export.HTML_Export_path"), - new ConfigChange.Copied("Analysis.Export.Enabled", "Export.Parts.JavaScript_and_CSS"), - new ConfigChange.Copied("Analysis.Export.Enabled", "Export.Parts.Player_pages"), - new ConfigChange.Copied("Analysis.Export.Enabled", "Export.Parts.Players_page"), - new ConfigChange.Moved("Analysis.Export.Enabled", "Export.Parts.Server_page"), - - new ConfigChange.Removed("Commands"), - new ConfigChange.Removed("Analysis"), - new ConfigChange.Removed("Data"), - new ConfigChange.Removed("Customization"), - new ConfigChange.Removed("Theme") - }; - } - - private void applyChanges(Config config, ConfigChange[] changes) { - for (ConfigChange change : changes) { - try { - if (!change.hasBeenApplied(config)) { - change.apply(config); - logger.info("Config: " + change.getAppliedMessage()); - } - } catch (Exception e) { - errorHandler.log(L.WARN, this.getClass(), new IllegalStateException("Failed to apply config update: '" + change.getAppliedMessage() + "'", e)); - } - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/Config.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/Config.java deleted file mode 100644 index 1213ebb2d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/Config.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 Risto Lahtela - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.djrapitops.plan.system.settings.config; - -import com.djrapitops.plugin.utilities.Verify; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Objects; - -/** - * Configuration utility for storing settings in a .yml file. - *

- * Based on - * https://github.com/Rsl1122/Abstract-Plugin-Framework/blob/72e221d3571ef200727713d10d3684c51e9f469d/AbstractPluginFramework/api/src/main/java/com/djrapitops/plugin/config/Config.java - * - * @author Rsl1122 - */ -public class Config extends ConfigNode { - - private final Path configFilePath; - - public Config(File configFile) { - super("", null, null); - File folder = configFile.getParentFile(); - this.configFilePath = configFile.toPath(); - - try { - Verify.isTrue(folder.exists() || folder.mkdirs(), () -> - new FileNotFoundException("Folders could not be created for config file " + configFile.getAbsolutePath())); - Verify.isTrue(configFile.exists() || configFile.createNewFile(), () -> - new FileNotFoundException("Could not create file: " + configFile.getAbsolutePath())); - read(); - save(); - } catch (IOException e) { - throw new IllegalStateException(e.getMessage(), e); - } - } - - public Config(File configFile, ConfigNode defaults) { - this(configFile); - copyMissing(defaults); - try { - save(); - } catch (IOException e) { - throw new IllegalStateException(e.getMessage(), e); - } - } - - Config() { - super("", null, null); - configFilePath = null; - } - - public void read() throws IOException { - try (ConfigReader reader = new ConfigReader(Files.newInputStream(configFilePath))) { - copyAll(reader.read()); - } - } - - @Override - public void save() throws IOException { - new ConfigWriter(configFilePath).write(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null) return false; - return super.equals(o); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), configFilePath); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigNode.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigNode.java deleted file mode 100644 index 70ca37829..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigNode.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 Risto Lahtela - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.djrapitops.plan.system.settings.config; - -import com.djrapitops.plugin.utilities.Verify; - -import java.io.IOException; -import java.util.*; -import java.util.stream.Collectors; - -/** - * Represents a single node in a configuration file - *

- * Based on - * https://github.com/Rsl1122/Abstract-Plugin-Framework/blob/72e221d3571ef200727713d10d3684c51e9f469d/AbstractPluginFramework/api/src/main/java/com/djrapitops/plugin/config/ConfigNode.java - * - * @author Rsl1122 - */ -public class ConfigNode { - - protected final String key; - protected ConfigNode parent; - - protected List nodeOrder; - protected Map childNodes; - protected List comment; - - protected String value; - - public ConfigNode(String key, ConfigNode parent, String value) { - this.key = key; - this.parent = parent; - this.value = value; - - nodeOrder = new ArrayList<>(); - childNodes = new HashMap<>(); - comment = new ArrayList<>(); - } - - protected void updateParent(ConfigNode newParent) { - parent = newParent; - } - - public Optional getNode(String path) { - if (path == null) { - return Optional.empty(); - } - String[] parts = splitPathInTwo(path); - String key = parts[0]; - String leftover = parts[1]; - - if (leftover.isEmpty()) { - return Optional.ofNullable(childNodes.get(key)); - } else { - return getNode(key).flatMap(child -> child.getNode(leftover)); - } - } - - private String[] splitPathInTwo(String path) { - String[] split = path.split("\\.", 2); - if (split.length <= 1) { - return new String[]{split[0], ""}; - } - return split; - } - - public boolean contains(String path) { - return getNode(path).isPresent(); - } - - public ConfigNode addNode(String path) { - ConfigNode newParent = this; - if (path != null && !path.isEmpty()) { - String[] parts = splitPathInTwo(path); - String key = parts[0]; - String leftover = parts[1]; - - // Add a new child - ConfigNode child; - if (!childNodes.containsKey(key)) { - child = addChild(new ConfigNode(key, newParent, null)); - } else { - child = childNodes.get(key); - } - - // If the path ends return the leaf node - // Otherwise continue recursively. - return leftover.isEmpty() ? child : child.addNode(leftover); - } - throw new IllegalArgumentException("Can not add a node with path '" + path + "'"); - } - - /** - * Remove a node at a certain path. - * - * @param path Path to the node that is up for removal. - * @return {@code true} if the node was present and is now removed. {@code false} if the path did not have a node. - */ - public boolean removeNode(String path) { - Optional node = getNode(path); - node.ifPresent(ConfigNode::remove); - return node.isPresent(); - } - - public void remove() { - if (parent == null) { - throw new IllegalStateException("Can not remove root node from a tree."); - } - parent.childNodes.remove(key); - parent.nodeOrder.remove(key); - updateParent(null); - - // Remove children recursively to avoid memory leaks - nodeOrder.stream() - .sorted() // will use internal state and prevent Concurrent modification of underlying list - .map(childNodes::get) - .filter(Objects::nonNull) - .forEach(ConfigNode::remove); - } - - /** - * Add a new child ConfigNode. - * - * @param child ConfigNode to add. - * If from another config tree, the parent is 'cut', which breaks the old tree traversal. - * @return Return the node given, now part of this tree. - */ - protected ConfigNode addChild(ConfigNode child) { - getNode(child.key).ifPresent(ConfigNode::remove); - childNodes.put(child.key, child); - nodeOrder.add(child.key); - child.updateParent(this); - return child; - } - - protected void removeChild(ConfigNode child) { - removeNode(child.key); - } - - /** - * Moves a node from old path to new path. - * - * @param oldPath Old path of the node. - * @param newPath New path of the node. - * @return {@code true} if the move was successful. {@code false} if the new node is not present - */ - public boolean moveChild(String oldPath, String newPath) { - Optional found = getNode(oldPath); - if (!found.isPresent()) { - return false; - } - - ConfigNode moveFrom = found.get(); - ConfigNode moveTo = addNode(newPath); - - moveTo.copyAll(moveFrom); - removeNode(oldPath); - - return getNode(newPath).isPresent(); - } - - public String getKey(boolean deep) { - if (deep) { - String deepKey = parent != null ? parent.getKey(true) + "." + key : ""; - if (deepKey.startsWith(".")) { - return deepKey.substring(1); - } - return deepKey; - } - return key; - } - - public void sort() { - Collections.sort(nodeOrder); - } - - public void reorder(List newOrder) { - List oldOrder = nodeOrder; - nodeOrder = new ArrayList<>(); - for (String key : newOrder) { - if (childNodes.containsKey(key)) { - nodeOrder.add(key); - } - } - // Add those that were not in the new order, but are in the old order. - oldOrder.removeAll(nodeOrder); - nodeOrder.addAll(oldOrder); - } - - /** - * Find the root node and save. - * - * @throws IOException If the save can not be performed. - */ - public void save() throws IOException { - ConfigNode root = this.parent; - while (root.parent != null) { - root = root.parent; - } - root.save(); - } - - public void set(String path, T value) { - addNode(path).set(value); - } - - public void set(T value) { - if (value instanceof ConfigNode) { - copyAll((ConfigNode) value); - } else { - ConfigValueParser parser = ConfigValueParser.getParserFor(value.getClass()); - this.value = parser.decompose(value); - } - } - - public List getComment() { - return comment; - } - - public void setComment(List comment) { - this.comment = comment; - } - - public List getStringList() { - return value == null ? Collections.emptyList() - : new ConfigValueParser.StringListParser().compose(value); - } - - public Integer getInteger() { - return value == null ? null - : new ConfigValueParser.IntegerParser().compose(value); - } - - public Long getLong() { - return value == null ? null - : new ConfigValueParser.LongParser().compose(value); - } - - public String getString() { - return value == null ? null - : new ConfigValueParser.StringParser().compose(value); - } - - public boolean getBoolean() { - return new ConfigValueParser.BooleanParser().compose(value); - } - - public List getStringList(String path) { - return getNode(path).map(ConfigNode::getStringList).orElse(Collections.emptyList()); - } - - /** - * Return values in a Map. - * - * @param fullKeys Should the key be full keys of the Config node. - * @return Map with Config key - ConfigNode#getString. - */ - public Map getStringMap(boolean fullKeys) { - return childNodes.values().stream() - .collect(Collectors.toMap(node -> node.getKey(fullKeys), ConfigNode::getString)); - } - - public Integer getInteger(String path) { - return getNode(path).map(ConfigNode::getInteger).orElse(null); - } - - public Long getLong(String path) { - return getNode(path).map(ConfigNode::getLong).orElse(null); - } - - public String getString(String path) { - return getNode(path).map(ConfigNode::getString).orElse(null); - } - - public boolean getBoolean(String path) { - return getNode(path).map(ConfigNode::getBoolean).orElse(false); - } - - public void copyMissing(ConfigNode from) { - // Override comment conditionally - if (comment.size() < from.comment.size()) { - comment = from.comment; - } - - // Override value conditionally - if (Verify.isEmpty(value) && from.value != null) { - value = from.value; - } - - // Copy all nodes from 'from' - for (String key : from.nodeOrder) { - ConfigNode newChild = from.childNodes.get(key); - - // Copy values recursively to children - ConfigNode created = addNode(key); - created.copyMissing(newChild); - } - } - - public void copyAll(ConfigNode from) { - // Override comment and value unconditionally. - comment = from.comment; - value = from.value; - - // Copy all nodes from 'from' - for (String key : from.nodeOrder) { - ConfigNode newChild = from.childNodes.get(key); - - // Copy values recursively to children - ConfigNode created = addNode(key); - created.copyAll(newChild); - } - } - - protected int getNodeDepth() { - return parent != null ? parent.getNodeDepth() + 1 : -1; // Root node is -1 - } - - public ConfigNode getParent() { - return parent; - } - - public boolean isLeafNode() { - return nodeOrder.isEmpty(); - } - - protected List getNodeOrder() { - return nodeOrder; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ConfigNode)) return false; - ConfigNode that = (ConfigNode) o; - return Objects.equals(key, that.key) && - nodeOrder.equals(that.nodeOrder) && - childNodes.equals(that.childNodes) && - comment.equals(that.comment) && - Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(key, childNodes, comment, value); - } - - @Override - public String toString() { - return "{'" + value + "' " + (!childNodes.isEmpty() ? childNodes : "") + '}'; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigReader.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigReader.java deleted file mode 100644 index f10b8d707..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigReader.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.config; - -import com.djrapitops.plugin.utilities.Verify; - -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; - -/** - * Reader for parsing {@link Config} out of file-lines. - *

- * ConfigReader can read a single file at a time, so it is NOT thread safe. - * - * @author Rsl1122 - */ -public class ConfigReader implements Closeable { - - private boolean closed; - - private final Scanner scanner; - private ConfigNode previousNode; - private ConfigNode parent; - - // Indent mode assumes the number of spaces used to indent the file. - // If the first found indent is smaller, that will be used instead. - private int indentMode = 4; - private List unboundComment = new ArrayList<>(); - - private int lastDepth = -1; - - /** - * Create a new ConfigReader for a Path. - * - * @param filePath Path to a config file. - * @throws IOException If the path can not be read. - */ - public ConfigReader(Path filePath) throws IOException { - this(Files.newInputStream(filePath)); - } - - /** - * Create a new ConfigReader for an InputStream. - * - * @param in InputStream of a resource that is a config. - */ - public ConfigReader(InputStream in) { - this(new Scanner(new InputStreamReader(in, StandardCharsets.UTF_8))); - } - - /** - * Create a new ConfigReader for a BufferedReader. - * - * @param bufferedReader BufferedReader of a resource that is a config. - */ - public ConfigReader(BufferedReader bufferedReader) { - this(new Scanner(bufferedReader)); - } - - /** - * Create a new ConfigReader for a Scanner. - * - * @param scanner Scanner of a resource that is a config. - */ - public ConfigReader(Scanner scanner) { - this.scanner = scanner; - closed = false; - } - - /** - * Read the resource into a {@link Config}. - * - * @return Config parsed from the lines found in the given resource. - * @throws IllegalStateException If the configReader is closed by calling {@link ConfigReader#close()} - */ - public Config read() { - Verify.isFalse(closed, () -> new IllegalStateException("ConfigReader has been closed.")); - - Config config = new Config(); - - previousNode = config; - parent = config; - - while (scanner.hasNextLine()) { - String line = readNewLine(); - String trimmed = line.trim(); - handleLine(line, trimmed); - } - - return config; - } - - private void handleLine(String line, String trimmed) { - if (trimmed.isEmpty() || trimmed.startsWith(":")) { - // Add an empty row comment in case user wants spacers - handleCommentLine(" "); - } else if (trimmed.startsWith("#")) { - handleCommentLine(trimmed); - } else { - // Determine where the node belongs - - int currentDepth = findCurrentDepth(line); - parent = findParent(lastDepth, currentDepth); - Verify.nullCheck(parent, () -> new IllegalStateException("Could not determine parent on line: \"" + line + "\"")); - - // Get the node the line belongs to - previousNode = parseNode(trimmed); - Verify.nullCheck(previousNode, () -> new IllegalStateException("Could not parse node on line: \"" + line + "\"")); - - lastDepth = currentDepth; - handleUnboundComments(); - } - } - - private String readNewLine() { - String line = scanner.nextLine(); - - // Removing any dangling comments - int danglingComment = line.trim().indexOf(" #"); - if (danglingComment != -1) { - line = line.substring(0, danglingComment); - } - return line; - } - - private ConfigNode parseNode(String line) { - // Parse a node "Key: value" - String[] keyAndValue = line.split(":", 2); - if (keyAndValue.length <= 1) { - return handleMultiline(line); - } - String key = keyAndValue[0].trim(); - String value = keyAndValue[1].trim(); - return handleNewNode(key, !value.isEmpty() ? value : null); - } - - private ConfigNode handleMultiline(String line) { - if (line.startsWith("- ")) { - return handleListCase(line); - } else { - return handleMultilineString(line); - } - } - - private void handleCommentLine(String line) { - unboundComment.add(line.substring(1).trim()); - } - - private void handleUnboundComments() { - if (!unboundComment.isEmpty()) { - previousNode.setComment(new ArrayList<>(unboundComment)); - unboundComment.clear(); - } - } - - private ConfigNode handleMultilineString(String line) { - // Ensure we are not appending to null value - if (previousNode.value == null) { - previousNode.value = ""; - } - // Append the new line to the end of the value. - previousNode.value += line.trim(); - return previousNode; - } - - private ConfigNode handleNewNode(String key, String value) { - ConfigNode newNode = new ConfigNode(key, parent, value); - return parent.addChild(newNode); - } - - private ConfigNode handleListCase(String line) { - // Ensure we are not appending to null value - if (previousNode.value == null) { - previousNode.value = ""; - } - // Append list item to the value. - previousNode.value += "\n- " + line.substring(2).trim(); - return previousNode; - } - - private ConfigNode findParent(int previousDepth, int currentDepth) { - if (previousDepth < currentDepth) { - return previousNode; - } else if (previousDepth > currentDepth) { - // Prevents incorrect indent in the case: - // 1: - // 2: - // 3: - // 1: - int helperDepth = previousDepth; - ConfigNode foundParent = previousNode; - while (helperDepth > currentDepth) { - helperDepth = foundParent.getNodeDepth(); - foundParent = foundParent.parent; // Moves one level up the tree - } - return foundParent; - } else { - return parent; - } - } - - private int findCurrentDepth(String line) { - int indent = readIndent(line); - - // Re-define indent mode if indent is 2 for configs indented with 2 spaces. - if (indent == 2 && indentMode == 4) { - indentMode = indent; - } - - int depth; - if (indent % indentMode == 0) { - depth = indent / indentMode; - } else { - depth = ((indent - (indent % indentMode)) / indentMode) + 1; // Round up - } - return depth; - } - - private int readIndent(String line) { - int indentation = 0; - for (char c : line.toCharArray()) { - if (c == ' ') { - indentation++; - } else { - break; - } - } - return indentation; - } - - @Override - public void close() { - scanner.close(); - closed = true; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigValueParser.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigValueParser.java deleted file mode 100644 index ead1610bb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigValueParser.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.config; - -import com.djrapitops.plugin.utilities.Verify; -import org.apache.commons.lang3.math.NumberUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * Utilities for parsing config values. - * - * @param Type of the object being parsed. - * @author Rsl1122 - */ -public interface ConfigValueParser { - - static ConfigValueParser getParserFor(Class type) { - if (String.class.isAssignableFrom(type)) { - return new StringParser(); - } else if (List.class.isAssignableFrom(type)) { - return new StringListParser(); - } else if (Boolean.class.isAssignableFrom(type)) { - return new BooleanParser(); - } else if (Long.class.isAssignableFrom(type)) { - return new LongParser(); - } else if (Integer.class.isAssignableFrom(type)) { - return new IntegerParser(); - } - return toStringParser(); - } - - static ConfigValueParser toStringParser() { - return new ConfigValueParser() { - @Override - public Object compose(String fromValue) { - return fromValue; - } - - @Override - public String decompose(Object ofValue) { - return ofValue.toString(); - } - }; - } - - /** - * Parse a String value in the config into the appropriate object. - * - * @param fromValue String value in the config. - * @return Config value or null if it could not be parsed. - */ - T compose(String fromValue); - - /** - * Parse an object into a String value to save in the config. - * - * @param ofValue Value to save, not null. - * @return String format to save in the config. - * @throws IllegalArgumentException If null value is given. - */ - String decompose(T ofValue); - - static IllegalArgumentException nullInvalidException() { - return new IllegalArgumentException("Null value is not valid for saving"); - } - - class StringParser implements ConfigValueParser { - @Override - public String compose(String fromValue) { - boolean surroundedWithSingleQuotes = fromValue.startsWith("'") && fromValue.endsWith("'"); - boolean surroundedWithDoubleQuotes = fromValue.startsWith("\"") && fromValue.endsWith("\""); - if (surroundedWithSingleQuotes || surroundedWithDoubleQuotes) { - return fromValue.substring(1, fromValue.length() - 1); - } - return fromValue; - } - - @Override - public String decompose(String value) { - Verify.nullCheck(value, ConfigValueParser::nullInvalidException); - - boolean surroundedByQuotes = value.startsWith("'") || value.endsWith("'"); - boolean surroundedByDoubleQuotes = value.startsWith("\"") || value.endsWith("\""); - boolean containsSpace = value.isEmpty() || value.contains(" "); - boolean startsWithSpecialSymbol = value.startsWith("-") || value.startsWith("#") || value.startsWith("&"); - - if (surroundedByDoubleQuotes || containsSpace || startsWithSpecialSymbol) { - return "'" + value + "'"; - } else if (surroundedByQuotes) { - return "\"" + value + "\""; - } - return value; - } - } - - class IntegerParser implements ConfigValueParser { - @Override - public Integer compose(String fromValue) { - if (NumberUtils.isParsable(fromValue)) { - return NumberUtils.createInteger(fromValue); - } - return null; - } - - @Override - public String decompose(Integer ofValue) { - Verify.nullCheck(ofValue, ConfigValueParser::nullInvalidException); - return Integer.toString(ofValue); - } - } - - class LongParser implements ConfigValueParser { - @Override - public Long compose(String fromValue) { - try { - return Long.parseLong(fromValue); - } catch (NumberFormatException e) { - return null; - } - } - - @Override - public String decompose(Long ofValue) { - Verify.nullCheck(ofValue, ConfigValueParser::nullInvalidException); - return Long.toString(ofValue); - } - } - - class BooleanParser implements ConfigValueParser { - @Override - public Boolean compose(String fromValue) { - return Boolean.valueOf(fromValue); - } - - @Override - public String decompose(Boolean ofValue) { - Verify.nullCheck(ofValue, ConfigValueParser::nullInvalidException); - return Boolean.toString(ofValue); - } - } - - class StringListParser implements ConfigValueParser> { - private static final StringParser STRING_PARSER = new StringParser(); - - @Override - public List compose(String fromValue) { - List values = new ArrayList<>(); - for (String line : fromValue.split("\\n")) { - if (line.trim().isEmpty()) { - continue; - } - // Removes '- ' in front of the value. - line = line.substring(2).trim(); - // Handle quotes around the string - line = STRING_PARSER.compose(line); - if (!line.isEmpty()) { - values.add(line); - } - } - return values; - } - - @Override - public String decompose(List ofValue) { - Verify.nullCheck(ofValue, ConfigValueParser::nullInvalidException); - - StringBuilder decomposedString = new StringBuilder(); - for (String value : ofValue) { - decomposedString.append("\n- ").append(STRING_PARSER.decompose(value)); - } - return decomposedString.toString(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigWriter.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigWriter.java deleted file mode 100644 index 1b6ceb0b8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/ConfigWriter.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.config; - -import com.djrapitops.plugin.utilities.Verify; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * Writer for parsing {@link Config} into file-lines. - *

- * ConfigReader can write a single file at a time, so it is NOT thread safe. - * - * @author Rsl1122 - */ -public class ConfigWriter { - - private Path outputPath; - private int indent; - - /** - * Create a new ConfigWriter that doesn't write anywhere. - */ - public ConfigWriter() { - } - - /** - * Create a new ConfigWriter that writes to a Path. - * - * @param outputPath Path to write to. - */ - public ConfigWriter(Path outputPath) { - this.outputPath = outputPath; - } - - /** - * Write a {@link ConfigNode} into the given resource. - * - * @param writing ConfigNode to write. - * @throws IOException If the Path given to constructor can not be written to. - * @throws IllegalStateException If the Path is null - */ - public void write(ConfigNode writing) throws IOException { - Verify.nullCheck(outputPath, () -> new IllegalStateException("Output path was null.")); - - ConfigNode storedParent = writing.parent; - writing.updateParent(null); - - Files.write(outputPath, parseLines(writing), StandardCharsets.UTF_8); - - writing.updateParent(storedParent); - } - - /** - * Parse the lines of a {@link ConfigNode}. - *

- * "Write" the lines into a List. - * - * @param writing ConfigNode to "write" - * @return List of lines that would be written. - */ - public List parseLines(ConfigNode writing) { - List lines = new ArrayList<>(); - - dfsTreeTraverseLineResolve(writing, lines); - - return lines; - } - - private void dfsTreeTraverseLineResolve(ConfigNode writing, Collection lines) { - Map children = writing.childNodes; - for (String key : writing.getNodeOrder()) { - ConfigNode node = children.get(key); - if (node.value == null && node.nodeOrder.isEmpty()) { - continue; - } - - indent = node.getNodeDepth() * 4; - addComment(node.comment, lines); - addValue(node, lines); - - dfsTreeTraverseLineResolve(node, lines); - } - } - - private void addValue(ConfigNode node, Collection lines) { - String key = node.key; - String value = node.value; - - if (value == null || value.isEmpty()) { - addKey(key, lines); - } else if (value.contains("\n")) { - // List values include newline characters, - // see ConfigValueParser.StringListParser - addListValue(key, value.split("\\n"), lines); - } else { - addNormalValue(key, value, lines); - } - } - - private void addKey(String key, Collection lines) { - // Key: - lines.add(indentedBuilder().append(key).append(":").toString()); - } - - private void addNormalValue(String key, String value, Collection lines) { - // Key: value - StringBuilder lineBuilder = indentedBuilder().append(key).append(": ").append(value); - lines.add(lineBuilder.toString()); - } - - private void addListValue(String key, String[] listItems, Collection lines) { - // Key: - // - List item - addKey(key, lines); - for (String listItem : listItems) { - listItem = listItem.trim(); - if (listItem.isEmpty()) { - continue; - } - addListItem(listItem, lines); - } - } - - private void addListItem(String listItem, Collection lines) { - StringBuilder lineBuilder = indentedBuilder() - .append(" ") // Append 2 spaces to adhere to yml format for lists - .append(listItem); - lines.add(lineBuilder.toString()); - } - - private void addComment(Iterable comments, Collection lines) { - // # Comment line - for (String comment : comments) { - StringBuilder lineBuilder = indentedBuilder().append("# ").append(comment); - lines.add(lineBuilder.toString()); - } - } - - private StringBuilder indentedBuilder() { - StringBuilder lineBuilder = new StringBuilder(); - indent(indent, lineBuilder); - return lineBuilder; - } - - private void indent(int indent, StringBuilder lineBuilder) { - for (int i = 0; i < indent; i++) { - lineBuilder.append(' '); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/PlanConfig.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/PlanConfig.java deleted file mode 100644 index 7e8879f2a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/PlanConfig.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.config; - -import com.djrapitops.plan.data.plugin.PluginsConfigSection; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; -import java.io.File; -import java.util.List; -import java.util.Objects; -import java.util.TimeZone; -import java.util.concurrent.TimeUnit; - -/** - * Plan configuration file. - * - * @author Rsl1122 - */ -@Singleton -public class PlanConfig extends Config { - - private final PluginsConfigSection pluginsConfigSection; - private final WorldAliasSettings worldAliasSettings; - private final PluginLogger logger; - - @Inject - public PlanConfig( - @Named("configFile") File file, - WorldAliasSettings worldAliasSettings, - PluginLogger logger - ) { - super(file); - - this.worldAliasSettings = worldAliasSettings; - this.logger = logger; - - pluginsConfigSection = new PluginsConfigSection(this); - } - - public int getTimeZoneOffsetHours() { - if (isTrue(TimeSettings.USE_SERVER_TIME)) { - int offset = TimeZone.getDefault().getOffset(System.currentTimeMillis()); - int hourMs = (int) TimeUnit.HOURS.toMillis(1L); - return -offset / hourMs; - } - return 0; // UTC - } - - public T get(Setting setting) { - T value = setting.getValueFrom(this); - Verify.isTrue(setting.isValid(value), () -> new IllegalStateException( - "Config value for " + setting.getPath() + " has a bad value: '" + value + "'" - )); - return value; - } - - public T getOrDefault(Setting setting, T defaultValue) { - try { - return get(setting); - } catch (IllegalStateException e) { - logger.warn(e.getMessage() + ", using '" + defaultValue + "'"); - return defaultValue; - } - } - - public boolean isTrue(Setting setting) { - return get(setting); - } - - public boolean isFalse(Setting setting) { - return !isTrue(setting); - } - - /** - * If the settings is a String, this method should be used. - * - * @return String value of the config setting. - */ - public String getString(Setting setting) { - return get(setting); - } - - /** - * If the settings is a number, this method should be used. - * - * @return Integer value of the config setting - */ - public int getNumber(Setting setting) { - return get(setting); - } - - public List getStringList(Setting> setting) { - return get(setting); - } - - public ConfigNode getConfigNode(Setting setting) { - return get(setting); - } - - public void set(Setting setting, T value) { - set(setting.getPath(), value); - } - - public PluginsConfigSection getPluginsConfigSection() { - return pluginsConfigSection; - } - - public WorldAliasSettings getWorldAliasSettings() { - return worldAliasSettings; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null) return false; - return super.equals(o); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode()); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/WorldAliasSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/WorldAliasSettings.java deleted file mode 100644 index 8c9678c3e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/WorldAliasSettings.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.config; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.time.GMTimes; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.paths.DisplaySettings; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.formatting.Formatters; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -/** - * Class responsible for managing config settings for World Aliases. - * - * @author Rsl1122 - */ -@Singleton -public class WorldAliasSettings { - - private final Lazy config; - private final Supplier> percentageFormatter; - private final Processing processing; - private final ErrorHandler errorHandler; - - @Inject - public WorldAliasSettings( - Lazy config, - Lazy formatters, - Processing processing, - ErrorHandler errorHandler - ) { - this.config = config; - this.processing = processing; - this.errorHandler = errorHandler; - - percentageFormatter = () -> formatters.get().percentage(); - } - - private ConfigNode getAliasSection() { - return config.get().get(DisplaySettings.WORLD_ALIASES); - } - - /** - * Adds a new World to the config section. - *

- * If exists does not override old value. - * - * @param world World name - */ - public void addWorld(String world) { - Verify.isFalse(Verify.isEmpty(world), () -> new IllegalArgumentException("Attempted to save empty world alias")); - - ConfigNode aliasSect = getAliasSection(); - - String previousValue = aliasSect.getString(world); - if (Verify.isEmpty(previousValue)) { - aliasSect.set(world, world); - processing.submitNonCritical(() -> { - try { - aliasSect.save(); - } catch (IOException e) { - errorHandler.log(L.WARN, WorldAliasSettings.class, e); - } - }); - } - } - - public Map getPlaytimePerAlias(WorldTimes worldTimes) { - if (worldTimes.getWorldTimes().isEmpty()) { - return new HashMap<>(); - } - - Map playtimePerWorld = worldTimes.getWorldTimes() // WorldTimes Map - .entrySet().stream() - .collect(Collectors.toMap( - Map.Entry::getKey, - entry -> entry.getValue().getTotal() // GMTimes.getTotal - )); - - ConfigNode aliases = getAliasSection(); - - Map playtimePerAlias = new HashMap<>(); - for (Map.Entry entry : playtimePerWorld.entrySet()) { - String worldName = entry.getKey(); - long playtime = entry.getValue(); - - if (!aliases.contains(worldName)) { - addWorld(worldName); - } - - String alias = aliases.getString(worldName); - - playtimePerAlias.put(alias, playtimePerAlias.getOrDefault(alias, 0L) + playtime); - } - return playtimePerAlias; - } - - public Map getGMTimesPerAlias(WorldTimes worldTimes) { - ConfigNode aliases = getAliasSection(); - - Map gmTimesPerAlias = new HashMap<>(); - - String[] gms = GMTimes.getGMKeyArray(); - - for (Map.Entry entry : worldTimes.getWorldTimes().entrySet()) { - String worldName = entry.getKey(); - GMTimes gmTimes = entry.getValue(); - - if (!aliases.contains(worldName)) { - addWorld(worldName); - } - - String alias = aliases.getString(worldName); - - GMTimes aliasGMTimes = gmTimesPerAlias.getOrDefault(alias, new GMTimes()); - for (String gm : gms) { - aliasGMTimes.addTime(gm, gmTimes.getTime(gm)); - } - gmTimesPerAlias.put(alias, aliasGMTimes); - } - return gmTimesPerAlias; - } - - public String getLongestWorldPlayed(Session session) { - ConfigNode aliases = getAliasSection(); - - if (!session.supports(SessionKeys.WORLD_TIMES)) { - return "No World Time Data"; - } - WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()); - if (!session.supports(SessionKeys.END)) { - return worldTimes.getCurrentWorld() - .map(currentWorld -> "Current: " + (aliases.contains(currentWorld) ? aliases.getString(currentWorld) : currentWorld)) - .orElse("Current: Unavailable"); - } - - Map playtimePerAlias = getPlaytimePerAlias(worldTimes); - long total = worldTimes.getTotal(); - // Prevent arithmetic error if 0 - if (total <= 0) { - total = -1; - } - - long longest = 0; - String theWorld = "-"; - for (Map.Entry entry : playtimePerAlias.entrySet()) { - String world = entry.getKey(); - long time = entry.getValue(); - if (time > longest) { - longest = time; - theWorld = world; - } - } - - double quotient = longest * 1.0 / total; - - return theWorld + " (" + percentageFormatter.get().apply(quotient) + ")"; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettingManager.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettingManager.java deleted file mode 100644 index 84b5a5c9e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettingManager.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.network; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.NewerConfigQuery; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.db.access.transactions.StoreConfigTransaction; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.*; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.utilities.file.FileWatcher; -import com.djrapitops.plan.utilities.file.WatchedFile; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -/** - * In charge of updating network-server configs. - *

- * Performs the following tasks related to network configs: - * - File modification watching related to server configs - * - Database update operations related to server configs - * - File update operations from database related to server configs - * - * @author Rsl1122 - */ -@Singleton -public class NetworkSettingManager implements SubSystem { - - private final PlanFiles files; - private final DBSystem dbSystem; - private final ServerInfo serverInfo; - private final RunnableFactory runnableFactory; - private PlanConfig config; - private final PluginLogger logger; - private ErrorHandler errorHandler; - - private File serverSettingsFolder; - - private FileWatcher watcher; - - @Inject - public NetworkSettingManager( - PlanFiles files, - PlanConfig config, - DBSystem dbSystem, - ServerInfo serverInfo, - RunnableFactory runnableFactory, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.files = files; - this.config = config; - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.runnableFactory = runnableFactory; - this.logger = logger; - - this.errorHandler = errorHandler; - } - - @Override - public void enable() throws EnableException { - serverSettingsFolder = createServerSettingsFolder(); - - watcher = prepareFileWatcher(); - watcher.start(); - logger.debug("Server Settings folder FileWatcher started."); - - scheduleDBCheckTask(); - } - - @Override - public void disable() { - if (watcher != null) { - watcher.interrupt(); - } - } - - public static UUID getServerUUIDFromFilename(File file) { - String fileName = file.getName(); - String uuidString = fileName.substring(0, fileName.length() - 4); - return UUID.fromString(uuidString); - } - - private FileWatcher prepareFileWatcher() { - FileWatcher fileWatcher = new FileWatcher(serverSettingsFolder, errorHandler); - - File[] files = getConfigFiles(); - if (files != null) { - for (File file : files) { - addFileToWatchList(fileWatcher, file); - } - } - - return fileWatcher; - } - - public File[] getConfigFiles() { - return serverSettingsFolder.listFiles((dir, name) -> name.endsWith(".yml")); - } - - private void addFileToWatchList(FileWatcher fileWatcher, File file) { - try { - UUID serverUUID = getServerUUIDFromFilename(file); - - fileWatcher.addToWatchlist(new WatchedFile(file, () -> updateConfigInDB(file, serverUUID))); - } catch (IndexOutOfBoundsException | IllegalArgumentException ignore) { - /* Invalid file-name, ignored */ - } - } - - private void scheduleDBCheckTask() { - long checkPeriod = TimeAmount.toTicks(config.get(TimeSettings.CONFIG_UPDATE_INTERVAL), TimeUnit.MILLISECONDS); - runnableFactory.create("Config Update DB Checker", new AbsRunnable() { - @Override - public void run() { - updateConfigFromDBIfUpdated(); - } - }).runTaskTimerAsynchronously(checkPeriod, checkPeriod); - } - - private File createServerSettingsFolder() throws EnableException { - try { - File serverConfigFolder = files.getFileFromPluginFolder("serverConfiguration"); - Files.createDirectories(serverConfigFolder.toPath()); - return serverConfigFolder; - } catch (IOException e) { - throw new EnableException("Could not initialize NetworkSettingManager: " + e.getMessage(), e); - } - } - - private File getServerConfigFile(UUID serverUUID) { - return new File(serverSettingsFolder, serverUUID + ".yml"); - } - - private void updateConfigFromDBIfUpdated() { - Database database = dbSystem.getDatabase(); - Set serverUUIDs = database.query(ServerQueries.fetchPlanServerInformation()).keySet(); - // Remove the proxy server from the list - serverUUIDs.remove(serverInfo.getServerUUID()); - - for (UUID serverUUID : serverUUIDs) { - updateConfigFromDBIfUpdated(database, serverUUID); - } - } - - private void updateConfigFromDBIfUpdated(Database database, UUID serverUUID) { - File configFile = getServerConfigFile(serverUUID); - long lastModified = configFile.exists() ? configFile.lastModified() : -1; - - Optional foundConfig = database.query(new NewerConfigQuery(serverUUID, lastModified)); - if (foundConfig.isPresent()) { - try { - Config writing = foundConfig.get(); - String serverName = writing.getNode(PluginSettings.SERVER_NAME.getPath()).map(ConfigNode::getString).orElse("Unknown"); - - new ConfigWriter(configFile.toPath()).write(writing); - logger.info("Config file for server '" + serverName + "' updated in /Plan/serverConfiguration"); - addFileToWatchList(watcher, configFile); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - } - - public void updateConfigInDB(File file, UUID serverUUID) { - if (!file.exists()) { - return; - } - - Database database = dbSystem.getDatabase(); - - try (ConfigReader reader = new ConfigReader(file.toPath())) { - Config config = reader.read(); - database.executeTransaction(new StoreConfigTransaction(serverUUID, config, file.lastModified())); - String serverName = config.getNode(PluginSettings.SERVER_NAME.getPath()).map(ConfigNode::getString).orElse("Unknown"); - logger.debug("Server config '" + serverName + "' in db now up to date."); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/network/ServerSettingsManager.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/network/ServerSettingsManager.java deleted file mode 100644 index c509a2bd3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/network/ServerSettingsManager.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.network; - -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.NewerConfigQuery; -import com.djrapitops.plan.db.access.transactions.StoreConfigTransaction; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.Config; -import com.djrapitops.plan.system.settings.config.ConfigReader; -import com.djrapitops.plan.system.settings.config.ConfigWriter; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.system.tasks.TaskSystem; -import com.djrapitops.plan.utilities.file.FileWatcher; -import com.djrapitops.plan.utilities.file.WatchedFile; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.AbsRunnable; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -/** - * In charge of updating server-network config. - *

- * Performs following tasks related to the config: - * - File modification watching related to config.yml - * - Database updating related to config.yml - * - File update operations from database related to config.yml - * - * @author Rsl1122 - */ -@Singleton -public class ServerSettingsManager implements SubSystem { - - private final PlanFiles files; - private final PlanConfig config; - private final DBSystem dbSystem; - private ServerInfo serverInfo; - private final TaskSystem taskSystem; - private final ErrorHandler errorHandler; - private PluginLogger logger; - private FileWatcher watcher; - - @Inject - public ServerSettingsManager( - PlanFiles files, - PlanConfig config, - DBSystem dbSystem, - ServerInfo serverInfo, - TaskSystem taskSystem, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.files = files; - this.config = config; - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.taskSystem = taskSystem; - this.logger = logger; - this.errorHandler = errorHandler; - } - - @Override - public void enable() { - watcher = prepareFileWatcher(); - watcher.start(); - logger.debug("Server Settings folder FileWatcher started."); - scheduleDBCheckTask(); - } - - private FileWatcher prepareFileWatcher() { - FileWatcher fileWatcher = new FileWatcher(files.getDataFolder(), errorHandler); - File configFile = files.getConfigFile(); - fileWatcher.addToWatchlist(new WatchedFile(configFile, - () -> updateConfigInDB(configFile) - )); - return fileWatcher; - } - - private void updateConfigInDB(File file) { - if (!file.exists()) { - return; - } - - Database database = dbSystem.getDatabase(); - - try (ConfigReader reader = new ConfigReader(file.toPath())) { - Config config = reader.read(); - database.executeTransaction(new StoreConfigTransaction(serverInfo.getServerUUID(), config, file.lastModified())); - logger.debug("Server config saved to database."); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private void scheduleDBCheckTask() { - long checkPeriod = TimeAmount.toTicks(config.get(TimeSettings.CONFIG_UPDATE_INTERVAL), TimeUnit.MILLISECONDS); - taskSystem.registerTask("Config Update DB Checker", new AbsRunnable() { - @Override - public void run() { - checkDBForNewConfigSettings(dbSystem.getDatabase()); - } - }).runTaskTimerAsynchronously(checkPeriod, checkPeriod); - } - - private void checkDBForNewConfigSettings(Database database) { - File configFile = files.getConfigFile(); - long lastModified = configFile.exists() ? configFile.lastModified() : -1; - - Optional foundConfig = database.query(new NewerConfigQuery(serverInfo.getServerUUID(), lastModified)); - if (foundConfig.isPresent()) { - try { - new ConfigWriter(configFile.toPath()).write(foundConfig.get()); - logger.info("The Config was updated to match one on the Proxy. Reload for changes to take effect."); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - } - - @Override - public void disable() { - if (watcher != null) { - watcher.interrupt(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DataGatheringSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DataGatheringSettings.java deleted file mode 100644 index e5f851c61..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DataGatheringSettings.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.system.settings.paths.key.BooleanSetting; -import com.djrapitops.plan.system.settings.paths.key.Setting; - -/** - * {@link Setting} values that are in "Data_gathering" section. - * - * @author Rsl1122 - */ -public class DataGatheringSettings { - - public static final Setting GEOLOCATIONS = new BooleanSetting("Data_gathering.Geolocations"); - public static final Setting PING = new BooleanSetting("Data_gathering.Ping"); - public static final Setting LOG_UNKNOWN_COMMANDS = new BooleanSetting("Data_gathering.Commands.Log_unknown"); - public static final Setting COMBINE_COMMAND_ALIASES = new BooleanSetting("Data_gathering.Commands.Log_aliases_as_main_command"); - - private DataGatheringSettings() { - /* static variable class */ - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DatabaseSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DatabaseSettings.java deleted file mode 100644 index 1aa35782a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DatabaseSettings.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.db.DBType; -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plan.system.settings.paths.key.StringSetting; -import org.apache.commons.lang3.math.NumberUtils; - -/** - * {@link Setting} values that are in "Database" section. - * - * @author Rsl1122 - */ -public class DatabaseSettings { - - public static final Setting TYPE = new StringSetting("Database.Type", DBType::exists); - public static final Setting MYSQL_HOST = new StringSetting("Database.MySQL.Host"); - public static final Setting MYSQL_PORT = new StringSetting("Database.MySQL.Port", NumberUtils::isParsable); - public static final Setting MYSQL_USER = new StringSetting("Database.MySQL.User"); - public static final Setting MYSQL_PASS = new StringSetting("Database.MySQL.Password"); - public static final Setting MYSQL_DATABASE = new StringSetting("Database.MySQL.Database"); - public static final Setting MYSQL_LAUNCH_OPTIONS = new StringSetting("Database.MySQL.Launch_options"); - - private DatabaseSettings() { - /* static variable class */ - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DisplaySettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DisplaySettings.java deleted file mode 100644 index 8da90a2b2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/DisplaySettings.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.system.settings.config.ConfigNode; -import com.djrapitops.plan.system.settings.paths.key.BooleanSetting; -import com.djrapitops.plan.system.settings.paths.key.IntegerSetting; -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plan.system.settings.paths.key.StringSetting; - -/** - * {@link Setting} values that are in "Display_options" section. - * - * @author Rsl1122 - */ -public class DisplaySettings { - - public static final Setting THEME = new StringSetting("Display_options.Theme"); - public static final Setting REPLACE_SESSION_ACCORDION_WITH_TABLE = new BooleanSetting("Display_options.Sessions.Replace_accordion_with_table"); - public static final Setting SESSIONS_PER_PAGE = new IntegerSetting("Display_options.Sessions.Show_on_page"); - public static final Setting SESSION_MOST_PLAYED_WORLD_IN_TITLE = new BooleanSetting("Display_options.Sessions.Show_most_played_world_in_title"); - public static final Setting ORDER_WORLD_PIE_BY_PERC = new BooleanSetting("Display_options.Sessions.Order_world_pies_by_percentage"); - public static final Setting PLAYERS_PER_SERVER_PAGE = new IntegerSetting("Display_options.Players_table.Show_on_server_page"); - public static final Setting PLAYERS_PER_PLAYERS_PAGE = new IntegerSetting("Display_options.Players_table.Show_on_players_page"); - public static final Setting OPEN_PLAYER_LINKS_IN_NEW_TAB = new BooleanSetting("Display_options.Open_player_links_in_new_tab"); - public static final Setting PLAYER_IPS = new BooleanSetting("Display_options.Show_player_IPs"); - public static final Setting GAPS_IN_GRAPH_DATA = new BooleanSetting("Display_options.Graphs.Show_gaps_in_data"); - public static final Setting GRAPH_TPS_THRESHOLD_HIGH = new IntegerSetting("Display_options.Graphs.TPS.High_threshold"); - public static final Setting GRAPH_TPS_THRESHOLD_MED = new IntegerSetting("Display_options.Graphs.TPS.Medium_threshold"); - public static final Setting GRAPH_DISK_THRESHOLD_HIGH = new IntegerSetting("Display_options.Graphs.Disk_space.High_threshold"); - public static final Setting GRAPH_DISK_THRESHOLD_MED = new IntegerSetting("Display_options.Graphs.Disk_space.Medium_threshold"); - public static final Setting CMD_COLOR_MAIN = new StringSetting("Display_options.Command_colors.Main"); - public static final Setting CMD_COLOR_SECONDARY = new StringSetting("Display_options.Command_colors.Secondary"); - public static final Setting CMD_COLOR_TERTIARY = new StringSetting("Display_options.Command_colors.Highlight"); - public static final Setting WORLD_ALIASES = new Setting("World_aliases", ConfigNode.class) { - @Override - public ConfigNode getValueFrom(ConfigNode node) { - return node.getNode(path).orElse(node.addNode(path)); - } - }; - - private DisplaySettings() { - /* static variable class */ - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ExportSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ExportSettings.java deleted file mode 100644 index 7a10c4306..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ExportSettings.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.system.settings.paths.key.BooleanSetting; -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plan.system.settings.paths.key.StringSetting; - -/** - * {@link Setting} values that are in "Export" section. - * - * @author Rsl1122 - */ -public class ExportSettings { - - public static final Setting HTML_EXPORT_PATH = new StringSetting("Export.HTML_Export_path"); - public static final Setting JSON_EXPORT_PATH = new StringSetting("Export.JSON_Export_path"); - public static final Setting JS_AND_CSS = new BooleanSetting("Export.Parts.JavaScript_and_CSS"); - public static final Setting PLAYER_PAGES = new BooleanSetting("Export.Parts.Player_pages"); - public static final Setting PLAYER_JSON = new BooleanSetting("Export.Parts.Player_JSON"); - public static final Setting PLAYERS_PAGE = new BooleanSetting("Export.Parts.Players_page"); - public static final Setting SERVER_PAGE = new BooleanSetting("Export.Parts.Server_page"); - public static final Setting SERVER_JSON = new BooleanSetting("Export.Parts.Server_JSON"); - public static final Setting EXPORT_ON_ONLINE_STATUS_CHANGE = new BooleanSetting("Export.Export_player_on_login_and_logout"); - - private ExportSettings() { - /* static variable class */ - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/FormatSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/FormatSettings.java deleted file mode 100644 index d476d3583..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/FormatSettings.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.system.settings.paths.key.BooleanSetting; -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plan.system.settings.paths.key.StringSetting; - -/** - * {@link Setting} values that are in "Formatting" section. - * - * @author Rsl1122 - */ -public class FormatSettings { - - public static final Setting DECIMALS = new StringSetting("Formatting.Decimal_points"); - public static final Setting DATE_RECENT_DAYS = new BooleanSetting("Formatting.Dates.Show_recent_day_names"); - public static final Setting DATE_RECENT_DAYS_PATTERN = new StringSetting("Formatting.Dates.Show_recent_day_names.DatePattern"); - public static final Setting DATE_FULL = new StringSetting("Formatting.Dates.Full"); - public static final Setting DATE_NO_SECONDS = new StringSetting("Formatting.Dates.NoSeconds"); - public static final Setting DATE_CLOCK = new StringSetting("Formatting.Dates.JustClock"); - public static final Setting YEAR = new StringSetting("Formatting.Time_amount.Year"); - public static final Setting YEARS = new StringSetting("Formatting.Time_amount.Years"); - public static final Setting MONTH = new StringSetting("Formatting.Time_amount.Month"); - public static final Setting MONTHS = new StringSetting("Formatting.Time_amount.Months"); - public static final Setting DAY = new StringSetting("Formatting.Time_amount.Day"); - public static final Setting DAYS = new StringSetting("Formatting.Time_amount.Days"); - public static final Setting HOURS = new StringSetting("Formatting.Time_amount.Hours"); - public static final Setting MINUTES = new StringSetting("Formatting.Time_amount.Minutes"); - public static final Setting SECONDS = new StringSetting("Formatting.Time_amount.Seconds"); - public static final Setting ZERO_SECONDS = new StringSetting("Formatting.Time_amount.Zero"); - - private FormatSettings() { - /* static variable class */ - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/PluginDataSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/PluginDataSettings.java deleted file mode 100644 index 6ba486b43..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/PluginDataSettings.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plan.system.settings.paths.key.StringListSetting; -import com.djrapitops.plan.system.settings.paths.key.StringSetting; - -import java.util.List; - -/** - * {@link Setting} values that are in "Plugins" section. - * - * @author Rsl1122 - */ -public class PluginDataSettings { - - public static final Setting PLUGIN_BUYCRAFT_SECRET = new StringSetting("Plugins.BuyCraft.Secret"); - public static final Setting> HIDE_FACTIONS = new StringListSetting("Plugins.Factions.HideFactions"); - public static final Setting> HIDE_TOWNS = new StringListSetting("Plugins.Towny.HideTowns"); - - private PluginDataSettings() { - /* static variable class */ - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/PluginSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/PluginSettings.java deleted file mode 100644 index c55d4665a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/PluginSettings.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.system.settings.paths.key.BooleanSetting; -import com.djrapitops.plan.system.settings.paths.key.IntegerSetting; -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plan.system.settings.paths.key.StringSetting; - -/** - * {@link Setting} values that are in "Server" or "Plugin" section. - * - * @author Rsl1122 - */ -public class PluginSettings { - - public static final Setting SERVER_NAME = new StringSetting("Server.ServerName"); - public static final Setting LOCALE = new StringSetting("Plugin.Logging.Locale"); - public static final Setting WRITE_NEW_LOCALE = new BooleanSetting("Plugin.Logging.Create_new_locale_file_on_next_enable"); - public static final Setting DEBUG = new StringSetting("Plugin.Logging.Debug"); - public static final Setting DEV_MODE = new BooleanSetting("Plugin.Logging.Dev"); - public static final Setting KEEP_LOGS_DAYS = new IntegerSetting("Plugin.Logging.Delete_logs_after_days", Setting::timeValidator); - public static final Setting CHECK_FOR_UPDATES = new BooleanSetting("Plugin.Update_notifications.Check_for_updates"); - public static final Setting NOTIFY_ABOUT_DEV_RELEASES = new BooleanSetting("Plugin.Update_notifications.Notify_about_DEV_releases"); - public static final Setting BUNGEE_COPY_CONFIG = new BooleanSetting("Plugin.Configuration.Allow_bungeecord_to_manage_settings"); - - private PluginSettings() { - /* static variable class */ - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ProxySettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ProxySettings.java deleted file mode 100644 index c766b097d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ProxySettings.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plan.system.settings.paths.key.StringSetting; - -/** - * {@link Setting} values that are in "Database" section. - * - * @author Rsl1122 - */ -public class ProxySettings { - - public static final Setting IP = new StringSetting("Server.IP"); - public static final Setting NETWORK_NAME = new StringSetting("Network.Name"); - - private ProxySettings() { - /* static variable class */ - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/TimeSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/TimeSettings.java deleted file mode 100644 index 0eb48a5fc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/TimeSettings.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.system.settings.paths.key.BooleanSetting; -import com.djrapitops.plan.system.settings.paths.key.IntegerSetting; -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plan.system.settings.paths.key.TimeSetting; - -/** - * {@link Setting} values that are in "Time" section. - * - * @author Rsl1122 - */ -public class TimeSettings { - - public static final Setting USE_SERVER_TIME = new BooleanSetting("Time.Use_server_timezone"); - public static final Setting PING_SERVER_ENABLE_DELAY = new TimeSetting("Time.Delays.Ping_server_enable_delay"); - public static final Setting PING_PLAYER_LOGIN_DELAY = new TimeSetting("Time.Delays.Ping_player_join_delay"); - public static final Setting DB_TRANSACTION_FINISH_WAIT_DELAY = new TimeSetting("Time.Delays.Wait_for_DB_Transactions_on_disable"); - public static final Setting AFK_THRESHOLD = new TimeSetting("Time.Thresholds.AFK_threshold"); - public static final Setting ACTIVE_LOGIN_THRESHOLD = new IntegerSetting("Time.Thresholds.Activity_index.Login_threshold", Setting::timeValidator); - public static final Setting ACTIVE_PLAY_THRESHOLD = new TimeSetting("Time.Thresholds.Activity_index.Playtime_threshold"); - public static final Setting DELETE_INACTIVE_PLAYERS_AFTER = new TimeSetting("Time.Thresholds.Remove_inactive_player_data_after"); - public static final Setting DELETE_TPS_DATA_AFTER = new TimeSetting("Time.Thresholds.Remove_time_series_data_after"); - public static final Setting DELETE_PING_DATA_AFTER = new TimeSetting("Time.Thresholds.Remove_ping_data_after"); - public static final Setting ANALYSIS_REFRESH_PERIOD = new TimeSetting("Time.Periodic_tasks.Analysis_refresh_every"); - public static final Setting EXTENSION_DATA_REFRESH_PERIOD = new TimeSetting("Time.Periodic_tasks.Extension_data_refresh_every"); - public static final Setting CLEAN_CACHE_PERIOD = new TimeSetting("Time.Periodic_tasks.Clean_caches_every"); - public static final Setting CLEAN_DATABASE_PERIOD = new TimeSetting("Time.Periodic_tasks.Clean_Database_every"); - public static final Setting CONFIG_UPDATE_INTERVAL = new TimeSetting("Time.Periodic_tasks.Check_DB_for_server_config_files_every"); - - private TimeSettings() { - /* static variable class */ - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/WebserverSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/WebserverSettings.java deleted file mode 100644 index c50635dec..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/WebserverSettings.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths; - -import com.djrapitops.plan.system.settings.paths.key.BooleanSetting; -import com.djrapitops.plan.system.settings.paths.key.IntegerSetting; -import com.djrapitops.plan.system.settings.paths.key.Setting; -import com.djrapitops.plan.system.settings.paths.key.StringSetting; - -/** - * {@link Setting} values that are in "Webserver" section. - * - * @author Rsl1122 - */ -public class WebserverSettings { - - public static final Setting PORT = new IntegerSetting("Webserver.Port"); - public static final Setting SHOW_ALTERNATIVE_IP = new BooleanSetting("Webserver.Alternative_IP"); - public static final Setting ALTERNATIVE_IP = new StringSetting("Webserver.Alternative_IP.Address"); - public static final Setting INTERNAL_IP = new StringSetting("Webserver.Internal_IP"); - public static final Setting CERTIFICATE_PATH = new StringSetting("Webserver.Security.SSL_certificate.KeyStore_path"); - public static final Setting CERTIFICATE_KEYPASS = new StringSetting("Webserver.Security.SSL_certificate.Key_pass"); - public static final Setting CERTIFICATE_STOREPASS = new StringSetting("Webserver.Security.SSL_certificate.Store_pass"); - public static final Setting CERTIFICATE_ALIAS = new StringSetting("Webserver.Security.SSL_certificate.Alias"); - public static final Setting DISABLED = new BooleanSetting("Webserver.Disable_Webserver"); - public static final Setting EXTERNAL_LINK = new StringSetting("Webserver.External_Webserver_address"); - - private WebserverSettings() { - /* static variable class */ - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/BooleanSetting.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/BooleanSetting.java deleted file mode 100644 index 22e104265..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/BooleanSetting.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths.key; - -import com.djrapitops.plan.system.settings.config.ConfigNode; - -import java.util.function.Predicate; - -/** - * Setting implementation for String value settings. - * - * @author Rsl1122 - */ -public class BooleanSetting extends Setting { - - public BooleanSetting(String path) { - super(path, Boolean.class); - } - - public BooleanSetting(String path, Predicate validator) { - super(path, Boolean.class, validator); - } - - @Override - public Boolean getValueFrom(ConfigNode node) { - return node.getNode(path).map(ConfigNode::getBoolean).orElse(false); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/IntegerSetting.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/IntegerSetting.java deleted file mode 100644 index abfb4b652..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/IntegerSetting.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths.key; - -import com.djrapitops.plan.system.settings.config.ConfigNode; - -import java.util.function.Predicate; - -/** - * Setting implementation for String value settings. - * - * @author Rsl1122 - */ -public class IntegerSetting extends Setting { - - public IntegerSetting(String path) { - super(path, Integer.class); - } - - public IntegerSetting(String path, Predicate validator) { - super(path, Integer.class, validator); - } - - @Override - public Integer getValueFrom(ConfigNode node) { - return node.getInteger(path); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/Setting.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/Setting.java deleted file mode 100644 index 11bec5c99..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/Setting.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths.key; - -import com.djrapitops.plan.data.store.Type; -import com.djrapitops.plan.system.settings.config.ConfigNode; - -import java.util.function.Predicate; - -/** - * Represents a path to a config value. - * - * @author Rsl1122 - */ -public abstract class Setting { - - protected final String path; - private final Predicate validator; - - public Setting(String path, Class type) { - this(path, type, Setting::nullValidator); - } - - public Setting(String path, Class type, Predicate validator) { - // null validator has to be called before the actual validator to avoid possible null errors. - this(path, Type.ofClass(type), ((Predicate) Setting::nullValidator).and(validator)); - } - - public Setting(String path, Type type) { - this(path, type, Setting::nullValidator); - } - - public Setting(String path, Type type, Predicate validator) { - this.path = path; - this.validator = validator; - } - - public static boolean nullValidator(T value) { - return value != null; - } - - public static boolean timeValidator(Number number) { - return number.doubleValue() > 0; - } - - /** - * Used to get the String path of a the config setting. - *

- * Path separates nested levels with a dot. - * - * @return Example: Settings.WebServer.Enabled - */ - public String getPath() { - return path; - } - - public abstract T getValueFrom(ConfigNode node); - - public boolean isValid(T value) { - return validator.test(value); - } - - @Override - public String toString() { - throw new UnsupportedOperationException( - "Setting#toString should not be called, relies on old behavior. " + - "Use getValueFrom(ConfigNode) instead. " + - "(Called path: '" + path + "')" - ); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/StringListSetting.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/StringListSetting.java deleted file mode 100644 index b9c0710ed..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/StringListSetting.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths.key; - -import com.djrapitops.plan.data.store.Type; -import com.djrapitops.plan.system.settings.config.ConfigNode; - -import java.util.List; -import java.util.function.Predicate; - -/** - * Setting implementation for String value settings. - * - * @author Rsl1122 - */ -public class StringListSetting extends Setting> { - - public StringListSetting(String path) { - super(path, new Type>() {}); - } - - public StringListSetting(String path, Predicate> validator) { - super(path, new Type>() {}, validator); - } - - @Override - public List getValueFrom(ConfigNode node) { - return node.getStringList(path); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/StringSetting.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/StringSetting.java deleted file mode 100644 index f8a74d738..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/StringSetting.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths.key; - -import com.djrapitops.plan.system.settings.config.ConfigNode; - -import java.util.function.Predicate; - -/** - * Setting implementation for String value settings. - * - * @author Rsl1122 - */ -public class StringSetting extends Setting { - - public StringSetting(String path) { - super(path, String.class); - } - - public StringSetting(String path, Predicate validator) { - super(path, String.class, validator); - } - - @Override - public String getValueFrom(ConfigNode node) { - return node.getString(path); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/TimeSetting.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/TimeSetting.java deleted file mode 100644 index 525f7dd16..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/key/TimeSetting.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.paths.key; - -import com.djrapitops.plan.system.settings.config.ConfigNode; -import com.djrapitops.plugin.utilities.Verify; - -import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; - -/** - * Setting implementation for settings that use {@link java.util.concurrent.TimeUnit} under the value. - *

- * All values return milliseconds. - * - * @author Rsl1122 - */ -public class TimeSetting extends Setting { - - public TimeSetting(String path) { - super(path, Long.class, Setting::timeValidator); - } - - public TimeSetting(String path, Predicate validator) { - super(path, Long.class, validator.and(Setting::timeValidator)); - } - - @Override - public Long getValueFrom(ConfigNode node) { - Long duration = node.getLong(path); - if (duration == null) { - return null; - } - String unitName = node.getString(path + ".Unit"); - try { - Verify.nullCheck(unitName, () -> new IllegalStateException( - "Config value for " + path + ".Unit has a bad value: 'null'" - )); - TimeUnit unit = TimeUnit.valueOf(unitName.toUpperCase()); - return unit.toMillis(duration); - } catch (IllegalArgumentException e) { - return -1L; - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/PlanColorScheme.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/PlanColorScheme.java deleted file mode 100644 index 034534879..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/PlanColorScheme.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.theme; - -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DisplaySettings; -import com.djrapitops.plugin.command.ColorScheme; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; - -/** - * ColorScheme that uses values in config settings specific to Plan or PlanBungee. - * - * @author Rsl1122 - */ -public class PlanColorScheme extends ColorScheme { - - private PlanColorScheme(String... colors) { - super(colors); - } - - public static PlanColorScheme create(PlanConfig config, PluginLogger logger) { - try { - String main = "§" + config.get(DisplaySettings.CMD_COLOR_MAIN).charAt(1); - String secondary = "§" + config.get(DisplaySettings.CMD_COLOR_SECONDARY).charAt(1); - String tertiary = "§" + config.get(DisplaySettings.CMD_COLOR_TERTIARY).charAt(1); - - return new PlanColorScheme(main, secondary, tertiary); - } catch (Exception e) { - logger.log(L.INFO_COLOR, "§cCustomization, Chat colors set-up wrong, using defaults."); - return new PlanColorScheme("§2", "§7", "§f"); - } - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/Theme.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/Theme.java deleted file mode 100644 index 75f694279..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/Theme.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.theme; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.utilities.Verify; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; - -import static com.djrapitops.plan.system.settings.theme.ThemeVal.*; - -/** - * Enum that contains available themes. - *

- * Change config setting Theme.Base to select one. - * - * @author Rsl1122 - */ -@Singleton -public class Theme implements SubSystem { - - private final PlanFiles files; - private final PlanConfig config; - private final PluginLogger logger; - - private ThemeConfig themeConfig; - - @Inject - public Theme(PlanFiles files, PlanConfig config, PluginLogger logger) { - this.files = files; - this.config = config; - this.logger = logger; - } - - public String getValue(ThemeVal variable) { - try { - return getThemeValue(variable); - } catch (NullPointerException | IllegalStateException e) { - return variable.getDefaultValue(); - } - } - - @Override - public void enable() throws EnableException { - try { - themeConfig = new ThemeConfig(files, config, logger); - themeConfig.save(); - } catch (IOException e) { - throw new EnableException("theme.yml could not be saved.", e); - } - } - - @Override - public void disable() { - // No need to save theme on disable - } - - private String getColor(ThemeVal variable) { - String path = variable.getThemePath(); - try { - String value = themeConfig.getString(path); - - if (value.contains(".")) { - return "url(\"" + value + "\")"; - } else { - return value; - } - } catch (Exception | NoSuchFieldError e) { - logger.error("Something went wrong with getting variable " + variable.name() + " for: " + path); - } - return variable.getDefaultValue(); - } - - public String replaceThemeColors(String resourceString) { - String replaced = resourceString; - ThemeVal[] themeVariables = new ThemeVal[]{ - RED, PINK, PURPLE, - DEEP_PURPLE, INDIGO, BLUE, LIGHT_BLUE, CYAN, TEAL, GREEN, LIGHT_GREEN, LIME, - YELLOW, AMBER, ORANGE, DEEP_ORANGE, BROWN, GREY, BLUE_GREY, BLACK, WHITE, - GRAPH_PUNCHCARD, GRAPH_PLAYERS_ONLINE, GRAPH_TPS_HIGH, GRAPH_TPS_MED, GRAPH_TPS_LOW, - GRAPH_CPU, GRAPH_RAM, GRAPH_CHUNKS, GRAPH_ENTITIES, GRAPH_WORLD_PIE, GRAPH_GM_PIE, - GRAPH_ACTIVITY_PIE, GRAPH_SERVER_PREF_PIE, FONT_STYLESHEET, FONT_FAMILY - }; - for (ThemeVal variable : themeVariables) { - String value = getColor(variable); - String defaultValue = variable.getDefaultValue(); - if (Verify.equalsOne(value, defaultValue)) { - continue; - } - if (value.contains("url")) { - String[] colorAndUrl = value.split(" "); - if (colorAndUrl.length >= 2) { - replaced = replaced.replace("background: " + defaultValue, "background: " + colorAndUrl[1]); - replaced = replaced.replace(defaultValue, colorAndUrl[0]); - return replaced; - } - } else { - replaced = replaced.replace(defaultValue, value); - } - } - return replaced.replace("${defaultTheme}", getValue(ThemeVal.THEME_DEFAULT)); - } - - private String getThemeValue(ThemeVal color) { - return themeConfig.getString(color.getThemePath()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeConfig.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeConfig.java deleted file mode 100644 index 0b7505e27..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeConfig.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.theme; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.settings.config.Config; -import com.djrapitops.plan.system.settings.config.ConfigNode; -import com.djrapitops.plan.system.settings.config.ConfigReader; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DisplaySettings; -import com.djrapitops.plugin.logging.console.PluginLogger; - -import java.io.File; -import java.io.IOException; - -/** - * Config that keeps track of theme.yml. - * - * @author Rsl1122 - */ -public class ThemeConfig extends Config { - - public ThemeConfig(PlanFiles files, PlanConfig config, PluginLogger logger) { - this(getConfigFile(files), getDefaults(files, config, logger)); - } - - private ThemeConfig(File configFile, ConfigNode defaults) { - super(configFile, defaults); - - if (defaults.isLeafNode()) { - ConfigNode util = new ConfigNode("", null, ""); - for (ThemeVal themeVal : ThemeVal.values()) { - util.set(themeVal.getThemePath(), themeVal.getDefaultValue()); - } - copyMissing(util); - } - } - - private static ConfigNode getDefaults(PlanFiles files, PlanConfig config, PluginLogger logger) { - String fileName = config.get(DisplaySettings.THEME); - String fileLocation = getFileLocation(fileName); - - try (ConfigReader reader = new ConfigReader(files.getResourceFromJar(fileLocation).asInputStream())) { - return reader.read(); - } catch (IOException e) { - logger.error("Could not find theme " + fileLocation + ". Attempting to use default."); - return new ConfigNode(null, null, null); - } - } - - private static String getFileLocation(String fileName) { - switch (fileName.toLowerCase()) { - case "soft": - case "soften": - return "themes/soft.yml"; - case "mute": - case "lowsaturation": - return "themes/mute.yml"; - case "pastel": - case "bright": - case "harsh": - case "saturated": - case "high": - return "themes/pastel.yml"; - case "sepia": - case "brown": - return "themes/sepia.yml"; - case "grey": - case "gray": - case "greyscale": - case "grayscale": - return "themes/greyscale.yml"; - default: - return "themes/theme.yml"; - } - } - - private static File getConfigFile(PlanFiles files) { - return files.getFileFromPluginFolder("theme.yml"); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeVal.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeVal.java deleted file mode 100644 index bb9f15276..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeVal.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.settings.theme; - -/** - * Enum class used for getting the Html colors that match the config settings. - * - * @author Rsl1122 - */ -public enum ThemeVal { - - THEME_DEFAULT("DefaultColor", "light-green"), - - FONT_STYLESHEET("Font.FontStyleSheet", "https://fonts.googleapis.com/css?family=Roboto:400,700&subset=latin,cyrillic-ext"), - FONT_FAMILY("Font.FontFamily", "\"Roboto\", sans-serif"), - - RED("Colors.red", "#E91E63"), - PINK("Colors.pink", "#F44336"), - PURPLE("Colors.purple", "#9C27B0"), - DEEP_PURPLE("Colors.deep-purple", "#673AB7"), - INDIGO("Colors.indigo", "#3F51B5"), - BLUE("Colors.blue", "#2196F3"), - LIGHT_BLUE("Colors.light-blue", "#03A9F4"), - CYAN("Colors.cyan", "#00BCD4"), - TEAL("Colors.teal", "#009688"), - GREEN("Colors.green", "#4CAF50"), - LIGHT_GREEN("Colors.light-green", "#8BC34A"), - LIME("Colors.lime", "#CDDC39"), - YELLOW("Colors.yellow", "#ffe821"), - AMBER("Colors.amber", "#FFC107"), - ORANGE("Colors.orange", "#FF9800"), - DEEP_ORANGE("Colors.deep-orange", "#FF5722"), - BROWN("Colors.brown", "#795548"), - GREY("Colors.grey", "#9E9E9E"), - BLUE_GREY("Colors.blue-grey", "#607D8B"), - BLACK("Colors.black", "#000000"), - WHITE("Colors.Extra.White", "#fff"), - - GRAPH_PUNCHCARD("GraphColors.PunchCard", "#222"), - GRAPH_PLAYERS_ONLINE("GraphColors.PlayersOnline", "#1E90FF"), - GRAPH_TPS_HIGH("GraphColors.TPS.High", "#267F00"), - GRAPH_TPS_MED("GraphColors.TPS.Medium", "#e5cc12"), - GRAPH_TPS_LOW("GraphColors.TPS.Low", "#b74343"), - GRAPH_CPU("GraphColors.CPU", "#e0d264"), - GRAPH_RAM("GraphColors.RAM", "#7dcc24"), - GRAPH_CHUNKS("GraphColors.Chunks", "#b58310"), - GRAPH_ENTITIES("GraphColors.Entities", "#ac69ef"), - GRAPH_WORLD_PIE("GraphColors.WorldPie", "\"#0099C6\", \"#66AA00\", \"#316395\", \"#994499\", \"#22AA99\", \"#AAAA11\", \"#6633CC\", \"#E67300\", \"#329262\", \"#5574A6\""), - GRAPH_GM_PIE("GraphColors.GMDrilldown", "\"#438c99\", \"#639A67\", \"#D8EBB5\", \"#D9BF77\""), - GRAPH_ACTIVITY_PIE("GraphColors.ActivityPie", "\"#4CAF50\", \"#8BC34A\", \"#CDDC39\", \"#FFC107\", \"#607D8B\""), - GRAPH_SERVER_PREF_PIE("GraphColors.ServerPreferencePie", "\"#0099C6\", \"#66AA00\", \"#316395\", \"#994499\", \"#22AA99\", \"#AAAA11\", \"#6633CC\", \"#E67300\", \"#329262\", \"#5574A6\""), - GRAPH_AVG_PING("GraphColors.Ping.Avg", "#ffc107"), - GRAPH_MAX_PING("GraphColors.Ping.Max", "#ffa000"), - GRAPH_MIN_PING("GraphColors.Ping.Min", "#ffd54f"), - WORLD_MAP_HIGH("GraphColors.WorldMap_High", "#267f00"), - WORLD_MAP_LOW("GraphColors.WorldMap_Low", "#EEFFEE"), - - PARSED_SESSION_ACCORDION("ParsedElements.SessionAccordion", "teal"), - PARSED_SERVER_ACCORDION("ParsedElements.ServerAccordion", "light-green"); - - private final String themePath; - private final String defaultValue; - - ThemeVal(String themePath, String defaultValue) { - this.themePath = themePath; - this.defaultValue = defaultValue; - } - - public String getThemePath() { - return themePath; - } - - public String getDefaultValue() { - return defaultValue; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/status/Status.java b/Plan/common/src/main/java/com/djrapitops/plan/system/status/Status.java deleted file mode 100644 index 4efd7d4ce..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/status/Status.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.status; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class Status { - - private boolean countKicks; - - @Inject - public Status() { - countKicks = true; - } - - public boolean areKicksCounted() { - return countKicks; - } - - public void setCountKicks(boolean countKicks) { - this.countKicks = countKicks; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java deleted file mode 100644 index 5f011a534..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.task.AbsRunnable; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -/** - * Task in charge of removing old log files - * - * @author Rsl1122 - */ -@Singleton -public class LogsFolderCleanTask extends AbsRunnable { - - private final File folder; - private final PlanConfig config; - private final PluginLogger logger; - - @Inject - public LogsFolderCleanTask( - PlanFiles files, - PlanConfig config, - PluginLogger logger - ) { - this.folder = files.getLogsFolder(); - this.config = config; - this.logger = logger; - } - - @Override - public void run() { - try { - if (!folder.exists() || folder.isFile()) { - return; - } - cleanFolder(); - } catch (NullPointerException ignore) { - /* Ignored - not supposed to occur. */ - } finally { - try { - cancel(); - } catch (Exception ignore) { - /* Ignored, TaskCenter concurrent modification exception, will be fixed later in apf-3.3.0. */ - } - } - } - - private void cleanFolder() { - long now = System.currentTimeMillis(); - for (File file : Objects.requireNonNull(folder.listFiles())) { - long forDaysMs = TimeUnit.DAYS.toMillis(config.get(PluginSettings.KEEP_LOGS_DAYS)); - if (now - file.lastModified() > (forDaysMs > 0 ? forDaysMs : TimeUnit.DAYS.toMillis(1L))) { - try { - Files.delete(file.toPath()); - } catch (IOException e) { - logger.warn("Could not delete log file at: " + file.getAbsolutePath() + ", " + e.getMessage()); - } - } - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/PlayersPageRefreshTask.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/PlayersPageRefreshTask.java deleted file mode 100644 index 852b77fd6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/PlayersPageRefreshTask.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks; - -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plugin.task.AbsRunnable; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class PlayersPageRefreshTask extends AbsRunnable { - - @Inject - public PlayersPageRefreshTask() { - // Inject constructor required for dagger - } - - @Override - public void run() { - ResponseCache.clearResponse(PageId.PLAYERS.id()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java deleted file mode 100644 index 194aba116..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks; - -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.system.tasks.server.BootAnalysisTask; -import com.djrapitops.plan.system.tasks.server.PeriodicAnalysisTask; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.task.RunnableFactory; - -import java.util.concurrent.TimeUnit; - -/** - * Abstracted TaskSystem implementation for both Bukkit and Sponge. - * - * @author Rsl1122 - */ -public abstract class ServerTaskSystem extends TaskSystem { - - protected final PlanConfig config; - private final BootAnalysisTask bootAnalysisTask; - private final PeriodicAnalysisTask periodicAnalysisTask; - private final LogsFolderCleanTask logsFolderCleanTask; - private final PlayersPageRefreshTask playersPageRefreshTask; - - public ServerTaskSystem( - RunnableFactory runnableFactory, - TPSCountTimer tpsCountTimer, - PlanConfig config, - BootAnalysisTask bootAnalysisTask, - PeriodicAnalysisTask periodicAnalysisTask, - LogsFolderCleanTask logsFolderCleanTask, - PlayersPageRefreshTask playersPageRefreshTask) { - super(runnableFactory, tpsCountTimer); - this.config = config; - this.bootAnalysisTask = bootAnalysisTask; - this.periodicAnalysisTask = periodicAnalysisTask; - this.logsFolderCleanTask = logsFolderCleanTask; - this.playersPageRefreshTask = playersPageRefreshTask; - } - - @Override - public void enable() { - registerTasks(); - } - - private void registerTasks() { - // Analysis refresh settings - long analysisRefreshMs = config.get(TimeSettings.ANALYSIS_REFRESH_PERIOD); - boolean analysisRefreshTaskIsEnabled = analysisRefreshMs > 0; - long analysisPeriod = TimeAmount.toTicks(analysisRefreshMs, TimeUnit.MILLISECONDS); - - registerTask(tpsCountTimer).runTaskTimer(1000, TimeAmount.toTicks(1L, TimeUnit.SECONDS)); - registerTask(bootAnalysisTask).runTaskLaterAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS)); - - if (analysisRefreshTaskIsEnabled) { - registerTask(periodicAnalysisTask).runTaskTimerAsynchronously(analysisPeriod, analysisPeriod); - } - - registerTask(logsFolderCleanTask).runTaskLaterAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS)); - registerTask(playersPageRefreshTask) - .runTaskTimerAsynchronously(TimeAmount.toTicks(5L, TimeUnit.MINUTES), TimeAmount.toTicks(5L, TimeUnit.MINUTES)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/TPSCountTimer.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/TPSCountTimer.java deleted file mode 100644 index 80b7c8d10..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/TPSCountTimer.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.db.access.transactions.events.TPSStoreTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.AbsRunnable; - -import java.io.File; -import java.lang.management.ManagementFactory; -import java.lang.management.OperatingSystemMXBean; -import java.util.ArrayList; -import java.util.List; - -/** - * Class responsible for calculating TPS every second. - * - * @author Rsl1122 - */ -public abstract class TPSCountTimer extends AbsRunnable { - - protected final List history; - - protected final DBSystem dbSystem; - protected final ServerInfo serverInfo; - protected final PluginLogger logger; - protected final ErrorHandler errorHandler; - - private boolean diskErrored = false; - - protected int latestPlayersOnline = 0; - - public TPSCountTimer( - DBSystem dbSystem, - ServerInfo serverInfo, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.logger = logger; - this.errorHandler = errorHandler; - history = new ArrayList<>(); - } - - @Override - public void run() { - try { - long nanoTime = System.nanoTime(); - long now = System.currentTimeMillis(); - - addNewTPSEntry(nanoTime, now); - - if (history.size() >= 60) { - dbSystem.getDatabase().executeTransaction(new TPSStoreTransaction( - serverInfo.getServerUUID(), - new ArrayList<>(history) - )); - history.clear(); - } - } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { - logger.error("TPS Count Task Disabled due to error, reload Plan to re-enable."); - errorHandler.log(L.ERROR, this.getClass(), e); - cancel(); - } - } - - public abstract void addNewTPSEntry(long nanoTime, long now); - - public int getLatestPlayersOnline() { - return latestPlayersOnline; - } - - protected long getUsedMemory() { - Runtime runtime = Runtime.getRuntime(); - long totalMemory = runtime.totalMemory(); - return (totalMemory - runtime.freeMemory()) / 1000000; - } - - protected double getCPUUsage() { - double averageCPUUsage; - - OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean(); - if (osBean instanceof com.sun.management.OperatingSystemMXBean) { - com.sun.management.OperatingSystemMXBean nativeOsBean = (com.sun.management.OperatingSystemMXBean) osBean; - averageCPUUsage = nativeOsBean.getSystemCpuLoad(); - } else { - int availableProcessors = osBean.getAvailableProcessors(); - averageCPUUsage = osBean.getSystemLoadAverage() / availableProcessors; - } - if (averageCPUUsage < 0) { // If unavailable, getSystemLoadAverage() returns -1 - averageCPUUsage = -1; - } - return averageCPUUsage * 100.0; - } - - protected long getFreeDiskSpace() { - try { - File file = new File(new File("").getAbsolutePath()); - return file.getFreeSpace() / 1000000L; - } catch (SecurityException noPermission) { - if (!diskErrored) { - errorHandler.log(L.WARN, this.getClass(), noPermission); - } - diskErrored = true; - return -1; - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/TaskSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/TaskSystem.java deleted file mode 100644 index 4f25386ed..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/TaskSystem.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks; - -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.PluginRunnable; -import com.djrapitops.plugin.task.RunnableFactory; - -/** - * TaskSystem that registers tasks that were previously registered inside Plugin classes. - * - * Subclasses register actual tasks. - * - * @author Rsl1122 - */ -public abstract class TaskSystem implements SubSystem { - - protected final TPSCountTimer tpsCountTimer; - protected final RunnableFactory runnableFactory; - - public TaskSystem(RunnableFactory runnableFactory, TPSCountTimer tpsCountTimer) { - this.tpsCountTimer = tpsCountTimer; - this.runnableFactory = runnableFactory; - } - - protected PluginRunnable registerTask(AbsRunnable runnable) { - String taskName = runnable.getClass().getSimpleName(); - return registerTask(taskName, runnable); - } - - public PluginRunnable registerTask(String name, AbsRunnable runnable) { - return runnableFactory.create(name, runnable); - } - - @Override - public void disable() { - runnableFactory.cancelAllKnownTasks(); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkConfigStoreTask.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkConfigStoreTask.java deleted file mode 100644 index 664871c99..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkConfigStoreTask.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks.proxy; - -import com.djrapitops.plan.system.settings.network.NetworkSettingManager; -import com.djrapitops.plugin.task.AbsRunnable; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.File; -import java.util.UUID; - -/** - * Task on networks that stores server configs in /plugins/Plan/serverConfiguration in database on boot. - * - * @author Rsl1122 - */ -@Singleton -public class NetworkConfigStoreTask extends AbsRunnable { - - private final NetworkSettingManager networkSettingManager; - - @Inject - public NetworkConfigStoreTask( - NetworkSettingManager networkSettingManager - ) { - this.networkSettingManager = networkSettingManager; - } - - @Override - public void run() { - updateDBConfigs(); - cancel(); - } - - private void updateDBConfigs() { - File[] configFiles = networkSettingManager.getConfigFiles(); - - for (File configFile : configFiles) { - UUID serverUUID = NetworkSettingManager.getServerUUIDFromFilename(configFile); - networkSettingManager.updateConfigInDB(configFile, serverUUID); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkPageRefreshTask.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkPageRefreshTask.java deleted file mode 100644 index bb477b574..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkPageRefreshTask.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks.proxy; - -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plugin.task.AbsRunnable; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class NetworkPageRefreshTask extends AbsRunnable { - - private final ServerInfo serverInfo; - - @Inject - public NetworkPageRefreshTask(ServerInfo serverInfo) { - this.serverInfo = serverInfo; - } - - @Override - public void run() { - ResponseCache.clearResponse(PageId.SERVER.of(serverInfo.getServerUUID())); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java deleted file mode 100644 index ed29802be..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks.server; - -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plan.system.info.request.InfoRequestFactory; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.task.AbsRunnable; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class BootAnalysisTask extends AbsRunnable { - - private final InfoSystem infoSystem; - private final InfoRequestFactory infoRequestFactory; - private final ServerInfo serverInfo; - private final WebExceptionLogger webExceptionLogger; - - @Inject - public BootAnalysisTask( - InfoSystem infoSystem, - InfoRequestFactory infoRequestFactory, - ServerInfo serverInfo, - WebExceptionLogger webExceptionLogger - ) { - this.infoSystem = infoSystem; - this.infoRequestFactory = infoRequestFactory; - this.serverInfo = serverInfo; - this.webExceptionLogger = webExceptionLogger; - } - - @Override - public void run() { - try { - webExceptionLogger.logIfOccurs(this.getClass(), () -> - infoSystem.sendRequest(infoRequestFactory.generateAnalysisPageRequest(serverInfo.getServerUUID())) - ); - } catch (IllegalStateException ignore) { - /* Plugin was reloading */ - } finally { - cancel(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/ConfigStoreTask.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/ConfigStoreTask.java deleted file mode 100644 index 06bc29db7..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/ConfigStoreTask.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks.server; - -import com.djrapitops.plan.db.access.transactions.StoreConfigTransaction; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.task.AbsRunnable; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Task that stores a server config in the database on boot. - * - * @author Rsl1122 - */ -@Singleton -public class ConfigStoreTask extends AbsRunnable { - - private final PlanFiles files; - private final PlanConfig config; - private final ServerInfo serverInfo; - private final DBSystem dbSystem; - private final PluginLogger logger; - - @Inject - public ConfigStoreTask( - PlanFiles files, - PlanConfig config, - ServerInfo serverInfo, - DBSystem dbSystem, - PluginLogger logger - ) { - this.files = files; - this.config = config; - this.serverInfo = serverInfo; - this.dbSystem = dbSystem; - this.logger = logger; - } - - @Override - public void run() { - long lastModified = files.getConfigFile().lastModified(); - dbSystem.getDatabase().executeTransaction(new StoreConfigTransaction(serverInfo.getServerUUID(), config, lastModified)); - logger.debug("Config Store Task - Config in db now up to date."); - cancel(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java b/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java deleted file mode 100644 index 29a3f1d1d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.tasks.server; - -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plan.system.info.request.InfoRequestFactory; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.task.AbsRunnable; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class PeriodicAnalysisTask extends AbsRunnable { - - private final InfoSystem infoSystem; - private final InfoRequestFactory infoRequestFactory; - private final ServerInfo serverInfo; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - private final WebExceptionLogger webExceptionLogger; - - @Inject - public PeriodicAnalysisTask( - InfoSystem infoSystem, - InfoRequestFactory infoRequestFactory, ServerInfo serverInfo, - PluginLogger logger, - ErrorHandler errorHandler, - WebExceptionLogger webExceptionLogger - ) { - this.infoSystem = infoSystem; - this.infoRequestFactory = infoRequestFactory; - this.serverInfo = serverInfo; - this.logger = logger; - this.errorHandler = errorHandler; - this.webExceptionLogger = webExceptionLogger; - } - - @Override - public void run() { - try { - webExceptionLogger.logIfOccurs(this.getClass(), () -> - infoSystem.sendRequest(infoRequestFactory.generateAnalysisPageRequest(serverInfo.getServerUUID())) - ); - } catch (IllegalStateException ignore) { - /* Plugin was reloading */ - } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { - logger.error("Periodic Analysis Task Disabled due to error, reload Plan to re-enable."); - errorHandler.log(L.ERROR, this.getClass(), e); - cancel(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java deleted file mode 100644 index db5378398..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.update; - -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plugin.api.utility.Version; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; -import java.io.IOException; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -/** - * System for checking if new Version is available when the System initializes. - * - * @author Rsl1122 - */ -@Singleton -public class VersionCheckSystem implements SubSystem { - - private final String currentVersion; - private final Locale locale; - private final PlanConfig config; - private final PluginLogger logger; - - private VersionInfo newVersionAvailable; - - @Inject - public VersionCheckSystem( - @Named("currentVersion") String currentVersion, - Locale locale, - PlanConfig config, - PluginLogger logger - ) { - this.currentVersion = currentVersion; - this.locale = locale; - this.config = config; - this.logger = logger; - } - - public boolean isNewVersionAvailable() { - return newVersionAvailable != null; - } - - @Override - public void enable() { - if (config.isFalse(PluginSettings.CHECK_FOR_UPDATES)) { - return; - } - try { - List versions = VersionInfoLoader.load(); - if (config.isFalse(PluginSettings.NOTIFY_ABOUT_DEV_RELEASES)) { - versions = versions.stream().filter(VersionInfo::isRelease).collect(Collectors.toList()); - } - VersionInfo newestVersion = versions.get(0); - if (Version.isNewVersionAvailable(new Version(currentVersion), newestVersion.getVersion())) { - newVersionAvailable = newestVersion; - String notification = locale.getString( - PluginLang.VERSION_AVAILABLE, - newestVersion.getVersion().toString(), - newestVersion.getChangeLogUrl() - ) + (newestVersion.isRelease() ? "" : locale.getString(PluginLang.VERSION_AVAILABLE_DEV)); - logger.log(L.INFO_COLOR, "§a----------------------------------------"); - logger.log(L.INFO_COLOR, "§a" + notification); - logger.log(L.INFO_COLOR, "§a----------------------------------------"); - } else { - logger.info(locale.getString(PluginLang.VERSION_NEWEST)); - } - } catch (IOException e) { - logger.error(locale.getString(PluginLang.VERSION_FAIL_READ_VERSIONS)); - } - } - - @Override - public void disable() { - /* Does not need to be closed */ - } - - public Optional getNewVersionAvailable() { - return Optional.ofNullable(newVersionAvailable); - } - - public Optional getUpdateHtml() { - return getNewVersionAvailable() - .map(v -> v.isTrusted() ? "" + - "

v" + v.getVersion().getVersionString() + " available!

" : ""); - } - - public String getCurrentVersion() { - return currentVersion; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionInfo.java b/Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionInfo.java deleted file mode 100644 index 018639d6c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionInfo.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.update; - -import com.djrapitops.plugin.api.utility.Version; -import com.google.common.base.Objects; - -/** - * Data class for reading version.txt in https://github.com/Rsl1122/Plan-PlayerAnalytics. - * - * @author Rsl1122 - */ -public class VersionInfo implements Comparable { - - private final boolean release; - private final Version version; - private final String downloadUrl; - private final String changeLogUrl; - - public VersionInfo(boolean release, Version version, String downloadUrl, String changeLogUrl) { - this.release = release; - this.version = version; - this.downloadUrl = downloadUrl; - this.changeLogUrl = changeLogUrl; - } - - public boolean isRelease() { - return release; - } - - public Version getVersion() { - return version; - } - - public String getDownloadUrl() { - return downloadUrl; - } - - public String getChangeLogUrl() { - return changeLogUrl; - } - - public boolean isTrusted() { - return downloadUrl.startsWith("https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/"); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - VersionInfo that = (VersionInfo) o; - return release == that.release && - Objects.equal(version, that.version); - } - - @Override - public int hashCode() { - return Objects.hashCode(release, version); - } - - @Override - public int compareTo(VersionInfo o) { - return o.version.compareTo(this.version); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionInfoLoader.java b/Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionInfoLoader.java deleted file mode 100644 index 335e5ed4f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/update/VersionInfoLoader.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.update; - -import com.djrapitops.plugin.api.utility.Version; - -import java.io.IOException; -import java.net.URL; -import java.util.*; - -/** - * Utility for loading version information from github. - * - * @author Rsl1122 - */ -public class VersionInfoLoader { - - private static final String VERSION_TXT_URL = - "https://raw.githubusercontent.com/Rsl1122/Plan-PlayerAnalytics/master/versions.txt"; - - private VersionInfoLoader() { - /* Static method class */ - } - - /** - * Loads version information from github. - * - * @return List of VersionInfo, newest version first. - * @throws IOException If site can not be accessed. - * @throws java.net.MalformedURLException If VERSION_TXT_URL is not valid. - */ - public static List load() throws IOException { - URL url = new URL(VERSION_TXT_URL); - - List versionInfo = new ArrayList<>(); - - try (Scanner websiteScanner = new Scanner(url.openStream())) { - while (websiteScanner.hasNextLine()) { - checkLine(websiteScanner).ifPresent(lineParts -> { - boolean release = lineParts[0].equals("REL"); - Version version = new Version(lineParts[1]); - String downloadUrl = lineParts[2]; - String changeLogUrl = lineParts[3]; - - versionInfo.add(new VersionInfo(release, version, downloadUrl, changeLogUrl)); - }); - } - } - - Collections.sort(versionInfo); - return versionInfo; - } - - private static Optional checkLine(Scanner websiteScanner) { - String line = websiteScanner.nextLine(); - if (!line.startsWith("REL") && !line.startsWith("DEV")) { - return Optional.empty(); - } - String[] parts = line.split("\\|"); - if (parts.length < 4) { - return Optional.empty(); - } - return Optional.of(parts); - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/Request.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/Request.java deleted file mode 100644 index e0d7a2bd2..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/Request.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.sun.net.httpserver.HttpExchange; - -import java.io.InputStream; -import java.net.URI; -import java.util.Optional; - -/** - * Represents a HttpExchange Request. - *

- * Automatically gets the Basic Auth from headers. - * - * @author Rsl1122 - */ -public class Request { - private final String requestMethod; - - private URI requestURI; - - private final HttpExchange exchange; - private final String remoteAddress; - private final Locale locale; - private Authentication auth; - - public Request(HttpExchange exchange, Locale locale) { - this.requestMethod = exchange.getRequestMethod(); - requestURI = exchange.getRequestURI(); - - remoteAddress = exchange.getRemoteAddress().getAddress().getHostAddress(); - - this.exchange = exchange; - - this.locale = locale; - } - - public Optional getAuth() { - return Optional.ofNullable(auth); - } - - public void setAuth(Authentication authentication) { - auth = authentication; - } - - public String getRequestMethod() { - return requestMethod; - } - - public String getTargetString() { - return requestURI.getPath() + '?' + requestURI.getQuery(); - } - - public RequestTarget getTarget() { - return new RequestTarget(requestURI); - } - - public InputStream getRequestBody() { - return exchange.getRequestBody(); - } - - @Override - public String toString() { - return "Request:" + requestMethod + " " + requestURI.getPath(); - } - - public String getRemoteAddress() { - return remoteAddress; - } - - public Locale getLocale() { - return locale; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java deleted file mode 100644 index 8d7e99cbc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver; - -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.auth.BasicAuthentication; -import com.djrapitops.plan.system.webserver.response.PromptAuthorizationResponse; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; -import com.djrapitops.plan.system.webserver.response.errors.ForbiddenResponse; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -/** - * HttpHandler for WebServer request management. - * - * @author Rsl1122 - */ -@Singleton -public class RequestHandler implements HttpHandler { - - private final Locale locale; - private final PlanConfig config; - private final Theme theme; - private final DBSystem dbSystem; - private final ResponseHandler responseHandler; - private final ResponseFactory responseFactory; - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - private final Cache failedLoginAttempts = Caffeine.newBuilder() - .expireAfterWrite(90, TimeUnit.SECONDS) - .build(); - - @Inject - RequestHandler( - Locale locale, - PlanConfig config, - Theme theme, - DBSystem dbSystem, - ResponseHandler responseHandler, - ResponseFactory responseFactory, - PluginLogger logger, - ErrorHandler errorHandler - ) { - this.locale = locale; - this.config = config; - this.theme = theme; - this.dbSystem = dbSystem; - this.responseHandler = responseHandler; - this.responseFactory = responseFactory; - this.logger = logger; - this.errorHandler = errorHandler; - } - - @Override - public void handle(HttpExchange exchange) { - Headers requestHeaders = exchange.getRequestHeaders(); - Headers responseHeaders = exchange.getResponseHeaders(); - - Request request = new Request(exchange, locale); - request.setAuth(getAuthorization(requestHeaders)); - - try { - Response response = shouldPreventRequest(request.getRemoteAddress()) // Forbidden response (Optional) - .orElse(responseHandler.getResponse(request)); // Or the actual requested response - - // Increase attempt count and block if too high - Optional forbid = handlePasswordBruteForceAttempts(request, response); - if (forbid.isPresent()) { - response = forbid.get(); - } - - // Authentication failed, but was not blocked - if (response instanceof PromptAuthorizationResponse) { - responseHeaders.set("WWW-Authenticate", response.getHeader("WWW-Authenticate").orElse("Basic realm=\"Plan WebUser (/plan register)\"")); - } - - response.setResponseHeaders(responseHeaders); - response.send(exchange, locale, theme); - } catch (Exception e) { - if (config.isTrue(PluginSettings.DEV_MODE)) { - logger.warn("THIS ERROR IS ONLY LOGGED IN DEV MODE:"); - errorHandler.log(L.WARN, this.getClass(), e); - } - } finally { - exchange.close(); - } - } - - private Optional shouldPreventRequest(String accessor) { - Integer attempts = failedLoginAttempts.getIfPresent(accessor); - if (attempts == null) { - attempts = 0; - } - - // Too many attempts, forbid further attempts. - if (attempts >= 5) { - return createForbiddenResponse(); - } - return Optional.empty(); - } - - private Optional handlePasswordBruteForceAttempts(Request request, Response response) { - if (request.getAuth().isPresent() && response instanceof PromptAuthorizationResponse) { - // Authentication was attempted, but failed so new attempt is going to be given if not forbidden - - failedLoginAttempts.cleanUp(); - - String accessor = request.getRemoteAddress(); - Integer attempts = failedLoginAttempts.getIfPresent(accessor); - if (attempts == null) { - attempts = 0; - } - - // Too many attempts, forbid further attempts. - if (attempts >= 5) { - logger.warn(accessor + " failed to login 5 times. Their access is blocked for 90 seconds."); - return createForbiddenResponse(); - } - - // Attempts only increased if less than 5 attempts to prevent frustration from the cache value not - // getting removed. - failedLoginAttempts.put(accessor, attempts + 1); - } else if (!(response instanceof PromptAuthorizationResponse) && !(response instanceof ForbiddenResponse)) { - // Successful login - failedLoginAttempts.invalidate(request.getRemoteAddress()); - } - // First connection, no authentication headers present. - return Optional.empty(); - } - - private Optional createForbiddenResponse() { - return Optional.of(responseFactory.forbidden403("You have too many failed login attempts. Please wait 2 minutes until attempting again.")); - } - - private Authentication getAuthorization(Headers requestHeaders) { - List authorization = requestHeaders.get("Authorization"); - if (Verify.isEmpty(authorization)) { - return null; - } - - String authLine = authorization.get(0); - if (authLine.contains("Basic ")) { - return new BasicAuthentication(authLine.split(" ")[1], dbSystem.getDatabase()); - } - return null; - } - - public ResponseHandler getResponseHandler() { - return responseHandler; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestTarget.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestTarget.java deleted file mode 100644 index e4a5f359a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestTarget.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver; - -import java.net.URI; -import java.util.*; -import java.util.stream.Collectors; - -/** - * Represents URI of a requested resource. - * - * @author Rsl1122 - */ -public class RequestTarget { - - private final String resourceString; - private final List resource; - private final Map parameters; - - public RequestTarget(URI targetURI) { - resourceString = targetURI.getPath(); - resource = Arrays.stream(resourceString.split("/")).filter(part -> !part.isEmpty()).collect(Collectors.toList()); - - parameters = new TreeMap<>(); - parseParameters(targetURI.getQuery()); - } - - private void parseParameters(String parameterString) { - if (parameterString == null || parameterString.isEmpty()) { - return; - } - - String[] keysAndValues = parameterString.split("&"); - for (String kv : keysAndValues) { - if (kv.isEmpty()) { - continue; - } - String[] keyAndValue = kv.split("=", 2); - if (keyAndValue.length >= 2) { - parameters.put(keyAndValue[0], keyAndValue[1]); - } - } - } - - public boolean isEmpty() { - return resource.isEmpty(); - } - - public int size() { - return resource.size(); - } - - public String get(int index) { - return resource.get(index); - } - - public void removeFirst() { - if (!isEmpty()) { - resource.remove(0); - } - } - - public boolean endsWith(String suffix) { - return resourceString.endsWith(suffix); - } - - public Optional getParameter(String key) { - return Optional.ofNullable(parameters.get(key)); - } - - public String getResourceString() { - return resourceString; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java deleted file mode 100644 index f36d6ba45..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.api.exceptions.connection.*; -import com.djrapitops.plan.system.info.connection.InfoRequestPageHandler; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.pages.*; -import com.djrapitops.plan.system.webserver.pages.json.RootJSONHandler; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; -import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import dagger.Lazy; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Optional; - -/** - * Handles choosing of the correct response to a request. - * - * @author Rsl1122 - */ -@Singleton -public class ResponseHandler extends TreePageHandler { - - private final DebugPageHandler debugPageHandler; - private final PlayersPageHandler playersPageHandler; - private final PlayerPageHandler playerPageHandler; - private final ServerPageHandler serverPageHandler; - private final InfoRequestPageHandler infoRequestPageHandler; - private final RootJSONHandler rootJSONHandler; - private final ErrorHandler errorHandler; - - private Lazy webServer; - - @Inject - public ResponseHandler( - ResponseFactory responseFactory, - Lazy webServer, - - DebugPageHandler debugPageHandler, - PlayersPageHandler playersPageHandler, - PlayerPageHandler playerPageHandler, - ServerPageHandler serverPageHandler, - InfoRequestPageHandler infoRequestPageHandler, - RootJSONHandler rootJSONHandler, - - ErrorHandler errorHandler - ) { - super(responseFactory); - this.webServer = webServer; - this.debugPageHandler = debugPageHandler; - this.playersPageHandler = playersPageHandler; - this.playerPageHandler = playerPageHandler; - this.serverPageHandler = serverPageHandler; - this.infoRequestPageHandler = infoRequestPageHandler; - this.rootJSONHandler = rootJSONHandler; - this.errorHandler = errorHandler; - } - - public void registerPages() { - registerPage("debug", debugPageHandler); - registerPage("players", playersPageHandler); - registerPage("player", playerPageHandler); - - registerPage("network", serverPageHandler); - registerPage("server", serverPageHandler); - - if (webServer.get().isAuthRequired()) { - registerPage("", new RootPageHandler(responseFactory)); - } else { - registerPage("", responseFactory.redirectResponse("/server"), 5); - } - - registerPage("info", infoRequestPageHandler); - registerPage("json", rootJSONHandler); - } - - public Response getResponse(Request request) { - try { - return tryToGetResponse(request); - } catch (NoServersException | NotFoundException e) { - return responseFactory.notFound404(e.getMessage()); - } catch (WebUserAuthException e) { - return responseFactory.basicAuthFail(e); - } catch (ForbiddenException e) { - return responseFactory.forbidden403(e.getMessage()); - } catch (BadRequestException e) { - return new BadRequestResponse(e.getMessage() + " (when requesting '" + request.getTargetString() + "')"); - } catch (UnauthorizedServerException e) { - return responseFactory.unauthorizedServer(e.getMessage()); - } catch (GatewayException e) { - return responseFactory.gatewayError504(e.getMessage()); - } catch (InternalErrorException e) { - if (e.getCause() != null) { - return responseFactory.internalErrorResponse(e.getCause(), request.getTargetString()); - } else { - return responseFactory.internalErrorResponse(e, request.getTargetString()); - } - } catch (Exception e) { - errorHandler.log(L.ERROR, this.getClass(), e); - return responseFactory.internalErrorResponse(e, request.getTargetString()); - } - } - - private Response tryToGetResponse(Request request) throws WebException { - Optional authentication = request.getAuth(); - RequestTarget target = request.getTarget(); - String resource = target.getResourceString(); - - if (target.endsWith(".css")) { - return ResponseCache.loadResponse(PageId.CSS.of(resource), () -> responseFactory.cssResponse(resource)); - } - if (target.endsWith(".js")) { - return ResponseCache.loadResponse(PageId.JS.of(resource), () -> responseFactory.javaScriptResponse(resource)); - } - if (target.endsWith("favicon.ico")) { - return ResponseCache.loadResponse(PageId.FAVICON.id(), responseFactory::faviconResponse); - } - boolean isNotInfoRequest = target.isEmpty() || !target.get(0).equals("info"); - boolean isAuthRequired = webServer.get().isAuthRequired() && isNotInfoRequest; - if (isAuthRequired && !authentication.isPresent()) { - if (webServer.get().isUsingHTTPS()) { - return responseFactory.basicAuth(); - } else { - return responseFactory.forbidden403(); - } - } - PageHandler pageHandler = getPageHandler(target); - if (pageHandler == null) { - return responseFactory.pageNotFound404(); - } else { - boolean isAuthorized = authentication.isPresent() && pageHandler.isAuthorized(authentication.get(), target); - if (!isAuthRequired || isAuthorized) { - return pageHandler.getResponse(request, target); - } - return responseFactory.forbidden403(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/WebServer.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/WebServer.java deleted file mode 100644 index 7a66c17a5..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/WebServer.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.WebserverSettings; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsParameters; -import com.sun.net.httpserver.HttpsServer; - -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.net.ssl.*; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.nio.file.InvalidPathException; -import java.nio.file.Paths; -import java.security.*; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.util.concurrent.*; - -/** - * @author Rsl1122 - */ -@Singleton -public class WebServer implements SubSystem { - - private final Locale locale; - private final PlanFiles files; - private final PlanConfig config; - - private final ServerProperties serverProperties; - private final RequestHandler requestHandler; - - private final PluginLogger logger; - private final ErrorHandler errorHandler; - - private int port; - private boolean enabled = false; - private HttpServer server; - - private boolean usingHttps = false; - - @Inject - public WebServer( - Locale locale, - PlanFiles files, - PlanConfig config, - ServerInfo serverInfo, - PluginLogger logger, - ErrorHandler errorHandler, - RequestHandler requestHandler - ) { - this.locale = locale; - this.files = files; - this.config = config; - this.serverProperties = serverInfo.getServerProperties(); - - this.requestHandler = requestHandler; - - this.logger = logger; - this.errorHandler = errorHandler; - } - - @Override - public void enable() throws EnableException { - this.port = config.get(WebserverSettings.PORT); - - initServer(); - - if (!isEnabled()) { - if (Check.isBungeeAvailable() || Check.isVelocityAvailable()) { - throw new EnableException(locale.getString(PluginLang.ENABLE_FAIL_NO_WEB_SERVER_PROXY)); - } - if (config.isTrue(WebserverSettings.DISABLED)) { - logger.warn(locale.getString(PluginLang.ENABLE_NOTIFY_WEB_SERVER_DISABLED)); - } else { - logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_PORT_BIND, port)); - } - } - - requestHandler.getResponseHandler().registerPages(); - } - - /** - * Starts up the WebServer in a new Thread Pool. - */ - private void initServer() { - if ((Check.isBukkitAvailable() || Check.isSpongeAvailable()) && config.isTrue(WebserverSettings.DISABLED)) { - // Bukkit/Sponge WebServer has been disabled. - return; - } - - if (enabled) { - // Server is already enabled stop code - return; - } - - try { - usingHttps = startHttpsServer(); - - logger.debug(usingHttps ? "Https Start Successful." : "Https Start Failed."); - - if (!usingHttps) { - logger.log(L.INFO_COLOR, "§e" + locale.getString(PluginLang.WEB_SERVER_NOTIFY_HTTP_USER_AUTH)); - server = HttpServer.create(new InetSocketAddress(config.get(WebserverSettings.INTERNAL_IP), port), 10); - } else if (server == null) { - logger.log(L.INFO_COLOR, "§eWebServer: Proxy HTTPS Override enabled. HTTP Server in use, make sure that your Proxy webserver is routing with HTTPS and AlternativeIP.Link points to the Proxy"); - server = HttpServer.create(new InetSocketAddress(config.get(WebserverSettings.INTERNAL_IP), port), 10); - } - server.createContext("/", requestHandler); - - ExecutorService executor = new ThreadPoolExecutor( - 4, 8, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), - new ThreadFactoryBuilder().setNameFormat("Plan WebServer Thread-%d").build() - ); - server.setExecutor(executor); - server.start(); - - enabled = true; - - logger.info(locale.getString(PluginLang.ENABLED_WEB_SERVER, server.getAddress().getPort(), getAccessAddress())); - } catch (IllegalArgumentException | IllegalStateException | IOException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - enabled = false; - } - } - - private boolean startHttpsServer() { - String keyStorePath = config.get(WebserverSettings.CERTIFICATE_PATH); - - if ("proxy".equalsIgnoreCase(keyStorePath)) { - return true; - } - - try { - if (!Paths.get(keyStorePath).isAbsolute()) { - keyStorePath = files.getDataFolder() + File.separator + keyStorePath; - } - } catch (InvalidPathException e) { - logger.error("WebServer: Could not find Keystore: " + e.getMessage()); - errorHandler.log(L.ERROR, this.getClass(), e); - } - - char[] storepass = config.get(WebserverSettings.CERTIFICATE_STOREPASS).toCharArray(); - char[] keypass = config.get(WebserverSettings.CERTIFICATE_KEYPASS).toCharArray(); - String alias = config.get(WebserverSettings.CERTIFICATE_ALIAS); - - boolean startSuccessful = false; - try (FileInputStream fIn = new FileInputStream(keyStorePath)) { - KeyStore keystore = KeyStore.getInstance("JKS"); - - keystore.load(fIn, storepass); - Certificate cert = keystore.getCertificate(alias); - - if (cert == null) { - throw new IllegalStateException("Certificate with Alias: " + alias + " was not found in the Keystore."); - } - - logger.info("Certificate: " + cert.getType()); - - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); - keyManagerFactory.init(keystore, keypass); - - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509"); - trustManagerFactory.init(keystore); - - server = HttpsServer.create(new InetSocketAddress(config.get(WebserverSettings.INTERNAL_IP), port), 10); - SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); - sslContext.init(keyManagerFactory.getKeyManagers(), null/*trustManagerFactory.getTrustManagers()*/, null); - - ((HttpsServer) server).setHttpsConfigurator(new HttpsConfigurator(sslContext) { - @Override - public void configure(HttpsParameters params) { - SSLEngine engine = sslContext.createSSLEngine(); - - params.setNeedClientAuth(false); - params.setCipherSuites(engine.getEnabledCipherSuites()); - params.setProtocols(engine.getEnabledProtocols()); - - SSLParameters defaultSSLParameters = sslContext.getDefaultSSLParameters(); - params.setSSLParameters(defaultSSLParameters); - } - }); - startSuccessful = true; - } catch (IllegalStateException e) { - logger.error(e.getMessage()); - errorHandler.log(L.ERROR, this.getClass(), e); - } catch (KeyManagementException | NoSuchAlgorithmException e) { - logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_SSL_CONTEXT)); - errorHandler.log(L.ERROR, this.getClass(), e); - } catch (FileNotFoundException e) { - logger.log(L.INFO_COLOR, "§e" + locale.getString(PluginLang.WEB_SERVER_NOTIFY_NO_CERT_FILE, keyStorePath)); - logger.info(locale.getString(PluginLang.WEB_SERVER_NOTIFY_HTTP)); - } catch (IOException e) { - logger.error("WebServer: " + e); - errorHandler.log(L.ERROR, this.getClass(), e); - } catch (KeyStoreException | CertificateException | UnrecoverableKeyException e) { - logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_STORE_LOAD)); - errorHandler.log(L.ERROR, this.getClass(), e); - } - return startSuccessful; - } - - /** - * @return if the WebServer is enabled - */ - public boolean isEnabled() { - return enabled; - } - - /** - * Shuts down the server - Async thread is closed with shutdown boolean. - */ - @Override - public void disable() { - if (server != null) { - shutdown(); - logger.info(locale.getString(PluginLang.DISABLED_WEB_SERVER)); - } - enabled = false; - } - - private void shutdown() { - server.stop(0); - Executor executor = server.getExecutor(); - if (executor instanceof ExecutorService) { - ExecutorService service = (ExecutorService) executor; - service.shutdown(); - try { - if (!service.awaitTermination(5, TimeUnit.SECONDS)) { - service.shutdownNow(); - } - } catch (InterruptedException e) { - logger.error("WebServer ExecutorService shutdown thread interrupted on disable: " + e.getMessage()); - Thread.currentThread().interrupt(); - } - } - } - - public String getProtocol() { - return usingHttps ? "https" : "http"; - } - - public boolean isUsingHTTPS() { - return usingHttps; - } - - public boolean isAuthRequired() { - return isUsingHTTPS(); - } - - public String getAccessAddress() { - return isEnabled() ? getProtocol() + "://" + getIP() : config.get(WebserverSettings.EXTERNAL_LINK); - } - - private String getIP() { - return config.isTrue(WebserverSettings.SHOW_ALTERNATIVE_IP) - ? config.get(WebserverSettings.ALTERNATIVE_IP).replace("%port%", String.valueOf(port)) - : serverProperties.getIp() + ":" + port; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/WebServerSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/WebServerSystem.java deleted file mode 100644 index f703865dc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/WebServerSystem.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver; - -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plugin.benchmarking.Timings; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * WebServer subsystem for managing WebServer initialization. - * - * @author Rsl1122 - */ -@Singleton -public class WebServerSystem implements SubSystem { - - private final WebServer webServer; - private Timings timings; - - @Inject - public WebServerSystem(WebServer webServer, Timings timings) { - this.webServer = webServer; - this.timings = timings; - } - - @Override - public void enable() throws EnableException { - timings.start("WebServer Initialization"); - webServer.enable(); - timings.end("WebServer Initialization"); - } - - @Override - public void disable() { - ResponseCache.clearCache(); - webServer.disable(); - } - - public WebServer getWebServer() { - return webServer; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/Authentication.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/Authentication.java deleted file mode 100644 index ba1905741..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/Authentication.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.auth; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.data.WebUser; - -/** - * Interface for different WebUser authentication methods used by Requests. - * - * @author Rsl1122 - */ -public interface Authentication { - - WebUser getWebUser() throws WebUserAuthException; - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java deleted file mode 100644 index 4d0fa2019..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.auth; - -import com.djrapitops.plan.api.exceptions.PassEncryptException; -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.WebUserQueries; -import com.djrapitops.plan.utilities.Base64Util; -import com.djrapitops.plan.utilities.PassEncryptUtil; - -/** - * Authentication handling for Basic Auth. - *

- * Basic access authentication (Wikipedia): - * https://en.wikipedia.org/wiki/Basic_access_authentication - * - * @author Rsl1122 - */ -public class BasicAuthentication implements Authentication { - - private final String authenticationString; - private final Database database; - - public BasicAuthentication(String authenticationString, Database database) { - this.authenticationString = authenticationString; - this.database = database; - } - - @Override - public WebUser getWebUser() throws WebUserAuthException { - String decoded = Base64Util.decode(authenticationString); - - String[] userInfo = decoded.split(":"); - if (userInfo.length != 2) { - throw new WebUserAuthException(FailReason.USER_AND_PASS_NOT_SPECIFIED); - } - - String user = userInfo[0]; - String passwordRaw = userInfo[1]; - - Database.State dbState = database.getState(); - if (dbState != Database.State.OPEN) { - throw new WebUserAuthException(FailReason.DATABASE_NOT_OPEN, "State was: " + dbState.name()); - } - - try { - WebUser webUser = database.query(WebUserQueries.fetchWebUser(user)) - .orElseThrow(() -> new WebUserAuthException(FailReason.USER_DOES_NOT_EXIST, user)); - - boolean correctPass = PassEncryptUtil.verifyPassword(passwordRaw, webUser.getSaltedPassHash()); - if (!correctPass) { - throw new WebUserAuthException(FailReason.USER_PASS_MISMATCH, user); - } - return webUser; - } catch (DBOpException | PassEncryptException e) { - throw new WebUserAuthException(e); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/FailReason.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/FailReason.java deleted file mode 100644 index 0a7cfeddf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/auth/FailReason.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.auth; - -import com.djrapitops.plan.system.locale.lang.Lang; - -/** - * Reason for WebUserAuthException. - * - * @author Rsl1122 - * @see com.djrapitops.plan.api.exceptions.WebUserAuthException - */ -public enum FailReason implements Lang { - USER_AND_PASS_NOT_SPECIFIED("User and Password not specified"), - USER_DOES_NOT_EXIST("User does not exist"), - USER_PASS_MISMATCH("User and Password did not match"), - DATABASE_NOT_OPEN("Database is not open, check db status with /plan info"), - ERROR("Authentication failed due to error"); - - private final String reason; - - FailReason(String reason) { - this.reason = reason; - } - - public String getReason() { - return reason; - } - - @Override - public String getIdentifier() { - return "HTML - " + name(); - } - - @Override - public String getDefault() { - return getReason(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/cache/PageId.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/cache/PageId.java deleted file mode 100644 index 935135d17..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/cache/PageId.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.cache; - -import java.util.UUID; - -/** - * Enum class for "magic" ResponseCache identifier values. - * - * @author Rsl1122 - */ -public enum PageId { - - SERVER("serverPage:"), - RAW_SERVER("rawServer:"), - PLAYER("playerPage:"), - RAW_PLAYER("rawPlayer:"), - PLAYERS("playersPage"), - - ERROR("error:"), - FORBIDDEN(ERROR.of("Forbidden")), - NOT_FOUND(ERROR.of("Not Found")), - - JS("js:"), - CSS("css:"), - - FAVICON("Favicon"), - - @Deprecated - PLAYER_PLUGINS_TAB("playerPluginsTab:"), - NETWORK_CONTENT("networkContent"); - - private final String id; - - PageId(String id) { - this.id = id; - } - - public String of(String additionalInfo) { - return id + additionalInfo; - } - - public String of(UUID uuid) { - return of(uuid.toString()); - } - - public String id() { - return id; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/cache/ResponseCache.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/cache/ResponseCache.java deleted file mode 100644 index a48c51d68..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/cache/ResponseCache.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.cache; - -import com.djrapitops.plan.system.webserver.response.Response; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; - -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; - -/** - * This class contains the page cache. - *

- * It caches all Responses with their matching identifiers. - * This reduces CPU cycles and the time to wait for loading the pages. - * This is especially useful in situations where multiple clients are accessing the server. - * - * @author Fuzzlemann - */ -public class ResponseCache { - - private static final Cache cache = Caffeine.newBuilder() - .expireAfterWrite(5, TimeUnit.MINUTES) - .build(); - - /** - * Constructor used to hide the public constructor - */ - private ResponseCache() { - throw new IllegalStateException("Utility class"); - } - - /** - * Loads the response from the response cache. - *

- * If the {@link Response} isn't cached, {@link Supplier#get()} in the {@code loader} - * is called to create the Response. - *

- * If the Response is created, it's automatically cached. - * - * @param identifier The identifier of the page - * @param loader The The {@link Response} {@link Supplier} (How should it load the page if it's not cached) - * @return The Response that was cached or created by the the {@link Response} {@link Supplier} - */ - public static Response loadResponse(String identifier, Supplier loader) { - return cache.get(identifier, k -> loader.get()); - } - - /** - * Loads the page from the page cache. - * - * @param identifier The identifier of the page - * @return The Response that was cached or {@code null} if it wasn't - */ - public static Response loadResponse(String identifier) { - return cache.getIfPresent(identifier); - } - - /** - * Puts the page into the page cache. - *

- * If the cache already inherits that {@code identifier}, it's renewed. - * - * @param identifier The identifier of the page - * @param loader The {@link Response} {@link Supplier} (How it should load the page) - */ - public static void cacheResponse(String identifier, Supplier loader) { - Response response = loader.get(); - if (response != null) { - cache.put(identifier, response); - } - } - - /** - * Checks if the page is cached. - * - * @param identifier The identifier of the page - * @return true if the page is cached - */ - public static boolean isCached(String identifier) { - return cache.getIfPresent(identifier) != null; - } - - /** - * Clears the cache from all its contents. - */ - public static void clearCache() { - cache.invalidateAll(); - } - - public static Set getCacheKeys() { - return cache.asMap().keySet(); - } - - public static long getEstimatedSize() { - return cache.estimatedSize(); - } - - public static void clearResponse(String identifier) { - cache.invalidate(identifier); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java deleted file mode 100644 index 181a38a20..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * PageHandler for /debug page. - * - * @author Rsl1122 - */ -@Singleton -public class DebugPageHandler implements PageHandler { - - private final ResponseFactory responseFactory; - - @Inject - public DebugPageHandler(ResponseFactory responseFactory) { - this.responseFactory = responseFactory; - } - - @Override - public Response getResponse(Request request, RequestTarget target) { - return responseFactory.debugPageResponse(); - } - - @Override - public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException { - WebUser webUser = auth.getWebUser(); - return webUser.getPermLevel() <= 0; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java deleted file mode 100644 index f76cf881a..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.response.Response; - -/** - * PageHandlers are used for easier Response management and authorization checking. - * - * @author Rsl1122 - */ -public interface PageHandler { - - /** - * Get the Response of a PageHandler. - * - * @param request Request in case it is useful for choosing page. - * @param target Rest of the target coordinates after this page has been solved. - * @return Response appropriate to the PageHandler. - */ - Response getResponse(Request request, RequestTarget target) throws WebException; - - default boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException { - return true; - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java deleted file mode 100644 index 0d449836e..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.api.exceptions.connection.ForbiddenException; -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.PlayerFetchQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; -import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; -import com.djrapitops.plan.utilities.uuid.UUIDUtility; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.UUID; - -/** - * PageHandler for /player/PlayerName pages. - * - * @author Rsl1122 - */ -@Singleton -public class PlayerPageHandler implements PageHandler { - - private final ResponseFactory responseFactory; - private final DBSystem dbSystem; - private final InfoSystem infoSystem; - private final UUIDUtility uuidUtility; - - @Inject - public PlayerPageHandler( - ResponseFactory responseFactory, - DBSystem dbSystem, - InfoSystem infoSystem, - UUIDUtility uuidUtility - ) { - this.responseFactory = responseFactory; - this.dbSystem = dbSystem; - this.infoSystem = infoSystem; - this.uuidUtility = uuidUtility; - } - - @Override - public Response getResponse(Request request, RequestTarget target) throws WebException { - if (target.isEmpty()) { - return responseFactory.pageNotFound404(); - } - - String playerName = target.get(0); - UUID uuid = uuidUtility.getUUIDOf(playerName); - - boolean raw = target.size() >= 2 && target.get(1).equalsIgnoreCase("raw"); - - if (uuid == null) { - return responseFactory.uuidNotFound404(); - } - try { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - throw new ForbiddenException("Database is " + dbState.name() + " - Please try again later. You can check database status with /plan info"); - } - // TODO Move this Database dependency to PlayerPage generation in PageFactory instead. - if (dbSystem.getDatabase().query(PlayerFetchQueries.isPlayerRegistered(uuid))) { - if (raw) { - return ResponseCache.loadResponse(PageId.RAW_PLAYER.of(uuid), () -> responseFactory.rawPlayerPageResponse(uuid)); - } - return playerResponseOrNotFound(uuid); - } else { - return responseFactory.playerNotFound404(); - } - } catch (NoServersException e) { - ResponseCache.loadResponse(PageId.PLAYER.of(uuid), () -> responseFactory.notFound404(e.getMessage())); - } - return responseFactory.serverNotFound404(); - } - - private Response playerResponseOrNotFound(UUID uuid) throws WebException { - Response response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); - if (!(response instanceof InspectPageResponse)) { - infoSystem.generateAndCachePlayerPage(uuid); - response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); - } - return response != null ? response : responseFactory.playerNotFound404(); - } - - @Override - public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException { - WebUser webUser = auth.getWebUser(); - return webUser.getPermLevel() <= 1 || webUser.getName().equalsIgnoreCase(target.get(target.size() - 1)); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java deleted file mode 100644 index d1be11287..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.api.exceptions.connection.ForbiddenException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * PageHandler for /players page. - * - * @author Rsl1122 - */ -@Singleton -public class PlayersPageHandler implements PageHandler { - - private final DBSystem dbSystem; - private final ResponseFactory responseFactory; - - @Inject - public PlayersPageHandler( - DBSystem dbSystem, - ResponseFactory responseFactory - ) { - this.dbSystem = dbSystem; - this.responseFactory = responseFactory; - } - - @Override - public Response getResponse(Request request, RequestTarget target) throws WebException { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - throw new ForbiddenException("Database is " + dbState.name() + " - Please try again later. You can check database status with /plan info"); - } - return ResponseCache.loadResponse(PageId.PLAYERS.id(), responseFactory::playersPageResponse); - } - - @Override - public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException { - return auth.getWebUser().getPermLevel() <= 1; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/RootPageHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/RootPageHandler.java deleted file mode 100644 index 47052fa27..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/RootPageHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages; - -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.response.RedirectResponse; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; - -import java.util.Optional; - -/** - * PageHandler for / page (Address root). - *

- * Not Available if Authentication is not enabled. - * - * @author Rsl1122 - */ -public class RootPageHandler implements PageHandler { - - private final ResponseFactory responseFactory; - - public RootPageHandler(ResponseFactory responseFactory) { - this.responseFactory = responseFactory; - } - - @Override - public Response getResponse(Request request, RequestTarget target) throws WebException { - Optional auth = request.getAuth(); - if (!auth.isPresent()) { - return responseFactory.basicAuth(); - } - - WebUser webUser = auth.get().getWebUser(); - - int permLevel = webUser.getPermLevel(); - switch (permLevel) { - case 0: - return new RedirectResponse("/server"); - case 1: - return new RedirectResponse("/players"); - case 2: - return new RedirectResponse("/player/" + webUser.getName()); - default: - return responseFactory.forbidden403(); - } - } - - @Override - public boolean isAuthorized(Authentication auth, RequestTarget target) { - return true; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java deleted file mode 100644 index b947bdbf1..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; -import com.djrapitops.plan.api.exceptions.connection.ForbiddenException; -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Optional; -import java.util.UUID; - -/** - * PageHandler for /server and /network pages. - * - * @author Rsl1122 - */ -@Singleton -public class ServerPageHandler implements PageHandler { - - private final Processing processing; - private final ResponseFactory responseFactory; - private final DBSystem dbSystem; - private final ServerInfo serverInfo; - private final InfoSystem infoSystem; - - @Inject - public ServerPageHandler( - Processing processing, - ResponseFactory responseFactory, - DBSystem dbSystem, - ServerInfo serverInfo, - InfoSystem infoSystem - ) { - this.processing = processing; - this.responseFactory = responseFactory; - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; - this.infoSystem = infoSystem; - } - - @Override - public Response getResponse(Request request, RequestTarget target) throws WebException { - UUID serverUUID = getServerUUID(target); - - boolean raw = target.size() >= 2 && target.get(1).equalsIgnoreCase("raw"); - if (raw) { - checkDBState(); - return ResponseCache.loadResponse(PageId.RAW_SERVER.of(serverUUID), () -> responseFactory.rawServerPageResponse(serverUUID)); - } - - Response response = ResponseCache.loadResponse(PageId.SERVER.of(serverUUID)); - - if (response != null) { - return response; - } else { - checkDBState(); - if (serverInfo.getServer().isProxy() && serverInfo.getServerUUID().equals(serverUUID)) { - return ResponseCache.loadResponse(PageId.SERVER.of(serverUUID), responseFactory::networkPageResponse); - } - return refreshNow(serverUUID); - } - } - - private void checkDBState() throws ForbiddenException { - Database.State dbState = dbSystem.getDatabase().getState(); - if (dbState != Database.State.OPEN) { - throw new ForbiddenException("Database is " + dbState.name() + " - Please try again later. You can check database status with /plan info"); - } - } - - // TODO Split responsibility so that this method does not call system to refresh and also render a refresh page. - private Response refreshNow(UUID serverUUID) { - processing.submitNonCritical(() -> { - try { - infoSystem.generateAnalysisPage(serverUUID); - } catch (NoServersException | ConnectionFailException e) { - ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> responseFactory.notFound404(e.getMessage())); - } catch (WebException e) { - ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> responseFactory.internalErrorResponse(e, "Failed to generate Analysis Page")); - } - }); - return responseFactory.refreshingAnalysisResponse(); - } - - private UUID getServerUUID(RequestTarget target) { - // Default to current server's page - UUID serverUUID = serverInfo.getServerUUID(); - - if (!target.isEmpty()) { - try { - String serverName = target.get(0); - Optional serverUUIDOptional = dbSystem.getDatabase() - .query(ServerQueries.fetchServerMatchingIdentifier(serverName)) - .map(Server::getUuid); - if (serverUUIDOptional.isPresent()) { - serverUUID = serverUUIDOptional.get(); - } - } catch (IllegalArgumentException ignore) { - /*ignored*/ - } - } - return serverUUID; - } - - @Override - public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException { - return auth.getWebUser().getPermLevel() <= 0; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java deleted file mode 100644 index f082456ba..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; - -import java.util.HashMap; -import java.util.Map; - -/** - * Abstract PageHandler that allows Tree-like target deduction. - * - * @author Rsl1122 - */ -public abstract class TreePageHandler implements PageHandler { - - protected final ResponseFactory responseFactory; - - private Map pages; - - public TreePageHandler(ResponseFactory responseFactory) { - this.responseFactory = responseFactory; - pages = new HashMap<>(); - } - - public void registerPage(String targetPage, PageHandler handler) { - pages.put(targetPage, handler); - } - - public void registerPage(String targetPage, Response response, int requiredPerm) { - pages.put(targetPage, new PageHandler() { - @Override - public Response getResponse(Request request, RequestTarget target) { - return response; - } - - @Override - public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException { - return auth.getWebUser().getPermLevel() <= requiredPerm; - } - }); - } - - @Override - public Response getResponse(Request request, RequestTarget target) throws WebException { - PageHandler pageHandler = getPageHandler(target); - return pageHandler != null - ? pageHandler.getResponse(request, target) - : responseFactory.pageNotFound404(); - } - - public PageHandler getPageHandler(RequestTarget target) { - if (target.isEmpty()) { - return pages.get(""); - } - String targetPage = target.get(0); - target.removeFirst(); - return pages.get(targetPage); - } - - public PageHandler getPageHandler(String targetPage) { - return pages.get(targetPage); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/JSONFactory.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/JSONFactory.java deleted file mode 100644 index f42363709..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/JSONFactory.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages.json; - -import com.djrapitops.plan.db.Database; -import com.djrapitops.plan.db.access.queries.containers.ServerPlayersTableContainersQuery; -import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionServerPlayerDataTableQuery; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DisplaySettings; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.utilities.formatting.Formatters; -import com.djrapitops.plan.utilities.html.tables.PlayersTableJSONParser; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.UUID; - -/** - * Factory with different JSON parsing placed to a single class. - * - * @author Rsl1122 - */ -@Singleton -public class JSONFactory { - - private final PlanConfig config; - private final DBSystem dbSystem; - private final Formatters formatters; - - @Inject - public JSONFactory( - PlanConfig config, - DBSystem dbSystem, - Formatters formatters - ) { - this.config = config; - this.dbSystem = dbSystem; - this.formatters = formatters; - } - - public String serverPlayersTableJSON(UUID serverUUID) { - Integer xMostRecentPlayers = config.get(DisplaySettings.PLAYERS_PER_SERVER_PAGE); - Integer loginThreshold = config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD); - Long playtimeThreshold = config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD); - Boolean openPlayerLinksInNewTab = config.get(DisplaySettings.OPEN_PLAYER_LINKS_IN_NEW_TAB); - - Database database = dbSystem.getDatabase(); - - return new PlayersTableJSONParser( - database.query(new ServerPlayersTableContainersQuery(serverUUID)), - database.query(new ExtensionServerPlayerDataTableQuery(serverUUID, xMostRecentPlayers)), - xMostRecentPlayers, playtimeThreshold, loginThreshold, openPlayerLinksInNewTab, - formatters - ).toJSONString(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/PlayersTableJSONHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/PlayersTableJSONHandler.java deleted file mode 100644 index c426605db..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/PlayersTableJSONHandler.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages.json; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.db.access.queries.objects.ServerQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.pages.PageHandler; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.data.JSONResponse; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Optional; -import java.util.UUID; - -/** - * JSON handler for different Player table JSON requests. - * - * @author Rsl1122 - * @see com.djrapitops.plan.utilities.html.tables.PlayersTableJSONParser For JSON parsing of /server players table. - */ -@Singleton -public class PlayersTableJSONHandler implements PageHandler { - - private final DBSystem dbSystem; - private final JSONFactory jsonFactory; - - @Inject - public PlayersTableJSONHandler( - DBSystem dbSystem, - JSONFactory jsonFactory - ) { - this.jsonFactory = jsonFactory; - this.dbSystem = dbSystem; - } - - @Override - public Response getResponse(Request request, RequestTarget target) throws WebException { - UUID serverUUID = getServerUUID(target); // Can throw BadRequestException - return new JSONResponse(jsonFactory.serverPlayersTableJSON(serverUUID)); - } - - private UUID getServerUUID(RequestTarget target) throws BadRequestException { - Optional serverUUID = target.getParameter("serverUUID"); - if (serverUUID.isPresent()) { - return getServerUUIDDirectly(serverUUID.get()); - } else { - return getServerUUIDFromName(target); // Preferred - } - } - - private UUID getServerUUIDFromName(RequestTarget target) throws BadRequestException { - String serverName = target.getParameter("serverName") - .orElseThrow(() -> new BadRequestException("'serverName' parameter was not defined.")); - return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverName)) - .map(Server::getUuid) - .orElseThrow(() -> new BadRequestException("'serverName' was not found in the database.: '" + serverName + "'")); - } - - private UUID getServerUUIDDirectly(String serverUUIDString) throws BadRequestException { - try { - return UUID.fromString(serverUUIDString); - } catch (IllegalArgumentException malformedUUIDException) { - throw new BadRequestException("'serverName' was not a valid UUID: " + malformedUUIDException.getMessage()); - } - } - - @Override - public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException { - return auth.getWebUser().getPermLevel() <= 0; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/RootJSONHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/RootJSONHandler.java deleted file mode 100644 index b5690a138..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/RootJSONHandler.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.pages.json; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.system.webserver.RequestTarget; -import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.pages.TreePageHandler; -import com.djrapitops.plan.system.webserver.response.ResponseFactory; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Root handler for different JSON end points. - * - * @author Rsl1122 - */ -@Singleton -public class RootJSONHandler extends TreePageHandler { - - @Inject - public RootJSONHandler( - ResponseFactory responseFactory, - PlayersTableJSONHandler playersTableJSONHandler - ) { - super(responseFactory); - - registerPage("players", playersTableJSONHandler); - } - - @Override - public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException { - return true; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ByteResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ByteResponse.java deleted file mode 100644 index 547fda430..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ByteResponse.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.sun.net.httpserver.HttpExchange; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * {@link Response} for raw bytes. - * - * @author Rsl1122 - */ -public class ByteResponse extends Response { - - private final PlanFiles files; - private final String fileName; - - public ByteResponse(ResponseType type, String fileName, PlanFiles files) { - super(type); - this.fileName = fileName; - this.files = files; - - setHeader("HTTP/1.1 200 OK"); - } - - @Override - public void send(HttpExchange exchange, Locale locale, Theme theme) throws IOException { - responseHeaders.set("Accept-Ranges", "bytes"); - exchange.sendResponseHeaders(getCode(), 0); - - try (OutputStream out = exchange.getResponseBody(); - InputStream bis = files.getCustomizableResourceOrDefault(fileName).asInputStream()) { - byte[] buffer = new byte[2048]; - int count; - while ((count = bis.read(buffer)) != -1) { - out.write(buffer, 0, count); - } - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/CSSResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/CSSResponse.java deleted file mode 100644 index 92cfb28f6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/CSSResponse.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -import com.djrapitops.plan.system.file.PlanFiles; - -import java.io.IOException; - -/** - * @author Rsl1122 - */ -public class CSSResponse extends FileResponse { - - public CSSResponse(String fileName, PlanFiles files) throws IOException { - super(format(fileName), files); - super.setType(ResponseType.CSS); - setContent(getContent()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/DefaultResponses.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/DefaultResponses.java deleted file mode 100644 index 012e952cf..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/DefaultResponses.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -/** - * Enum containing default responses that don't need to be cached because they're always the same. - * - * @author Rsl1122 - */ -public enum DefaultResponses { - SUCCESS(new TextResponse("Success")); - - private final Response response; - - DefaultResponses(Response response) { - this.response = response; - } - - public Response get() { - return response; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java deleted file mode 100644 index 8362a11ca..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plugin.utilities.Verify; - -import java.io.IOException; - -/** - * Response class for returning file contents. - *

- * Created to remove copy-paste. - * - * @author Rsl1122 - */ -public class FileResponse extends Response { - - public FileResponse(String fileName, PlanFiles files) throws IOException { - super.setHeader("HTTP/1.1 200 OK"); - super.setContent(files.getCustomizableResourceOrDefault(fileName).asString()); - } - - public static String format(String fileName) { - String[] split = fileName.split("/"); - int i; - for (i = 0; i < split.length; i++) { - String s = split[i]; - if (Verify.equalsOne(s, "css", "js", "plugins", "scss")) { - break; - } - } - StringBuilder b = new StringBuilder("web"); - for (int j = i; j < split.length; j++) { - String s = split[j]; - b.append("/").append(s); - } - return b.toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java deleted file mode 100644 index 88eca07c5..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -import com.djrapitops.plan.system.file.PlanFiles; - -import java.io.IOException; - -/** - * @author Rsl1122 - */ -public class JavaScriptResponse extends FileResponse { - - JavaScriptResponse(String fileName, PlanFiles files) throws IOException { - super(format(fileName), files); - super.setType(ResponseType.JAVASCRIPT); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java deleted file mode 100644 index 69ea8a8c6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plan.system.webserver.auth.FailReason; -import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; -import com.djrapitops.plan.utilities.html.icon.Icon; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * @author Rsl1122 - */ -public class PromptAuthorizationResponse extends ErrorResponse { - - private static final String TIPS = "
- Ensure you have registered a user with /plan register
" - + "- Check that the username and password are correct
" - + "- Username and password are case-sensitive
" - + "
If you have forgotten your password, ask a staff member to delete your old user and re-register."; - - private PromptAuthorizationResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - super(versionCheckSystem, files); - super.setTitle(Icon.called("lock").build() + " 401 Unauthorized"); - } - - public static PromptAuthorizationResponse getBasicAuthResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - PromptAuthorizationResponse response = new PromptAuthorizationResponse(versionCheckSystem, files); - response.setHeader("HTTP/1.1 401 Access Denied\r\n" - + "WWW-Authenticate: Basic realm=\"Plan WebUser (/plan register)\""); - - response.setParagraph("Authentication Failed." + TIPS); - response.replacePlaceholders(); - return response; - } - - public static PromptAuthorizationResponse getBasicAuthResponse(WebUserAuthException e, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - PromptAuthorizationResponse response = new PromptAuthorizationResponse(versionCheckSystem, files); - - FailReason failReason = e.getFailReason(); - String reason = failReason.getReason(); - - if (failReason == FailReason.ERROR) { - StringBuilder errorBuilder = new StringBuilder("

");
-            for (String line : getStackTrace(e.getCause())) {
-                errorBuilder.append(line);
-            }
-            errorBuilder.append("
"); - - reason += errorBuilder.toString(); - } - - response.setHeader("HTTP/1.1 401 Access Denied\r\n" - + "WWW-Authenticate: Basic realm=\"" + failReason.getReason() + "\""); - response.setParagraph("Authentication Failed.

Reason: " + reason + "

" + TIPS); - response.replacePlaceholders(); - return response; - } - - /** - * Gets lines for stack trace recursively. - * - * @param throwable Throwable element - * @return lines of stack trace. - */ - private static List getStackTrace(Throwable throwable) { - List stackTrace = new ArrayList<>(); - stackTrace.add(throwable.toString()); - for (StackTraceElement element : throwable.getStackTrace()) { - stackTrace.add(" " + element.toString()); - } - - Throwable cause = throwable.getCause(); - if (cause != null) { - List causeTrace = getStackTrace(cause); - if (!causeTrace.isEmpty()) { - causeTrace.set(0, "Caused by: " + causeTrace.get(0)); - stackTrace.addAll(causeTrace); - } - } - - return stackTrace; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/RedirectResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/RedirectResponse.java deleted file mode 100644 index 24c0afef7..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/RedirectResponse.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.sun.net.httpserver.HttpExchange; - -import java.io.IOException; - -/** - * @author Rsl1122 - */ -public class RedirectResponse extends Response { - - public RedirectResponse(String direct) { - super.setHeader("HTTP/1.1 302 Found"); - super.setContent(direct); - } - - @Override - public void send(HttpExchange exchange, Locale locale, Theme theme) throws IOException { - responseHeaders.set("Location", getContent()); - super.send(exchange, locale, theme); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/Response.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/Response.java deleted file mode 100644 index 177a94dc6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/Response.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpExchange; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Objects; -import java.util.Optional; -import java.util.zip.GZIPOutputStream; - -/** - * @author Rsl1122 - */ -public abstract class Response { - - private String type; - private String header; - private String content; - - protected Headers responseHeaders; - - public Response(ResponseType type) { - this.type = type.get(); - } - - /** - * Default Response constructor that defaults ResponseType to HTML. - */ - public Response() { - this(ResponseType.HTML); - } - - protected String getHeader() { - return header; - } - - public Optional getHeader(String called) { - for (String header : header.split("\r\n")) { - if (header.startsWith(called)) { - return Optional.of(header.split(": ")[1]); - } - } - return Optional.empty(); - } - - public void setHeader(String header) { - this.header = header; - } - - public String getResponse() { - return header + "\r\n" - + "Content-Type: " + type + ";\r\n" - + "Content-Length: " + content.length() + "\r\n" - + "\r\n" - + content; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public int getCode() { - return header == null ? 500 : Integer.parseInt(header.split(" ")[1]); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Response response = (Response) o; - return Objects.equals(header, response.header) && - Objects.equals(content, response.content); - } - - @Override - public int hashCode() { - return Objects.hash(header, content); - } - - protected void setType(ResponseType type) { - this.type = type.get(); - } - - public void setResponseHeaders(Headers responseHeaders) { - this.responseHeaders = responseHeaders; - } - - public void send(HttpExchange exchange, Locale locale, Theme theme) throws IOException { - responseHeaders.set("Content-Type", type); - responseHeaders.set("Content-Encoding", "gzip"); - exchange.sendResponseHeaders(getCode(), 0); - - String sentContent = getContent(); - // TODO Smell - if (!(this instanceof JavaScriptResponse)) { - sentContent = locale.replaceMatchingLanguage(sentContent); - } - sentContent = theme.replaceThemeColors(sentContent); - - try ( - GZIPOutputStream out = new GZIPOutputStream(exchange.getResponseBody()); - ByteArrayInputStream bis = new ByteArrayInputStream(sentContent.getBytes(StandardCharsets.UTF_8)) - ) { - byte[] buffer = new byte[2048]; - int count; - while ((count = bis.read(buffer)) != -1) { - out.write(buffer, 0, count); - } - } - } - - @Override - public String toString() { - return header + " | " + getResponse(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseCode.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseCode.java deleted file mode 100644 index c2214263b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseCode.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -/** - * Enum for HTTP response codes. - * - * @author Rsl1122 - */ -public enum ResponseCode { - NONE(0), - CONNECTION_REFUSED(-1), - SUCCESS(200), - BAD_REQUEST(400), - UNAUTHORIZED(401), - FORBIDDEN(403), - NOT_FOUND(404), - PRECONDITION_FAILED(412), - INTERNAL_ERROR(500), - GATEWAY_ERROR(504); - - private final int code; - - ResponseCode(int code) { - this.code = code; - } - - public int getCode() { - return code; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseFactory.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseFactory.java deleted file mode 100644 index 62eaffaba..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseFactory.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.api.exceptions.WebUserAuthException; -import com.djrapitops.plan.db.access.queries.containers.ContainerFetchQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.ErrorPageLang; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plan.system.webserver.response.errors.*; -import com.djrapitops.plan.system.webserver.response.pages.*; -import com.djrapitops.plan.utilities.html.pages.PageFactory; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.io.IOException; -import java.util.UUID; - -/** - * Factory for creating different {@link Response} objects. - * - * @author Rsl1122 - */ -@Singleton -public class ResponseFactory { - - private final VersionCheckSystem versionCheckSystem; - private final PlanFiles files; - private final PageFactory pageFactory; - private final Locale locale; - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public ResponseFactory( - VersionCheckSystem versionCheckSystem, - PlanFiles files, - PageFactory pageFactory, - Locale locale, - DBSystem dbSystem, - ErrorHandler errorHandler - ) { - this.versionCheckSystem = versionCheckSystem; - this.files = files; - this.pageFactory = pageFactory; - this.locale = locale; - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - } - - public Response debugPageResponse() { - try { - return new DebugPageResponse(pageFactory.debugPage(), versionCheckSystem, files); - } catch (IOException e) { - return internalErrorResponse(e, "Failed to parse debug page"); - } - } - - public Response playersPageResponse() { - try { - return new PlayersPageResponse(pageFactory.playersPage()); - } catch (ParseException e) { - return internalErrorResponse(e, "Failed to parse players page"); - } - } - - public ErrorResponse internalErrorResponse(Throwable e, String s) { - try { - errorHandler.log(L.WARN, this.getClass(), e); - return new InternalErrorResponse(s, e, versionCheckSystem, files); - } catch (IOException improperRestartException) { - return new ErrorResponse( - "Error occurred: " + e.toString() + - ", additional error occurred when attempting to send error page to user: " + - improperRestartException.toString() - ); - } - } - - public Response networkPageResponse() { - try { - return new NetworkPageResponse(pageFactory.networkPage()); - } catch (ParseException e) { - return internalErrorResponse(e, "Failed to parse network page"); - } - } - - public RawDataResponse rawPlayerPageResponse(UUID uuid) { - return new RawPlayerDataResponse(dbSystem.getDatabase().query(ContainerFetchQueries.fetchPlayerContainer(uuid))); - } - - public RawDataResponse rawServerPageResponse(UUID serverUUID) { - return new RawServerDataResponse(dbSystem.getDatabase().query(ContainerFetchQueries.fetchServerContainer(serverUUID))); - } - - public Response javaScriptResponse(String fileName) { - try { - return new JavaScriptResponse(fileName, files); - } catch (IOException e) { - return notFound404("JS File not found from jar: " + fileName + ", " + e.toString()); - } - } - - public Response cssResponse(String fileName) { - try { - return new CSSResponse(fileName, files); - } catch (IOException e) { - return notFound404("CSS File not found from jar: " + fileName + ", " + e.toString()); - } - } - - public Response redirectResponse(String location) { - return new RedirectResponse(location); - } - - public Response faviconResponse() { - return new ByteResponse(ResponseType.X_ICON, "web/favicon.ico", files); - } - - public ErrorResponse pageNotFound404() { - return notFound404(locale.getString(ErrorPageLang.UNKNOWN_PAGE_404)); - } - - public ErrorResponse uuidNotFound404() { - return notFound404(locale.getString(ErrorPageLang.UUID_404)); - } - - public ErrorResponse playerNotFound404() { - return notFound404(locale.getString(ErrorPageLang.NOT_PLAYED_404)); - } - - public ErrorResponse serverNotFound404() { - return notFound404(locale.getString(ErrorPageLang.NO_SERVERS_404)); - } - - public ErrorResponse notFound404(String message) { - try { - return new NotFoundResponse(message, versionCheckSystem, files); - } catch (IOException e) { - return internalErrorResponse(e, "Failed to parse 404 page"); - } - } - - public ErrorResponse basicAuthFail(WebUserAuthException e) { - try { - return PromptAuthorizationResponse.getBasicAuthResponse(e, versionCheckSystem, files); - } catch (IOException e1) { - return internalErrorResponse(e, "Failed to parse PromptAuthorizationResponse"); - } - } - - public ErrorResponse forbidden403() { - return forbidden403("Your user is not authorized to view this page.
" - + "If you believe this is an error contact staff to change your access level."); - } - - public ErrorResponse forbidden403(String message) { - try { - return new ForbiddenResponse(message, versionCheckSystem, files); - } catch (IOException e) { - return internalErrorResponse(e, "Failed to parse ForbiddenResponse"); - } - } - - public ErrorResponse unauthorizedServer(String message) { - try { - return new UnauthorizedServerResponse(message, versionCheckSystem, files); - } catch (IOException e) { - return internalErrorResponse(e, "Failed to parse UnauthorizedServerResponse"); - } - } - - public ErrorResponse gatewayError504(String message) { - try { - return new GatewayErrorResponse(message, versionCheckSystem, files); - } catch (IOException e) { - return internalErrorResponse(e, "Failed to parse GatewayErrorResponse"); - } - } - - public ErrorResponse basicAuth() { - try { - return PromptAuthorizationResponse.getBasicAuthResponse(versionCheckSystem, files); - } catch (IOException e) { - return internalErrorResponse(e, "Failed to parse PromptAuthorizationResponse"); - } - } - - public ErrorResponse refreshingAnalysisResponse() { - try { - return new RefreshingAnalysisResponse(versionCheckSystem, files); - } catch (IOException e) { - return internalErrorResponse(e, "Failed to parse RefreshingAnalysisResponse"); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseType.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseType.java deleted file mode 100644 index 175cb0423..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseType.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -/** - * Enum for HTTP content-type response header Strings. - * - * @author Rsl1122 - */ -public enum ResponseType { - HTML("text/html; charset=utf-8"), - CSS("text/css"), - JSON("application/json"), - JAVASCRIPT("application/javascript"), - IMAGE("image/gif"), - X_ICON("image/x-icon"); - - private final String type; - - ResponseType(String type) { - this.type = type; - } - - public String get() { - return type; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/TextResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/TextResponse.java deleted file mode 100644 index c549aeb17..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/TextResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response; - -/** - * Response for raw text. - * - * @author Rsl1122 - */ -public class TextResponse extends Response { - - public TextResponse(String content) { - setHeader("HTTP/1.1 200 OK"); - setContent(content); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/data/JSONResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/data/JSONResponse.java deleted file mode 100644 index b114caa83..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/data/JSONResponse.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.data; - -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseType; - -/** - * Generic JSON response implemented using Gson. - *

- * Returns a JSON version of the given object. - * - * @author Rsl1122 - */ -public class JSONResponse extends Response { - - public JSONResponse(T object) { - super(ResponseType.JSON); - super.setHeader("HTTP/1.1 200 OK"); - - try { - Class gsonClass = Class.forName("com.google.gson.Gson"); - Object gson = gsonClass.getConstructor().newInstance(); - Object json = gsonClass.getMethod("toJson", Object.class).invoke(gson, object); - - super.setContent(json.toString()); - } catch (ReflectiveOperationException e) { - super.setContent("{\"error\":\"Gson for json responses not available on this server: " + e.toString() + "\"}"); - } - } - - public JSONResponse(String jsonString) { - super(ResponseType.JSON); - super.setHeader("HTTP/1.1 200 OK"); - super.setContent(jsonString); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/BadRequestResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/BadRequestResponse.java deleted file mode 100644 index b82b30c35..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/BadRequestResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.errors; - -import com.djrapitops.plan.system.webserver.response.Response; - -/** - * @author Fuzzlemann - */ -public class BadRequestResponse extends Response { - - public BadRequestResponse(String error) { - super.setHeader("HTTP/1.1 400 Bad Request " + error); - super.setContent("400 Bad Request: " + error); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java deleted file mode 100644 index 72d12ad5b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.errors; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plan.system.webserver.response.pages.PageResponse; -import org.apache.commons.text.StringSubstitutor; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Represents generic HTTP Error response that has the page style in it. - * - * @author Rsl1122 - */ -public class ErrorResponse extends PageResponse { - - private String title; - private String paragraph; - - private VersionCheckSystem versionCheckSystem; - - public ErrorResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - this.versionCheckSystem = versionCheckSystem; - setContent(files.getCustomizableResourceOrDefault("web/error.html").asString()); - } - - public ErrorResponse(String message) { - setContent(message); - } - - public void replacePlaceholders() { - Map placeHolders = new HashMap<>(); - placeHolders.put("title", title); - String[] split = title.split(">", 3); - placeHolders.put("titleText", split.length == 3 ? split[2] : title); - placeHolders.put("paragraph", paragraph); - placeHolders.put("version", versionCheckSystem.getCurrentVersion()); - placeHolders.put("update", versionCheckSystem.getUpdateHtml().orElse("")); - - setContent(StringSubstitutor.replace(getContent(), placeHolders)); - } - - public void setTitle(String title) { - this.title = title; - } - - public void setParagraph(String paragraph) { - this.paragraph = paragraph; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ErrorResponse)) return false; - if (!super.equals(o)) return false; - ErrorResponse that = (ErrorResponse) o; - return Objects.equals(title, that.title) && - Objects.equals(paragraph, that.paragraph); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), title, paragraph); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java deleted file mode 100644 index 9ee22d827..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.errors; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plan.utilities.html.icon.Family; -import com.djrapitops.plan.utilities.html.icon.Icon; - -import java.io.IOException; - -/** - * @author Rsl1122 - */ -public class ForbiddenResponse extends ErrorResponse { - public ForbiddenResponse(String msg, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - super(versionCheckSystem, files); - super.setHeader("HTTP/1.1 403 Forbidden"); - super.setTitle(Icon.called("hand-paper").of(Family.REGULAR) + " 403 Forbidden - Access Denied"); - super.setParagraph(msg); - super.replacePlaceholders(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/GatewayErrorResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/GatewayErrorResponse.java deleted file mode 100644 index b126fff00..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/GatewayErrorResponse.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.errors; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.update.VersionCheckSystem; - -import java.io.IOException; - -/** - * ErrorResponse for GatewayException. - * - * @author Rsl1122 - */ -public class GatewayErrorResponse extends ErrorResponse { - - public GatewayErrorResponse(String message, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - super(versionCheckSystem, files); - super.setHeader("HTTP/1.1 504 Gateway Error"); - super.setTitle("Failed to Connect (Gateway Error)"); - super.setParagraph(message); - super.replacePlaceholders(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java deleted file mode 100644 index 5789f6818..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.errors; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plan.utilities.html.icon.Icon; - -import java.io.IOException; - -/** - * @author Rsl1122 - */ -public class InternalErrorResponse extends ErrorResponse { - - public InternalErrorResponse(String cause, Throwable e, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - super(versionCheckSystem, files); - super.setHeader("HTTP/1.1 500 Internal Error"); - - super.setTitle(Icon.called("bug") + " 500 Internal Error occurred"); - - StringBuilder paragraph = new StringBuilder(); - paragraph.append("Please report this issue here: "); - paragraph.append(Html.LINK.parse("https://github.com/Rsl1122/Plan-PlayerAnalytics/issues", "Issues")); - paragraph.append("

");
-        paragraph.append(e).append(" | ").append(cause);
-
-        for (StackTraceElement element : e.getStackTrace()) {
-            paragraph.append("
"); - paragraph.append(" ").append(element); - } - if (e.getCause() != null) { - appendCause(e.getCause(), paragraph); - } - - paragraph.append("
"); - - super.setParagraph(paragraph.toString()); - super.replacePlaceholders(); - } - - private void appendCause(Throwable cause, StringBuilder paragraph) { - paragraph.append("
Caused by: ").append(cause); - for (StackTraceElement element : cause.getStackTrace()) { - paragraph.append("
"); - paragraph.append(" ").append(element); - } - if (cause.getCause() != null) { - appendCause(cause.getCause(), paragraph); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java deleted file mode 100644 index d019270dc..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.errors; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plan.utilities.html.icon.Icon; - -import java.io.IOException; - -/** - * Generic 404 response. - * - * @author Rsl1122 - */ -public class NotFoundResponse extends ErrorResponse { - - public NotFoundResponse(String msg, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - super(versionCheckSystem, files); - super.setHeader("HTTP/1.1 404 Not Found"); - super.setTitle(Icon.called("map-signs") + " 404 Not Found"); - super.setParagraph(msg); - super.replacePlaceholders(); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/RefreshingAnalysisResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/RefreshingAnalysisResponse.java deleted file mode 100644 index 96c4ba2dd..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/RefreshingAnalysisResponse.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.errors; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.update.VersionCheckSystem; - -import java.io.IOException; - -/** - * This response is used when Analysis is being refreshed and the user needs some feedback. - * - * @author Rsl1122 - */ -public class RefreshingAnalysisResponse extends ErrorResponse { - - public RefreshingAnalysisResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - super(versionCheckSystem, files); - - setTitle("Analysis is being refreshed.."); - setParagraph(" Analysis is being run, refresh the page after a few seconds.. (F5)"); - replacePlaceholders(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/UnauthorizedServerResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/UnauthorizedServerResponse.java deleted file mode 100644 index d92c778fe..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/errors/UnauthorizedServerResponse.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.errors; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.update.VersionCheckSystem; - -import java.io.IOException; - -/** - * Response when Server is not found in database when attempting to InfoRequest. - * - * @author Rsl1122 - */ -public class UnauthorizedServerResponse extends ErrorResponse { - public UnauthorizedServerResponse(String message, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - super(versionCheckSystem, files); - super.setHeader("HTTP/1.1 412 Unauthorized"); - super.setTitle("Unauthorized Server"); - super.setParagraph(message); - super.replacePlaceholders(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java deleted file mode 100644 index 1b213fb03..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages; - -/** - * @author Rsl1122 - */ -public class AnalysisPageResponse extends PageResponse { - - public AnalysisPageResponse(String html) { - super.setHeader("HTTP/1.1 200 OK"); - super.setContent(html); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java deleted file mode 100644 index e95be1ca4..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages; - -import com.djrapitops.plan.system.file.PlanFiles; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; -import com.djrapitops.plan.utilities.html.icon.Icon; -import com.djrapitops.plan.utilities.html.pages.DebugPage; - -import java.io.IOException; - -/** - * WebServer response for /debug-page used for easing issue reporting. - * - * @author Rsl1122 - */ -public class DebugPageResponse extends ErrorResponse { - - public DebugPageResponse(DebugPage debugPage, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { - super(versionCheckSystem, files); - super.setHeader("HTTP/1.1 200 OK"); - super.setTitle(Icon.called("bug") + " Debug Information"); - super.setParagraph(debugPage.toHtml()); - replacePlaceholders(); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java deleted file mode 100644 index ecea30248..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages; - -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.pages.parts.InspectPagePluginsContent; -import org.apache.commons.text.StringSubstitutor; - -import java.util.*; - -/** - * @author Rsl1122 - */ -public class InspectPageResponse extends PageResponse { - - private final UUID uuid; - - public InspectPageResponse(UUID uuid, String html) { - super.setHeader("HTTP/1.1 200 OK"); - super.setContent(html); - this.uuid = uuid; - } - - @Override - public String getContent() { - Map replaceMap = new HashMap<>(); - // PluginData compatibility - Optional pluginsTab = Optional.ofNullable((InspectPagePluginsContent) ResponseCache.loadResponse(PageId.PLAYER_PLUGINS_TAB.of(uuid))) - .map(InspectPagePluginsContent::getContents); - - replaceMap.put("navPluginsTabs", pluginsTab.map(nav -> nav[0]).orElse("")); - replaceMap.put("pluginsTabs", pluginsTab.map(tab -> tab[1]).orElse("")); - - return StringSubstitutor.replace(super.getContent(), replaceMap); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof InspectPageResponse)) return false; - if (!super.equals(o)) return false; - InspectPageResponse that = (InspectPageResponse) o; - return Objects.equals(uuid, that.uuid); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), uuid); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/NetworkPageResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/NetworkPageResponse.java deleted file mode 100644 index 57b00144c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/NetworkPageResponse.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages; - -import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.utilities.html.pages.NetworkPage; - -/** - * Response for /network page. - * - * @author Rsl1122 - */ -public class NetworkPageResponse extends PageResponse { - - public NetworkPageResponse(NetworkPage networkPage) throws ParseException { - setHeader("HTTP/1.1 200 OK"); - setContent(networkPage.toHtml()); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PageResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PageResponse.java deleted file mode 100644 index fe6deb79d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PageResponse.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages; - -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.ResponseType; -import com.googlecode.htmlcompressor.compressor.HtmlCompressor; - -/** - * Response for all HTML Page responses. - * - * @author Rsl1122 - */ -public class PageResponse extends Response { - - private static final HtmlCompressor HTML_COMPRESSOR = new HtmlCompressor(); - - static { - HTML_COMPRESSOR.setRemoveIntertagSpaces(true); - } - - public PageResponse(ResponseType type) { - super(type); - } - - public PageResponse() { - } - - @Override - public void setContent(String content) { - super.setContent(HTML_COMPRESSOR.compress(content)); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java deleted file mode 100644 index 194155f37..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages; - -import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.utilities.html.pages.PlayersPage; - -/** - * @author Rsl1122 - */ -public class PlayersPageResponse extends PageResponse { - - public PlayersPageResponse(PlayersPage playersPage) throws ParseException { - setHeader("HTTP/1.1 200 OK"); - setContent(playersPage.toHtml()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawDataResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawDataResponse.java deleted file mode 100644 index a1dd8a097..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawDataResponse.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages; - -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.system.webserver.response.data.JSONResponse; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * Response for sending raw data as JSON when it is inside a DataContainer. - *

- * This transform class is required to remove Key-Supplier object pollution in the resulting JSON, as well as to remove - * the effects of the caching layer. - * - * @author Rsl1122 - */ -public class RawDataResponse extends JSONResponse> { - - public RawDataResponse(DataContainer dataContainer) { - super(mapToNormalMap(dataContainer)); - } - - private static Map mapToNormalMap(DataContainer player) { - Map values = new HashMap<>(); - player.getMap().forEach((key, value) -> - { - if (value instanceof DataContainer) { - value = mapToNormalMap((DataContainer) value); - } - if (value instanceof Map) { - value = handleMap((Map) value); - } - if (value instanceof List) { - value = handleList((List) value); - } - values.put(key.getKeyName(), value); - } - ); - return values; - } - - private static List handleList(List list) { - if (list.stream().findAny().orElse(null) instanceof DataContainer) { - return (List) list.stream().map(obj -> mapToNormalMap((DataContainer) obj)).collect(Collectors.toList()); - } - return list; - } - - private static Map handleMap(Map map) { - if (map.values().stream().findAny().orElse(null) instanceof DataContainer) { - Map newMap = new HashMap<>(); - map.forEach((key, value) -> newMap.put(key, mapToNormalMap((DataContainer) value))); - return newMap; - } - return map; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java deleted file mode 100644 index 0ae64aaea..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages; - -import com.djrapitops.plan.data.store.containers.PlayerContainer; - -/** - * Raw Data JSON response for a Player. - * - * @author Rsl1122 - */ -public class RawPlayerDataResponse extends RawDataResponse { - - public RawPlayerDataResponse(PlayerContainer playerContainer) { - super(playerContainer); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java deleted file mode 100644 index 1befb0166..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages; - -import com.djrapitops.plan.data.store.containers.ServerContainer; - -/** - * Raw Data JSON response for a Server. - * - * @author Rsl1122 - * @deprecated Marked for removal in 5.0.0 - */ -@Deprecated -public class RawServerDataResponse extends RawDataResponse { - - public RawServerDataResponse(ServerContainer serverContainer) { - super(serverContainer); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/parts/InspectPagePluginsContent.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/parts/InspectPagePluginsContent.java deleted file mode 100644 index a5ec5e577..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/pages/parts/InspectPagePluginsContent.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.system.webserver.response.pages.parts; - -import com.djrapitops.plan.data.element.InspectContainer; -import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.response.pages.PageResponse; -import com.djrapitops.plan.utilities.comparators.PluginDataNameComparator; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plan.utilities.html.HtmlStructure; -import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator; - -import java.util.*; - -/** - * Represents Plugins tabs on Inspect page. - *

- * Extends Response so that it can be stored in ResponseCache. - * - * @deprecated PluginData API has been deprecated - see https://github.com/plan-player-analytics/Plan/wiki/APIv5---DataExtension-API for new API. - * @author Rsl1122 - */ -@Deprecated -public class InspectPagePluginsContent extends PageResponse { - - // ServerUUID, {nav, html} - private final Map pluginsTab; - - public InspectPagePluginsContent() { - pluginsTab = new HashMap<>(); - } - - public InspectPagePluginsContent(String nav, String html) { - pluginsTab = new HashMap<>(); - addTab(nav, html); - } - - public static InspectPagePluginsContent generateForThisServer(UUID playerUUID, ServerInfo serverInfo, HookHandler hookHandler) { - String serverName = serverInfo.getServer().getName(); - String actualServerName = "Plan".equals(serverName) ? "Server " + serverInfo.getServer().getId() : serverName; - - Map containers = hookHandler.getInspectContainersFor(playerUUID); - if (containers.isEmpty()) { - return new InspectPagePluginsContent("

  • " + actualServerName + " (No Data)
  • ", - "
    " + - "
    " + Html.CARD.parse("

    No Data (" + actualServerName + ")

    ") + - "
    "); - } - - String nav = "
  • " + actualServerName + " (Legacy)
  • "; - String tab = createTab(containers); - - return new InspectPagePluginsContent(nav, tab); - } - - private static String createTab(Map containers) { - StringBuilder tab = new StringBuilder(); - tab.append("
    "); - - List order = new ArrayList<>(containers.keySet()); - order.sort(new PluginDataNameComparator()); - - for (PluginData pluginData : order) { - InspectContainer container = containers.get(pluginData); - AnalysisPluginsTabContentCreator.appendThird(pluginData, container, tab); - } - - tab.append("
    "); - return tab.toString(); - } - - public void addTab(String nav, String html) { - pluginsTab.put(nav, new String[]{nav, html}); - } - - public void addTab(InspectPagePluginsContent content) { - pluginsTab.putAll(content.pluginsTab); - } - - public String[] getContents() { - if (pluginsTab.isEmpty()) { - return HtmlStructure.createInspectPageTabContentCalculating(); - } - - List order = new ArrayList<>(pluginsTab.values()); - // Sort serverNames alphabetically - order.sort(Comparator.comparing(name -> name[0])); - - StringBuilder nav = new StringBuilder(); - StringBuilder tabs = new StringBuilder(); - for (String[] tab : order) { - nav.append(tab[0]); - tabs.append(tab[1]); - } - return new String[]{nav.toString(), tabs.toString()}; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/Base64Util.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/Base64Util.java deleted file mode 100644 index b637f8e96..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/Base64Util.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities; - -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; - -/** - * Utility for performing Base64 operations. - * - * @author Rsl1122 - */ -public class Base64Util { - - /** - * Hides public constructor. - */ - private Base64Util() { - } - - public static String encodeBytes(byte[] bytes) { - return new String(Base64.getEncoder().encode(bytes)); - } - - public static String encode(String decoded) { - byte[] encoded = Base64.getEncoder().encode(decoded.getBytes()); - return new String(encoded); - } - - public static byte[] decodeBytes(String encoded) { - return Base64.getDecoder().decode(encoded.getBytes()); - } - - public static String decode(String encoded) { - byte[] decoded = Base64.getDecoder().decode(encoded.getBytes()); - return new String(decoded); - } - - public static List split(String encoded, long partLength) { - List split = new ArrayList<>(); - StringBuilder builder = new StringBuilder(); - long length = 0; - for (char c : encoded.toCharArray()) { - builder.append(c); - length++; - if (length >= partLength) { - split.add(builder.toString()); - builder = new StringBuilder(); - length = 0; - } - } - - // Add the last part even if it isn't full length. - if (length != 0) { - split.add(builder.toString()); - } - - return split; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java deleted file mode 100644 index 2dd51af50..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities; - -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.Sender; - -import java.io.Closeable; -import java.io.IOException; - -/** - * Utility method class containing various static methods. - * - * @author Rsl1122 - */ -public class MiscUtils { - - /** - * Constructor used to hide the public constructor - */ - private MiscUtils() { - throw new IllegalStateException("Utility class"); - } - - /** - * Get a players name that matches the given arguments or name of the sender. - * - * @param args Arguments of command. - * @param sender Sender of command - * @return Player name. - */ - public static String getPlayerName(String[] args, Sender sender) { - return getPlayerName(args, sender, Permissions.INSPECT_OTHER); - } - - /** - * Used by the inspect command. - * - * @param args Arguments of a command, must not be empty if console sender. - * @param sender Command sender - * @param perm Permission to use when checking. - * @return The name of the player (first argument or sender) or null if sender has no permission. - */ - public static String getPlayerName(String[] args, Sender sender, Permissions perm) { - String playerName; - boolean isConsole = !CommandUtils.isPlayer(sender); - if (isConsole) { - playerName = args[0]; - } else if (args.length > 0) { - if (sender.hasPermission(perm.getPermission())) { - playerName = args[0]; - } else if (args[0].equalsIgnoreCase(sender.getName())) { - playerName = sender.getName(); - } else { - return null; - } - } else { - playerName = sender.getName(); - } - return playerName; - } - - public static void close(Closeable... close) { - for (Closeable c : close) { - if (c != null) { - try { - c.close(); - } catch (IOException ignored) { - // Closing exceptions are ignored. - } - } - } - } - - public static void close(AutoCloseable... close) { - for (AutoCloseable c : close) { - if (c != null) { - try { - c.close(); - } catch (Exception ignore) { - // Closing exceptions are ignored. - } - } - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/PassEncryptUtil.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/PassEncryptUtil.java deleted file mode 100644 index e46ad8635..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/PassEncryptUtil.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities; - -import com.djrapitops.plan.api.exceptions.PassEncryptException; - -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.spec.InvalidKeySpecException; -import java.util.Base64; - -/** - * Password Encryption utility. - *

    - * https://github.com/defuse/password-hashing/blob/master/PasswordStorage.java - * - * @author Defuse - */ -public class PassEncryptUtil { - - private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1"; - // These constants may be changed without breaking existing hashes. - private static final int SALT_BYTE_SIZE = 24; - private static final int HASH_BYTE_SIZE = 18; - private static final int PBKDF2_ITERATIONS = 64000; - // These constants define the encoding and may not be changed. - private static final int HASH_SECTIONS = 5; - private static final int HASH_ALGORITHM_INDEX = 0; - private static final int ITERATION_INDEX = 1; - private static final int HASH_SIZE_INDEX = 2; - private static final int SALT_INDEX = 3; - private static final int PBKDF2_INDEX = 4; - - /** - * Constructor used to hide the public constructor - */ - private PassEncryptUtil() { - throw new IllegalStateException("Utility class"); - } - - public static String createHash(String password) throws CannotPerformOperationException { - return createHash(password.toCharArray()); - } - - private static String createHash(char[] password) throws CannotPerformOperationException { - // Generate a random salt - SecureRandom random = new SecureRandom(); - byte[] salt = new byte[SALT_BYTE_SIZE]; - random.nextBytes(salt); - - // Hash the password - byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE); - int hashSize = hash.length; - - // format: algorithm:iterations:hashSize:salt:hash - return "sha1:" - + PBKDF2_ITERATIONS - + ":" + hashSize - + ":" + toBase64(salt) - + ":" + toBase64(hash); - } - - public static boolean verifyPassword(String password, String correctHash) throws CannotPerformOperationException, InvalidHashException { - return verifyPassword(password.toCharArray(), correctHash); - } - - private static boolean verifyPassword(char[] password, String correctHash) throws CannotPerformOperationException, InvalidHashException { - // Decode the hash into its parameters - String[] params = correctHash.split(":"); - if (params.length != HASH_SECTIONS) { - throw new InvalidHashException( - "Fields are missing from the password hash." - ); - } - - // Currently, Java only supports SHA1. - if (!params[HASH_ALGORITHM_INDEX].equals("sha1")) { - throw new CannotPerformOperationException( - ); - } - - int iterations; - try { - iterations = Integer.parseInt(params[ITERATION_INDEX]); - } catch (NumberFormatException ex) { - throw new InvalidHashException( - "Could not parse the iteration count as an integer.", ex - ); - } - - if (iterations < 1) { - throw new InvalidHashException( - "Invalid number of iterations. Must be >= 1." - ); - } - - byte[] salt; - try { - salt = fromBase64(params[SALT_INDEX]); - } catch (IllegalArgumentException ex) { - throw new InvalidHashException( - "Base64 decoding of salt failed.", ex - ); - } - - byte[] hash; - try { - hash = fromBase64(params[PBKDF2_INDEX]); - } catch (IllegalArgumentException ex) { - throw new InvalidHashException( - "Base64 decoding of pbkdf2 output failed.", ex - ); - } - - int storedHashSize; - try { - storedHashSize = Integer.parseInt(params[HASH_SIZE_INDEX]); - } catch (NumberFormatException ex) { - throw new InvalidHashException( - "Could not parse the hash size as an integer.", ex - ); - } - - if (storedHashSize != hash.length) { - throw new InvalidHashException( - "Hash length doesn't match stored hash length." - ); - } - - // Compute the hash of the provided password, using the same salt, - // iteration count, and hash length - byte[] testHash = pbkdf2(password, salt, iterations, hash.length); - // Compare the hashes in constant time. The password is correct if - // both hashes match. - return slowEquals(hash, testHash); - } - - private static boolean slowEquals(byte[] a, byte[] b) { - int diff = a.length ^ b.length; - for (int i = 0; i < a.length && i < b.length; i++) { - diff |= a[i] ^ b[i]; - } - return diff == 0; - } - - private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes) throws CannotPerformOperationException { - try { - PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8); - SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM); - return skf.generateSecret(spec).getEncoded(); - } catch (NoSuchAlgorithmException ex) { - throw new CannotPerformOperationException( - "Hash algorithm not supported: " + PBKDF2_ALGORITHM, ex - ); - } catch (InvalidKeySpecException ex) { - throw new CannotPerformOperationException( - "Invalid key spec.", ex - ); - } - } - - private static byte[] fromBase64(String hex) { - return Base64.getDecoder().decode(hex); - } - - private static String toBase64(byte[] array) { - return Base64.getEncoder().encodeToString(array); - } - - @SuppressWarnings("serial") - public static class InvalidHashException extends PassEncryptException { - - InvalidHashException(String message) { - super(message); - } - - InvalidHashException(String message, Throwable source) { - super(message, source); - } - } - - @SuppressWarnings("serial") - public static class CannotPerformOperationException extends PassEncryptException { - - CannotPerformOperationException() { - super("Unsupported hash type."); - } - - CannotPerformOperationException(String message, Throwable source) { - super(message, source); - } - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Median.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Median.java deleted file mode 100644 index 92b3ee2b0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Median.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.analysis; - -import java.util.Collections; -import java.util.List; - -/** - * Math utility for calculating the median from Integer values. - * - * @param a {@code Number} object which implements {@code Comparable} (In general every standard Java number) - * @author Rsl1122 - */ -public class Median> { - - private final List values; - private int size; - - private Median(List values) { - this.values = values; - Collections.sort(values); - size = values.size(); - } - - /** - * Creates a Median instance - * - * @param list the input list - * @return an instance of {@code Median} for the List given - */ - public static > Median forList(List list) { - return new Median<>(list); - } - - public double calculate() { - if (values.isEmpty()) { - return -1; - } - if (size % 2 == 0) { - return calculateEven(); - } else { - return calculateOdd(); - } - } - - private double calculateEven() { - int half = size / 2; - double x1 = values.get(half).doubleValue(); - double x2 = values.get(half - 1).doubleValue(); - return (x1 + x2) / 2; - } - - private double calculateOdd() { - int half = size / 2; - return values.get(half).doubleValue(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/DateHolderRecentComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/DateHolderRecentComparator.java deleted file mode 100644 index a94d9dcdb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/DateHolderRecentComparator.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -import com.djrapitops.plan.data.store.objects.DateHolder; - -import java.util.Comparator; - -/** - * Compares DateHolder objects so that most recent is first. - * - * @author Rsl1122 - */ -public class DateHolderRecentComparator implements Comparator { - - @Override - public int compare(DateHolder one, DateHolder two) { - return Long.compare(two.getDate(), one.getDate()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/GeoInfoComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/GeoInfoComparator.java deleted file mode 100644 index 2cba61106..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/GeoInfoComparator.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -/** - * Comparator for comparing GeoInfo so that most recent is the first component. - * - * @author Rsl1122 - */ -public class GeoInfoComparator extends DateHolderRecentComparator { - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/LocaleEntryComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/LocaleEntryComparator.java deleted file mode 100644 index 759b269f8..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/LocaleEntryComparator.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -import com.djrapitops.plan.system.locale.Message; -import com.djrapitops.plan.system.locale.lang.Lang; - -import java.util.Comparator; -import java.util.Map; - -/** - * Compares Locale Map Entries and sorts them alphabetically according to the Enum Names. - * - * @author Rsl1122 - */ -public class LocaleEntryComparator implements Comparator> { - - @Override - public int compare(Map.Entry o1, Map.Entry o2) { - return String.CASE_INSENSITIVE_ORDER.compare(o1.getKey().getIdentifier(), o2.getKey().getIdentifier()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PieSliceComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PieSliceComparator.java deleted file mode 100644 index 191229eae..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PieSliceComparator.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -import com.djrapitops.plan.utilities.html.graphs.pie.PieSlice; - -import java.util.Comparator; - -/** - * Comparator for PieSlices to descending Percentage order. - * - * @author Rsl1122 - */ -public class PieSliceComparator implements Comparator { - - @Override - public int compare(PieSlice o1, PieSlice o2) { - return -Long.compare(o1.getY(), o2.getY()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PlayerContainerLastPlayedComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PlayerContainerLastPlayedComparator.java deleted file mode 100644 index 6080fdd11..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PlayerContainerLastPlayedComparator.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; - -import java.util.Comparator; - -/** - * Comparator for PlayerContainer so that most recently seen is first. - * - * @author Rsl1122 - */ -public class PlayerContainerLastPlayedComparator implements Comparator { - - @Override - public int compare(PlayerContainer playerOne, PlayerContainer playerTwo) { - return Long.compare( - playerTwo.getValue(PlayerKeys.LAST_SEEN).orElse(0L), - playerOne.getValue(PlayerKeys.LAST_SEEN).orElse(0L) - ); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PluginDataNameComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PluginDataNameComparator.java deleted file mode 100644 index 3d093c50f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PluginDataNameComparator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -import com.djrapitops.plan.data.plugin.PluginData; - -import java.util.Comparator; - -/** - * Comparator for PluginData for Alphabetical Name order. - * - * @author Rsl1122 - */ -@Deprecated -public class PluginDataNameComparator implements Comparator { - - @Override - public int compare(PluginData u1, PluginData u2) { - return u1.getSourcePlugin().compareTo(u2.getSourcePlugin()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PointComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PointComparator.java deleted file mode 100644 index db159e59c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/PointComparator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -import com.djrapitops.plan.utilities.html.graphs.line.Point; - -import java.util.Comparator; - -/** - * Comparator for Points for ascending x value order. - * - * @author Rsl1122 - */ -public class PointComparator implements Comparator { - - @Override - public int compare(Point o1, Point o2) { - return Double.compare(o1.getX(), o2.getX()); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/SessionStartComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/SessionStartComparator.java deleted file mode 100644 index fa00d8d2b..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/SessionStartComparator.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -/** - * Comparator for Sessions in descending start order (Most recent first). - * - * @author Rsl1122 - */ -public class SessionStartComparator extends DateHolderRecentComparator { - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/StringLengthComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/StringLengthComparator.java deleted file mode 100644 index 2cef63023..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/StringLengthComparator.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -import java.util.Comparator; - -/** - * Compares Strings and sorts them by length (Longest fist). - * - * @author Rsl1122 - */ -public class StringLengthComparator implements Comparator { - - @Override - public int compare(String o1, String o2) { - return -Long.compare(o1.length(), o2.length()); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/TPSComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/TPSComparator.java deleted file mode 100644 index 1c23f5328..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/TPSComparator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -import com.djrapitops.plan.data.container.TPS; - -import java.util.Comparator; - -/** - * Compares TPS objects so that earliest is first. - * - * @author Rsl1122 - */ -public class TPSComparator implements Comparator { - - @Override - public int compare(TPS o1, TPS o2) { - return Long.compare(o1.getDate(), o2.getDate()); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/WebUserComparator.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/WebUserComparator.java deleted file mode 100644 index 173bfced0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/comparators/WebUserComparator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.comparators; - -import com.djrapitops.plan.data.WebUser; - -import java.util.Comparator; - -/** - * Orders WebUsers in descending order by permission level. - * - * @author Rsl1122 - */ -public class WebUserComparator implements Comparator { - - @Override - public int compare(WebUser o1, WebUser o2) { - return Integer.compare(o2.getPermLevel(), o1.getPermLevel()); - } - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/file/FileWatcher.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/file/FileWatcher.java deleted file mode 100644 index 53eeced16..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/file/FileWatcher.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.file; - -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import com.djrapitops.plugin.utilities.Verify; - -import java.io.File; -import java.io.IOException; -import java.nio.file.*; -import java.util.HashSet; -import java.util.Set; - -import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; - -/** - * Class for watching files for changes. - * - * @author Rsl1122 - */ -public class FileWatcher extends Thread { - - private final ErrorHandler errorHandler; - - private volatile boolean running; - - private Path watchedPath; - private Set watchedFiles; - - public FileWatcher( - File folder, - ErrorHandler errorHandler - ) { - this(folder.toPath(), errorHandler); - } - - public FileWatcher( - Path watchedPath, - ErrorHandler errorHandler - ) { - this.errorHandler = errorHandler; - this.running = false; - this.watchedFiles = new HashSet<>(); - - - Verify.isTrue(watchedPath.toFile().isDirectory(), () -> new IllegalArgumentException("Given File " + watchedPath.toString() + " was not a folder.")); - - this.watchedPath = watchedPath; - } - - public void addToWatchlist(WatchedFile watchedFile) { - watchedFiles.remove(watchedFile); - watchedFiles.add(watchedFile); - } - - @Override - public void run() { - this.running = true; - try (WatchService watcher = FileSystems.getDefault().newWatchService()) { - watchedPath.register(watcher, ENTRY_MODIFY); - runLoop(watcher); - } catch (IOException e) { - errorHandler.log(L.ERROR, this.getClass(), e); - interrupt(); - } catch (InterruptedException e) { - interrupt(); - } - } - - private void runLoop(WatchService watcher) throws InterruptedException { - while (running) { - // Blocking operation - WatchKey key = watcher.take(); - - if (key == null) { - Thread.yield(); - continue; - } - - pollEvents(key); - } - } - - private void pollEvents(WatchKey key) { - for (WatchEvent event : key.pollEvents()) { - handleEvent(event); - if (!key.reset()) { - break; - } - } - } - - private void handleEvent(WatchEvent event) { - if (event.kind() != ENTRY_MODIFY) { - Thread.yield(); - } else { - @SuppressWarnings("unchecked") - Path modifiedFile = ((WatchEvent) event).context(); - actOnModification(watchedPath.resolve(modifiedFile)); - } - } - - private void actOnModification(Path modifiedFile) { - for (WatchedFile watchedFile : new HashSet<>(watchedFiles)) { - watchedFile.modified(modifiedFile); - } - } - - @Override - public void interrupt() { - running = false; - super.interrupt(); - } - - public boolean isRunning() { - return running; - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/file/WatchedFile.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/file/WatchedFile.java deleted file mode 100644 index 208a81580..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/file/WatchedFile.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.file; - -import com.djrapitops.plan.utilities.java.VoidFunction; - -import java.io.File; -import java.nio.file.Path; -import java.util.Objects; - -/** - * File or Path with a function that is called if the file is modified. - * - * @author Rsl1122 - */ -public class WatchedFile { - - private final Path watchedPath; - private final VoidFunction onChange; - - public WatchedFile(File file, VoidFunction onChange) { - this(file.toPath(), onChange); - } - - public WatchedFile(Path path, VoidFunction onChange) { - this.watchedPath = path; - this.onChange = onChange; - } - - public void modified(Path modifiedPath) { - if (watchedPath.equals(modifiedPath)) { - onChange.apply(); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - WatchedFile that = (WatchedFile) o; - return Objects.equals(watchedPath, that.watchedPath); - } - - @Override - public int hashCode() { - return Objects.hash(watchedPath); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/DecimalFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/DecimalFormatter.java deleted file mode 100644 index ba289a4c9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/DecimalFormatter.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting; - -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.FormatSettings; - -import java.text.DecimalFormat; - -/** - * Formatter for decimal points that depends on settings. - * - * @author Rsl1122 - */ -public class DecimalFormatter implements Formatter { - - private final PlanConfig config; - - public DecimalFormatter(PlanConfig config) { - this.config = config; - } - - @Override - public String apply(Double value) { - // DecimalFormat is initialized here because config is not fully enabled in the constructor - return new DecimalFormat(config.get(FormatSettings.DECIMALS)).format(value); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/EntityNameFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/EntityNameFormatter.java deleted file mode 100644 index 1c062e591..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/EntityNameFormatter.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting; - -import com.djrapitops.plugin.utilities.Format; - -/** - * Formatter for entity names, that capitalizes the first word and removes symbols and numbers. - * - * @author Rsl1122 - */ -public class EntityNameFormatter implements Formatter { - - @Override - public String apply(String name) { - return new Format(name).removeNumbers().removeSymbols().capitalize().toString(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/Formatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/Formatter.java deleted file mode 100644 index f3ad0b0e1..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/Formatter.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting; - -import java.util.function.Function; - -/** - * Interface for formatting a value into a String. - * - * @author Rsl1122 - */ -public interface Formatter extends Function { - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/Formatters.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/Formatters.java deleted file mode 100644 index 45f513291..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/Formatters.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting; - -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.utilities.formatting.time.*; - -import javax.inject.Inject; -import javax.inject.Singleton; - -/** - * Factory for new instances of different {@link Formatter}s. - * - * @author Rsl1122 - */ -@Singleton -public class Formatters { - - private final DateHolderFormatter yearFormatter; - private final DateHolderFormatter dayFormatter; - private final DateHolderFormatter secondFormatter; - private final DateHolderFormatter clockFormatter; - private final DateHolderFormatter iso8601NoClockFormatter; - - private final YearFormatter yearLongFormatter; - private final DayFormatter dayLongFormatter; - private final SecondFormatter secondLongFormatter; - private final ClockFormatter clockLongFormatter; - private final ISO8601NoClockFormatter iso8601NoClockLongFormatter; - - private final TimeAmountFormatter timeAmountFormatter; - - private final DecimalFormatter decimalFormatter; - private final PercentageFormatter percentageFormatter; - - @Inject - public Formatters(PlanConfig config, Locale locale) { - yearLongFormatter = new YearFormatter(config, locale); - dayLongFormatter = new DayFormatter(config, locale); - clockLongFormatter = new ClockFormatter(config, locale); - secondLongFormatter = new SecondFormatter(config, locale); - iso8601NoClockLongFormatter = new ISO8601NoClockFormatter(config, locale); - - yearFormatter = new DateHolderFormatter(yearLongFormatter); - dayFormatter = new DateHolderFormatter(dayLongFormatter); - secondFormatter = new DateHolderFormatter(secondLongFormatter); - clockFormatter = new DateHolderFormatter(clockLongFormatter); - iso8601NoClockFormatter = new DateHolderFormatter(iso8601NoClockLongFormatter); - - timeAmountFormatter = new TimeAmountFormatter(config); - - decimalFormatter = new DecimalFormatter(config); - percentageFormatter = new PercentageFormatter(decimalFormatter); - - } - - public Formatter year() { - return this.yearFormatter; - } - - public Formatter yearLong() { - return yearLongFormatter; - } - - public Formatter day() { - return dayFormatter; - } - - public Formatter dayLong() { - return dayLongFormatter; - } - - public Formatter second() { - return secondFormatter; - } - - public Formatter secondLong() { - return secondLongFormatter; - } - - public Formatter clock() { - return clockFormatter; - } - - public Formatter clockLong() { - return clockLongFormatter; - } - - public Formatter iso8601NoClock() { - return iso8601NoClockFormatter; - } - - public Formatter iso8601NoClockLong() { - return iso8601NoClockLongFormatter; - } - - public Formatter timeAmount() { - return timeAmountFormatter; - } - - public Formatter percentage() { - return percentageFormatter; - } - - public Formatter decimals() { - return decimalFormatter; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/ItemNameFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/ItemNameFormatter.java deleted file mode 100644 index 14c404a3f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/ItemNameFormatter.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting; - -import com.djrapitops.plugin.utilities.Format; -import org.apache.commons.text.TextStringBuilder; - -import java.util.Arrays; - -/** - * Formatter for Item names, that capitalizes each part and separates them with spaces instead of underscores. - * - * @author Rsl1122 - */ -public class ItemNameFormatter implements Formatter { - - @Override - public String apply(String name) { - String[] parts = name.split("_"); - TextStringBuilder builder = new TextStringBuilder(); - builder.appendWithSeparators(Arrays.stream(parts).map(part -> new Format(part).capitalize()).iterator(), " "); - return builder.toString(); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/PercentageFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/PercentageFormatter.java deleted file mode 100644 index cdd9966a9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/PercentageFormatter.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting; - -/** - * Formatter for percentages. - * - * @author Rsl1122 - */ -public class PercentageFormatter implements Formatter { - - private final Formatter formatter; - - public PercentageFormatter(Formatter formatter) { - this.formatter = formatter; - } - - @Override - public String apply(Double value) { - return value >= 0 ? formatter.apply(value * 100.0) + "%" : "-"; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/PlaceholderReplacer.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/PlaceholderReplacer.java deleted file mode 100644 index 651cfdbe9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/PlaceholderReplacer.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting; - -import com.djrapitops.plan.data.store.PlaceholderKey; -import com.djrapitops.plan.data.store.containers.DataContainer; -import org.apache.commons.text.StringSubstitutor; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Objects; - -/** - * Formatter for replacing ${placeholder} values inside strings. - * - * @author Rsl1122 - */ -public class PlaceholderReplacer extends HashMap implements Formatter { - - public void addPlaceholderFrom(DataContainer container, PlaceholderKey key) { - put(key.getPlaceholder(), container.getValue(key).map(Objects::toString).orElse("Missing value " + key.getPlaceholder())); - } - - public void addAllPlaceholdersFrom(DataContainer container, PlaceholderKey... keys) { - for (PlaceholderKey key : keys) { - addPlaceholderFrom(container, key); - } - } - - public void addPlaceholderFrom(DataContainer container, Formatter formatter, PlaceholderKey key) { - if (!container.supports(key)) { - return; - } - put(key.getPlaceholder(), container.getFormattedUnsafe(key, formatter)); - } - - public void addAllPlaceholdersFrom(DataContainer container, Formatter formatter, PlaceholderKey... keys) { - for (PlaceholderKey key : keys) { - addPlaceholderFrom(container, formatter, key); - } - } - - @Override - public String apply(String string) { - StringSubstitutor sub = new StringSubstitutor(this); - sub.setEnableSubstitutionInVariables(true); - return sub.replace(string); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/ClockFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/ClockFormatter.java deleted file mode 100644 index 0aff0214d..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/ClockFormatter.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting.time; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.FormatSettings; - -/** - * Formatter for a timestamp that only includes a clock. - * - * @author Rsl1122 - */ -public class ClockFormatter extends DateFormatter { - - public ClockFormatter(PlanConfig config, Locale locale) { - super(config, locale); - } - - @Override - public String apply(Long date) { - return date > 0 ? format(date) : "-"; - } - - private String format(Long date) { - String format = config.get(FormatSettings.DATE_CLOCK); - - return format(date, format); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateFormatter.java deleted file mode 100644 index df692f256..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateFormatter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting.time; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.GenericLang; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.FormatSettings; -import com.djrapitops.plan.system.settings.paths.PluginSettings; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.utilities.formatting.Formatter; - -import java.text.SimpleDateFormat; -import java.util.TimeZone; -import java.util.concurrent.TimeUnit; - -/** - * Abstract formatter for a timestamp. - * - * @author Rsl1122 - */ -public abstract class DateFormatter implements Formatter { - - protected final PlanConfig config; - protected final Locale locale; - - public DateFormatter(PlanConfig config, Locale locale) { - this.config = config; - this.locale = locale; - } - - @Override - public abstract String apply(Long value); - - protected String format(long epochMs, String format) { - boolean useServerTime = config.isTrue(TimeSettings.USE_SERVER_TIME); - String localeSetting = config.get(PluginSettings.LOCALE); - java.util.Locale usedLocale = "default".equalsIgnoreCase(localeSetting) - ? java.util.Locale.ENGLISH - : java.util.Locale.forLanguageTag(localeSetting); - SimpleDateFormat dateFormat = new SimpleDateFormat(format, usedLocale); - TimeZone timeZone = useServerTime ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT"); - dateFormat.setTimeZone(timeZone); - return dateFormat.format(epochMs); - } - - protected String replaceRecentDays(long epochMs, String format) { - return replaceRecentDays(epochMs, format, config.get(FormatSettings.DATE_RECENT_DAYS_PATTERN)); - } - - protected String replaceRecentDays(long epochMs, String format, String pattern) { - long now = System.currentTimeMillis(); - - boolean useServerTime = config.isTrue(TimeSettings.USE_SERVER_TIME); - TimeZone timeZone = useServerTime ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT"); - int offset = timeZone.getOffset(epochMs); - - // Time since Start of day: UTC + Timezone % 24 hours - long fromStartOfDay = (now + offset) % TimeUnit.DAYS.toMillis(1L); - if (epochMs > now - fromStartOfDay) { - format = format.replace(pattern, locale.getString(GenericLang.TODAY)); - } else if (epochMs > now - TimeUnit.DAYS.toMillis(1L) - fromStartOfDay) { - format = format.replace(pattern, locale.getString(GenericLang.YESTERDAY)); - } else if (epochMs > now - TimeUnit.DAYS.toMillis(5L)) { - format = format.replace(pattern, "EEEE"); - } - return format; - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateHolderFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateHolderFormatter.java deleted file mode 100644 index 66056e393..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateHolderFormatter.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting.time; - -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.utilities.formatting.Formatter; - -/** - * Formatter for a DateHolder object that uses a different formatter. - * - * @author Rsl1122 - */ -public class DateHolderFormatter implements Formatter { - - private final Formatter formatter; - - public DateHolderFormatter(Formatter formatter) { - this.formatter = formatter; - } - - @Override - public String apply(DateHolder dateHolder) { - return formatter.apply(dateHolder.getDate()); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DayFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DayFormatter.java deleted file mode 100644 index 60ff58052..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/DayFormatter.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting.time; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.FormatSettings; - -/** - * Formatter for a timestamp which includes days as the smallest entry. - * - * @author Rsl1122 - */ -public class DayFormatter extends DateFormatter { - - public DayFormatter(PlanConfig config, Locale locale) { - super(config, locale); - } - - @Override - public String apply(Long date) { - return date > 0 ? format(date) : "-"; - } - - private String format(Long date) { - String format = "MMMMM d"; - - if (config.isTrue(FormatSettings.DATE_RECENT_DAYS)) { - format = replaceRecentDays(date, format, "MMMMM"); - } - - return format(date, format); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/ISO8601NoClockFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/ISO8601NoClockFormatter.java deleted file mode 100644 index 26ad793ed..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/ISO8601NoClockFormatter.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting.time; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; - -/** - * Formatter for a timestamp in ISO-8601 format without the clock. - * - * @author Rsl1122 - */ -public class ISO8601NoClockFormatter extends DateFormatter { - - public ISO8601NoClockFormatter(PlanConfig config, Locale locale) { - super(config, locale); - } - - @Override - public String apply(Long date) { - return date > 0 ? format(date) : "-"; - } - - private String format(Long date) { - String format = "yyyy-MM-dd"; - - return format(date, format); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/SecondFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/SecondFormatter.java deleted file mode 100644 index e77dc8ceb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/SecondFormatter.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting.time; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.FormatSettings; - -/** - * Formatter for timestamp which includes seconds as the smallest entry. - * - * @author Rsl1122 - */ -public class SecondFormatter extends DateFormatter { - - public SecondFormatter(PlanConfig config, Locale locale) { - super(config, locale); - } - - @Override - public String apply(Long date) { - return date > 0 ? format(date) : "-"; - } - - private String format(Long date) { - String format = config.get(FormatSettings.DATE_FULL); - - if (config.isTrue(FormatSettings.DATE_RECENT_DAYS)) { - format = replaceRecentDays(date, format); - } - - return format(date, format); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/TimeAmountFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/TimeAmountFormatter.java deleted file mode 100644 index 1daeacc49..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/TimeAmountFormatter.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting.time; - -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.FormatSettings; -import com.djrapitops.plan.utilities.formatting.Formatter; -import org.apache.commons.lang3.StringUtils; - -/** - * Formatter for time amount in milliseconds. - * - * @author Rsl1122 - */ -public class TimeAmountFormatter implements Formatter { - - // Placeholders for the config settings - private static final String ZERO_PH = "%zero%"; - private static final String SECONDS_PH = "%seconds%"; - private static final String MINUTES_PH = "%minutes%"; - private static final String HOURS_PH = "%hours%"; - private static final String DAYS_PH = "%days%"; - private static final String MONTHS_PH = "%months%"; - private static final String YEARS_PH = "%years%"; - - private final PlanConfig config; - - public TimeAmountFormatter(PlanConfig config) { - this.config = config; - } - - @Override - public String apply(Long ms) { - if (ms <= 0) { - return "-"; - } - StringBuilder builder = new StringBuilder(); - long x = ms / 1000; - long seconds = x % 60; - x /= 60; - long minutes = x % 60; - x /= 60; - long hours = x % 24; - x /= 24; - long days = x % 365; - long months = (days - days % 30) / 30; - days -= months * 30; - x /= 365; - long years = x; - - appendYears(builder, years); - appendMonths(builder, months); - appendDays(builder, days); - - String hourFormat = config.get(FormatSettings.HOURS); - String minuteFormat = config.get(FormatSettings.MINUTES); - String secondFormat = config.get(FormatSettings.SECONDS); - - appendHours(builder, hours, hourFormat); - appendMinutes(builder, minutes, hours, hourFormat, minuteFormat); - appendSeconds(builder, seconds, minutes, hours, hourFormat, minuteFormat, secondFormat); - - String formattedTime = StringUtils.remove(builder.toString(), ZERO_PH); - if (formattedTime.isEmpty()) { - return config.get(FormatSettings.ZERO_SECONDS); - } - return formattedTime; - } - - private void appendHours(StringBuilder builder, long hours, String fHours) { - if (hours != 0) { - String h = fHours.replace(HOURS_PH, String.valueOf(hours)); - if (h.contains(ZERO_PH) && String.valueOf(hours).length() == 1) { - builder.append('0'); - } - builder.append(h); - } - } - - private void appendMinutes(StringBuilder builder, long minutes, long hours, String fHours, String fMinutes) { - if (minutes != 0) { - String m = fMinutes.replace(MINUTES_PH, String.valueOf(minutes)); - if (hours == 0 && m.contains(HOURS_PH)) { - builder.append(fHours.replace(ZERO_PH, "0").replace(HOURS_PH, "0")); - m = m.replace(HOURS_PH, ""); - } - m = m.replace(HOURS_PH, ""); - if (m.contains(ZERO_PH) && String.valueOf(minutes).length() == 1) { - builder.append('0'); - } - builder.append(m); - } - } - - private void appendSeconds(StringBuilder builder, long seconds, long minutes, long hours, String fHours, String fMinutes, String fSeconds) { - if (seconds != 0 || fSeconds.contains(ZERO_PH)) { - String s = fSeconds.replace(SECONDS_PH, String.valueOf(seconds)); - if (minutes == 0 && s.contains(MINUTES_PH)) { - if (hours == 0 && fMinutes.contains(HOURS_PH)) { - builder.append(fHours.replace(ZERO_PH, "0").replace(HOURS_PH, "0")); - } - builder.append(fMinutes.replace(HOURS_PH, "").replace(ZERO_PH, "0").replace(MINUTES_PH, "0")); - } - s = s.replace(MINUTES_PH, ""); - if (s.contains(ZERO_PH) && String.valueOf(seconds).length() == 1) { - builder.append('0'); - } - builder.append(s); - } - } - - private void appendDays(StringBuilder builder, long days) { - String singular = config.get(FormatSettings.DAY); - String plural = config.get(FormatSettings.DAYS); - appendValue(builder, days, singular, plural, DAYS_PH); - } - - private void appendMonths(StringBuilder builder, long months) { - String singular = config.get(FormatSettings.MONTH); - String plural = config.get(FormatSettings.MONTHS); - - appendValue(builder, months, singular, plural, MONTHS_PH); - } - - private void appendYears(StringBuilder builder, long years) { - String singular = config.get(FormatSettings.YEAR); - String plural = config.get(FormatSettings.YEARS); - - appendValue(builder, years, singular, plural, YEARS_PH); - } - - private void appendValue(StringBuilder builder, long amount, String singular, String plural, String replace) { - if (amount != 0) { - if (amount == 1) { - builder.append(singular); - } else { - builder.append(plural.replace(replace, String.valueOf(amount))); - } - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/YearFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/YearFormatter.java deleted file mode 100644 index 994680cb9..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/formatting/time/YearFormatter.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.formatting.time; - -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.FormatSettings; - -/** - * Formatter for a timestamp which includes year, but not seconds. - * - * @author Rsl1122 - */ -public class YearFormatter extends DateFormatter { - - public YearFormatter(PlanConfig config, Locale locale) { - super(config, locale); - } - - @Override - public String apply(Long date) { - return date > 0 ? format(date) : "-"; - } - - private String format(Long date) { - String format = config.get(FormatSettings.DATE_NO_SECONDS); - - if (config.isTrue(FormatSettings.DATE_RECENT_DAYS)) { - format = replaceRecentDays(date, format); - } - return format(date, format); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/Html.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/Html.java deleted file mode 100644 index 895516579..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/Html.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html; - -import org.apache.commons.text.StringSubstitutor; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -/** - * @author Rsl1122 - */ -public enum Html { - - COLOR_0(""), - COLOR_1(""), - COLOR_2(""), - COLOR_3(""), - COLOR_4(""), - COLOR_5(""), - COLOR_6(""), - COLOR_7(""), - COLOR_8(""), - COLOR_9(""), - COLOR_A(""), - COLOR_B(""), - COLOR_C(""), - COLOR_D(""), - COLOR_E(""), - COLOR_F(""), - - /** - * @deprecated Use com.djrapitops.plan.utilities.html.icon.Icon instead - */ - @Deprecated - FONT_AWESOME_ICON(""), - /** - * @deprecated Use com.djrapitops.plan.utilities.html.icon.Icon instead - */ - @Deprecated - FA_COLORED_ICON(""), - SPAN("${0}"), - BUTTON("${1}"), - BUTTON_CLASS("class=\"button\""), - LINK("${1}"), - LINK_A("${1}"), - LINK_TOOLTIP("${1}"), - LINK_EXTERNAL("${1}"), - LINK_CLASS("class=\"link\""), - IMG(""), - - PARAGRAPH("

    ${0}

    "), - HEADER("

    ${0}

    "), - HEADER_2("

    ${0}

    "), - - DIV_W_CLASS("
    ${1}
    "), - DIV_W_CLASS_STYLE("
    ${2}
    "), - - ROW("
    ${0}
    "), - CARD("
    ${0}
    "), - BODY("
    ${0}
    "), - PANEL("
    ${0}
    "), - PANEL_BODY("
    ${0}
    "), - HELP_BUBBLE(""), - - TABLE_END("
    "), - TABLE(""), - TABLE_SCROLL("
    "), - TABLE_JQUERY("
    "), - TABLE_COLORED("
    "), - TABLE_HEAD("${0}"), - TABLE_BODY("${0}"), - TABLE_START_2("
    "), - TABLE_START_3("
    ${0}${1}
    "), - TABLE_START_4("
    ${0}${1}${2}
    "), - TABLELINE_2(""), - TABLELINE_3(""), - TABLELINE_4(""), - TABLELINE_PLAYERS("" + ""), - TABLELINE_PLAYERS_PLAYERS_PAGE("" + ""), - TABLELINE_3_CUSTOMKEY(""), - TABLELINE_3_CUSTOMKEY_1(""); - - private final String html; - - Html(String html) { - this.html = html; - } - - /** - * @return The HTML String - */ - public String parse() { - return html; - } - - /** - * Changes Minecraft color codes to HTML span elements with correct color class assignments. - * - * @param string String to replace Minecraft color codes from - * @return String with span elements. - */ - public static String swapColorCodesToSpan(String string) { - Html[] replacer = new Html[]{ - Html.COLOR_0, Html.COLOR_1, Html.COLOR_2, Html.COLOR_3, - Html.COLOR_4, Html.COLOR_5, Html.COLOR_6, Html.COLOR_7, - Html.COLOR_8, Html.COLOR_9, Html.COLOR_A, Html.COLOR_B, - Html.COLOR_C, Html.COLOR_D, Html.COLOR_E, Html.COLOR_F - }; - Map colorMap = new HashMap<>(); - - for (Html html : replacer) { - colorMap.put(Character.toLowerCase(html.name().charAt(6)), html.parse()); - colorMap.put('k', ""); - colorMap.put('l', ""); - colorMap.put('m', ""); - colorMap.put('n', ""); - colorMap.put('o', ""); - } - - StringBuilder result = new StringBuilder(string.length()); - String[] split = string.split("§"); - // Skip first part if it does not start with § - boolean skipFirst = !string.startsWith("§"); - - int placedSpans = 0; - for (String part : split) { - if (part.isEmpty()) { - continue; - } - if (skipFirst) { - result.append(part); - skipFirst = false; - continue; - } - - char colorChar = part.charAt(0); - if (colorChar == 'r') { - appendEndTags(result, placedSpans); - placedSpans = 0; // Colors were reset - result.append(part.substring(1)); - continue; - } - - String replacement = colorMap.get(colorChar); - if (replacement != null) { - result.append(replacement).append(part.substring(1)); - - if (!replacement.isEmpty()) { - placedSpans++; - } - } else { - result.append(part); - } - } - - appendEndTags(result, placedSpans); - - return result.toString(); - } - - private static void appendEndTags(StringBuilder result, int placedSpans) { - for (int i = 0; i < placedSpans; i++) { - result.append(""); - } - } - - /** - * @param replacements The replacement Strings - * @return The parsed HTML String - */ - public String parse(Serializable... replacements) { - Map replaceMap = new HashMap<>(); - - for (int i = 0; i < replacements.length; i++) { - replaceMap.put(String.valueOf(i), replacements[i]); - } - - StringSubstitutor sub = new StringSubstitutor(replaceMap); - sub.setEnableSubstitutionInVariables(false); - return sub.replace(html); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java deleted file mode 100644 index fad561be7..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html; - -import com.djrapitops.plan.utilities.html.icon.Color; -import com.djrapitops.plan.utilities.html.icon.Icon; -import com.djrapitops.plan.utilities.html.icon.Icons; -import org.apache.commons.text.TextStringBuilder; - -/** - * Class for parsing layout components of the websites. - * - * @author Rsl1122 - */ -public class HtmlStructure { - - public static String separateWithDots(String... elements) { - TextStringBuilder builder = new TextStringBuilder(); - builder.appendWithSeparators(elements, " • "); - return builder.toString(); - } - - public static String createDotList(String... elements) { - if (elements.length == 0) { - return ""; - } - StringBuilder builder = new StringBuilder(); - for (String element : elements) { - if (element.isEmpty()) { - continue; - } - builder.append("• "); - builder.append(element); - builder.append("
    "); - } - return builder.toString(); - } - - @Deprecated - public static String[] createInspectPageTabContentCalculating() { - String tab = "
    " + - "
    " + - "
    " + - "
    " + - "

    Plugin Data

    " + - "
    " + - "

    Calculating Plugins tab, refresh (F5) shortly..

    " + - "
    " + - "
    "; - return new String[]{"
  • Calculating... Refresh shortly
  • ", tab}; - } - - public static String playerStatus(boolean online, boolean banned, boolean op) { - StringBuilder html = new StringBuilder("

    "); - if (online) { - html.append(Icon.called("circle").of(Color.GREEN)).append(" Online"); - } else { - html.append(Icon.called("circle").of(Color.RED)).append(" Offline"); - } - html.append("

    "); - if (op) { - html.append("

    ").append(Icons.OPERATOR).append(" Operator

    "); - } - if (banned) { - html.append("

    ").append(Icons.BANNED).append(" Banned

    "); - } - return html.toString(); - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java deleted file mode 100644 index 870087f87..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html; - -/** - * @author Rsl1122 - */ -public class HtmlUtils { - - /** - * Constructor used to hide the public constructor - */ - private HtmlUtils() { - throw new IllegalStateException("Utility class"); - } - - /** - * Attempts to remove XSS components. - * - * @param string String to remove XSS components from - * @return String but with the components removed - */ - public static String removeXSS(String string) { - return string.replace("", "").replace("", "").replace("" + - ""; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java deleted file mode 100644 index b0ca88385..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.structure; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.utilities.comparators.SessionStartComparator; -import com.djrapitops.plan.utilities.formatting.Formatter; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -/** - * Utility class for creating recent login list html. - *

    - * This item can be seen on the Information tab on Server page. - * - * @author Rsl1122 - */ -public class RecentLoginList { - - private final List players; - - private final Formatter secondLongFormatter; - - public RecentLoginList(List players, Formatter secondLongFormatter) { - this.players = players; - this.secondLongFormatter = secondLongFormatter; - } - - public String toHtml() { - List recentLogins = getMostRecentLogins(); - - if (recentLogins.isEmpty()) { - return "

  • No Recent Logins
  • "; - } - - StringBuilder html = new StringBuilder(); - int i = 0; - for (RecentLogin recentLogin : recentLogins) { - if (i >= 20) { - break; - } - - String name = recentLogin.name; - String url = PlanAPI.getInstance().getPlayerInspectPageLink(name); - boolean isNew = recentLogin.isNew; - String start = secondLongFormatter.apply(recentLogin.date); - - html.append("
  • ").append(name).append("").append(start).append("
  • "); - - i++; - } - - return html.toString(); - } - - private List getMostRecentLogins() { - List recentLogins = new ArrayList<>(); - for (PlayerContainer player : players) { - if (!player.supports(PlayerKeys.NAME) - || !player.supports(PlayerKeys.SESSIONS)) { - continue; - } - String name = player.getUnsafe(PlayerKeys.NAME); - long registerDate = player.getValue(PlayerKeys.REGISTERED).orElse(0L); - - List sessions = player.getValue(PlayerKeys.SESSIONS).orElse(Collections.emptyList()); - if (sessions.isEmpty()) { - continue; - } - sessions.sort(new SessionStartComparator()); - Session session = sessions.get(0); - - if (!session.supports(SessionKeys.START)) { - continue; - } - long mostRecentStart = session.getUnsafe(SessionKeys.START); - boolean isFirstSession = Math.abs(registerDate - mostRecentStart) < TimeUnit.SECONDS.toMillis(10L); - recentLogins.add(new RecentLogin(mostRecentStart, isFirstSession, name)); - } - return recentLogins; - } - - class RecentLogin { - final long date; - final boolean isNew; - final String name; - - RecentLogin(long date, boolean isNew, String name) { - this.date = date; - this.isNew = isNew; - this.name = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof RecentLogin)) return false; - RecentLogin that = (RecentLogin) o; - return date == that.date && - isNew == that.isNew && - Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hash(date, isNew, name); - } - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java deleted file mode 100644 index 2f052c905..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.structure; - -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PerServerKeys; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.graphs.Graphs; -import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; -import com.djrapitops.plan.utilities.html.icon.Color; -import com.djrapitops.plan.utilities.html.icon.Icon; -import com.djrapitops.plan.utilities.html.icon.Icons; -import com.djrapitops.plugin.utilities.Format; - -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -/** - * HTML utility class for creating a Server Accordion. - * - * @author Rsl1122 - */ -public class ServerAccordion extends Accordion { - - private final StringBuilder viewScript; - - private final Map serverNames; - private PerServerContainer perServer; - - private final Theme theme; - private final Graphs graphs; - private final Formatter yearLongFormatter; - private final Formatter timeAmountFormatter; - - public ServerAccordion( - PlayerContainer container, Map serverNames, - Theme theme, - Graphs graphs, - Formatter yearLongFormatter, - Formatter timeAmountFormatter - ) { - super("server_accordion"); - this.theme = theme; - this.graphs = graphs; - this.yearLongFormatter = yearLongFormatter; - this.timeAmountFormatter = timeAmountFormatter; - - viewScript = new StringBuilder(); - - this.serverNames = serverNames; - Optional perServerData = container.getValue(PlayerKeys.PER_SERVER); - if (perServerData.isPresent()) { - perServer = perServerData.get(); - } else { - return; - } - - addElements(); - } - - public String toViewScript() { - return viewScript.toString(); - } - - private void addElements() { - int i = 0; - - for (Map.Entry entry : perServer.entrySet()) { - UUID serverUUID = entry.getKey(); - DataContainer container = entry.getValue(); - String serverName = serverNames.getOrDefault(serverUUID, "Unknown"); - WorldTimes worldTimes = container.getValue(PerServerKeys.WORLD_TIMES).orElse(new WorldTimes()); - SessionsMutator sessionsMutator = SessionsMutator.forContainer(container); - - boolean banned = container.getValue(PerServerKeys.BANNED).orElse(false); - boolean operator = container.getValue(PerServerKeys.OPERATOR).orElse(false); - long registered = container.getValue(PerServerKeys.REGISTERED).orElse(0L); - - long playtime = sessionsMutator.toPlaytime(); - long afkTime = sessionsMutator.toAfkTime(); - int sessionCount = sessionsMutator.count(); - long sessionMedian = sessionsMutator.toMedianSessionLength(); - long longestSession = sessionsMutator.toLongestSessionLength(); - - long mobKills = sessionsMutator.toMobKillCount(); - long playerKills = sessionsMutator.toPlayerKillCount(); - long deaths = sessionsMutator.toDeathCount(); - - String play = timeAmountFormatter.apply(playtime); - String afk = timeAmountFormatter.apply(afkTime); - String median = timeAmountFormatter.apply(sessionMedian); - String longest = timeAmountFormatter.apply(longestSession); - - String sanitizedServerName = new Format(serverName) - .removeSymbols() - .removeWhitespace().toString() + i; - String htmlID = "server_" + sanitizedServerName; - - String worldId = "worldPieServer" + sanitizedServerName; - - WorldPie worldPie = graphs.pie().worldPie(worldTimes); - - String title = serverName + "" + play + ""; - - String leftSide = new AccordionElementContentBuilder() - .addRowBold(Icons.OPERATOR, "Operator", operator ? "Yes" : "No") - .addRowBold(Icons.BANNED, "Banned", banned ? "Yes" : "No") - .addRowBold(Icon.called("user-plus").of(Color.LIGHT_GREEN), "Registered", yearLongFormatter.apply(registered)) - .addBreak() - .addRowBold(Icons.SESSION_COUNT, "Sessions", sessionCount) - .addRowBold(Icons.PLAYTIME, "Server Playtime", play) - .addRowBold(Icons.AFK_LENGTH, "Time AFK", afk) - .addRowBold(Icons.SESSION_LENGTH, "Longest Session", longest) - .addRowBold(Icons.SESSION_LENGTH, "Session Median", median) - .addBreak() - .addRowBold(Icons.PLAYER_KILLS, "Player Kills", playerKills) - .addRowBold(Icons.MOB_KILLS, "Mob Kills", mobKills) - .addRowBold(Icons.DEATHS, "Deaths", deaths) - .toHtml(); - - String rightSide = "
    " + - ""; - - addElement(new AccordionElement(htmlID, title) - .setColor(theme.getValue(ThemeVal.PARSED_SERVER_ACCORDION)) - .setLeftSide(leftSide) - .setRightSide(rightSide)); - - viewScript.append("worldPie(") - .append(worldId).append(", ") - .append(worldId).append("series, ") - .append(worldId).append("gmseries") - .append(");"); - - i++; - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java deleted file mode 100644 index d4c57c874..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.structure; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.system.settings.config.WorldAliasSettings; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.HtmlStructure; -import com.djrapitops.plan.utilities.html.graphs.Graphs; -import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; -import com.djrapitops.plan.utilities.html.icon.Icons; -import com.djrapitops.plan.utilities.html.tables.HtmlTables; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.function.Supplier; - -/** - * Utility for creating Session accordion html and javascript from Session objects. - * - * @author Rsl1122 - * @see com.djrapitops.plan.data.container.Session for object - */ -public class SessionAccordion extends Accordion { - - private final boolean forPlayer; - private final List sessions; - private final Supplier> serverNamesSupplier; - private final Supplier> playerNamesSupplier; - - private final StringBuilder viewScript; - private final boolean appendWorldPercentage; - private final int maxSessions; - - private final WorldAliasSettings worldAliasSettings; - private final Theme theme; - private final Graphs graphs; - private final HtmlTables tables; - private final Formatter yearFormatter; - private final Formatter timeAmountFormatter; - - SessionAccordion(boolean forPlayer, List sessions, - Supplier> serverNamesSupplier, - Supplier> playerNamesSupplier, - boolean appendWorldPercentage, - int maxSessions, - WorldAliasSettings worldAliasSettings, - Theme theme, - Graphs graphs, - HtmlTables tables, - Formatter yearFormatter, - Formatter timeAmountFormatter - ) { - super("session_accordion"); - - this.forPlayer = forPlayer; - this.sessions = sessions; - this.serverNamesSupplier = serverNamesSupplier; - this.playerNamesSupplier = playerNamesSupplier; - this.appendWorldPercentage = appendWorldPercentage; - this.maxSessions = maxSessions; - this.worldAliasSettings = worldAliasSettings; - this.theme = theme; - this.graphs = graphs; - this.tables = tables; - this.yearFormatter = yearFormatter; - this.timeAmountFormatter = timeAmountFormatter; - viewScript = new StringBuilder(); - - addElements(); - } - - public String toViewScript() { - return viewScript.toString(); - } - - private void addElements() { - if (forPlayer) { - addElementsForPlayer(); - } else { - addElementsForServer(); - } - // Requires refactoring of Session object to contain information about player and server - } - - private void addElementsForServer() { - Map serverNames = serverNamesSupplier.get(); - Map playerNames = playerNamesSupplier.get(); - sessions.sort(new DateHolderRecentComparator()); - - int i = 0; - for (Session session : sessions) { - if (i >= maxSessions) { - break; - } - - String serverName = serverNames.getOrDefault(session.getValue(SessionKeys.SERVER_UUID).orElse(null), "Unknown"); - String playerName = playerNames.getOrDefault(session.getValue(SessionKeys.UUID).orElse(null), "Unknown"); - String sessionStart = yearFormatter.apply(session); - - WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()); - WorldPie worldPie = graphs.pie().worldPie(worldTimes); - String longestWorldPlayed = worldAliasSettings.getLongestWorldPlayed(session); - - boolean hasEnded = session.supports(SessionKeys.END); - String sessionEnd = hasEnded ? yearFormatter.apply(() -> session.getUnsafe(SessionKeys.END)) : "Online"; - - String length = (hasEnded ? "" : "(Online) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)); - String afk = (hasEnded ? "" : "(Inaccurate) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.AFK_TIME).orElse(0L)); - - int playerKillCount = session.getValue(SessionKeys.PLAYER_KILL_COUNT).orElse(0); - int mobKillCount = session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0); - int deaths = session.getValue(SessionKeys.DEATH_COUNT).orElse(0); - - String info = appendWorldPercentage - ? HtmlStructure.separateWithDots(sessionStart, longestWorldPlayed) - : sessionStart; - String title = HtmlStructure.separateWithDots(playerName, info) + "" + length + ""; - String htmlID = "" + session.getValue(SessionKeys.START).orElse(0L) + i; - String worldHtmlID = "worldPieSession" + htmlID; - - String leftSide = new AccordionElementContentBuilder() - .addRowBold(Icons.SESSION_LENGTH, "Session Ended", sessionEnd) - .addRowBold(Icons.PLAYTIME, "Session Length", length) - .addRowBold(Icons.AFK_LENGTH, "AFK", afk) - .addRowBold(Icons.SERVER, "Server", serverName) - .addBreak() - .addRowBold(Icons.PLAYER_KILLS, "Player Kills", playerKillCount) - .addRowBold(Icons.MOB_KILLS, "Mob Kills", mobKillCount) - .addRowBold(Icons.DEATHS, "Deaths", deaths) - .toHtml(); - - String rightSide = "
    " + - ""; - viewScript.append("worldPie(") - .append(worldHtmlID).append(", ") - .append(worldHtmlID).append("series, ") - .append(worldHtmlID).append("gmseries") - .append(");"); - - List kills = session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()); - String leftBottom = tables.killsTable(kills, null).parseHtml(); - - String link = PlanAPI.getInstance().getPlayerInspectPageLink(playerName); - String rightBottom = ""; - - addElement(new AccordionElement(htmlID, title) - .setColor(theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION)) - .setLeftSide(leftSide + leftBottom) - .setRightSide(rightSide + rightBottom)); - i++; - } - } - - private void addElementsForPlayer() { - Map serverNames = serverNamesSupplier.get(); - sessions.sort(new DateHolderRecentComparator()); - - int i = 0; - for (Session session : new ArrayList<>(sessions)) { - if (i >= maxSessions) { - break; - } - - String serverName = serverNames.getOrDefault(session.getValue(SessionKeys.SERVER_UUID).orElse(null), "Unknown"); - String sessionStart = yearFormatter.apply(session); - - WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()); - WorldPie worldPie = graphs.pie().worldPie(worldTimes); - String longestWorldPlayed = worldAliasSettings.getLongestWorldPlayed(session); - - boolean hasEnded = session.supports(SessionKeys.END); - String sessionEnd = hasEnded ? yearFormatter.apply(() -> session.getValue(SessionKeys.END).orElse(0L)) : "Online"; - - String length = (hasEnded ? "" : "(Online) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)); - String afk = (hasEnded ? "" : "(Inaccurate) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.AFK_TIME).orElse(0L)); - - int playerKillCount = session.getValue(SessionKeys.PLAYER_KILL_COUNT).orElse(0); - int mobKillCount = session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0); - int deaths = session.getValue(SessionKeys.DEATH_COUNT).orElse(0); - - String info = appendWorldPercentage - ? HtmlStructure.separateWithDots(sessionStart, longestWorldPlayed) - : sessionStart; - String title = HtmlStructure.separateWithDots(serverName, info) + "" + length + ""; - String htmlID = "" + session.getValue(SessionKeys.START).orElse(0L) + i; - String worldHtmlID = "worldPieSession" + htmlID; - - String leftSide = new AccordionElementContentBuilder() - .addRowBold(Icons.SESSION_LENGTH, "Session Ended", sessionEnd) - .addRowBold(Icons.PLAYTIME, "Session Length", length) - .addRowBold(Icons.AFK_LENGTH, "AFK", afk) - .addRowBold(Icons.SERVER, "Server", serverName) - .addBreak() - .addRowBold(Icons.PLAYER_KILLS, "Player Kills", playerKillCount) - .addRowBold(Icons.MOB_KILLS, "Mob Kills", mobKillCount) - .addRowBold(Icons.DEATHS, "Deaths", deaths) - .toHtml(); - - String rightSide = "
    " + - ""; - viewScript.append("worldPie(") - .append(worldHtmlID).append(", ") - .append(worldHtmlID).append("series, ") - .append(worldHtmlID).append("gmseries") - .append(");"); - - List kills = session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()); - String leftBottom = tables.killsTable(kills, null).parseHtml(); - - addElement(new AccordionElement(htmlID, title) - .setColor(theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION)) - .setLeftSide(leftSide + leftBottom) - .setRightSide(rightSide)); - - i++; - } - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/TabsElement.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/TabsElement.java deleted file mode 100644 index 52f8f9fc0..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/TabsElement.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.structure; - -import com.djrapitops.plugin.utilities.Format; - -/** - * Represents a structural HTML element that has Tabs on the top. - * - * @author Rsl1122 - */ -public class TabsElement { - - private final Tab[] tabs; - - public TabsElement(Tab... tabs) { - this.tabs = tabs; - } - - public String toHtmlFull() { - String[] navAndContent = toHtml(); - return navAndContent[0] + navAndContent[1]; - } - - public String[] toHtml() { - StringBuilder nav = new StringBuilder(); - StringBuilder content = new StringBuilder(); - - nav.append("
      "); - content.append("
      "); - boolean first = true; - for (Tab tab : tabs) { - String id = tab.getId(); - String navText = tab.getNavText(); - String contentHtml = tab.getContentHtml(); - - nav.append("
    • ") - .append(navText).append("
    • "); - content.append("
      ") - .append(contentHtml).append("
      "); - first = false; - } - content.append("
      "); - nav.append("
    "); - - return new String[]{nav.toString(), content.toString()}; - } - - public static class Tab { - - private final String navText; - private final String contentHtml; - - public Tab(String navText, String contentHtml) { - this.navText = navText; - this.contentHtml = contentHtml; - } - - public String getNavText() { - return navText; - } - - public String getContentHtml() { - return contentHtml; - } - - public String getId() { - return "tab_" + new Format(navText).removeSymbols().removeWhitespace().lowerCase().toString(); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/CommandUseTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/CommandUseTable.java deleted file mode 100644 index 371bf4e09..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/CommandUseTable.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.utilities.html.HtmlUtils; -import com.djrapitops.plan.utilities.html.icon.Icon; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * Html table that displays how many times each command is used. - * - * @author Rsl1122 - */ -class CommandUseTable extends TableContainer { - - CommandUseTable(DataContainer container) { - super(Icon.called("terminal") + " Command", Icon.called("list-ol") + "Times Used"); - - Map commandUse = container.getValue(ServerKeys.COMMAND_USAGE).orElse(new HashMap<>()); - - setColor("lime"); - if (commandUse.isEmpty()) { - addRow("No Commands"); - } else { - addValues(commandUse); - } - } - - private List> sortByValue(Map map) { - return map.entrySet().stream() - .sorted((one, two) -> Integer.compare(two.getValue(), one.getValue())) - .collect(Collectors.toList()); - } - - private void addValues(Map commandUse) { - List> sorted = sortByValue(commandUse); - - int i = 0; - for (Map.Entry entry : sorted) { - if (i >= 500) { - break; - } - String command = HtmlUtils.removeXSS(entry.getKey()); - addRow(command, entry.getValue()); - - i++; - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/DeathsTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/DeathsTable.java deleted file mode 100644 index f3d50c4b3..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/DeathsTable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.data.container.PlayerDeath; -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plan.utilities.html.icon.Family; -import com.djrapitops.plan.utilities.html.icon.Icon; - -import java.util.List; - -/** - * Html table that displays Deaths of a single player. - * - * @author Rsl1122 - */ -class DeathsTable extends TableContainer { - - private final Formatter yearFormatter; - - DeathsTable(List playerPlayerDeaths, Formatter yearFormatter) { - super(Icon.called("clock").of(Family.REGULAR) + " Time", "Killed by", "With"); - this.yearFormatter = yearFormatter; - setColor("red"); - - if (playerPlayerDeaths.isEmpty()) { - addRow("No Player caused Deaths"); - } else { - addValues(playerPlayerDeaths); - } - } - - private void addValues(List playerPlayerDeaths) { - playerPlayerDeaths.sort(new DateHolderRecentComparator()); - - int i = 0; - for (PlayerDeath death : playerPlayerDeaths) { - if (i >= 40) { - break; - } - - String killerName = death.getKillerName(); - addRow( - yearFormatter.apply(death), - Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(killerName), killerName), - death.getWeapon() - ); - - i++; - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/GeoInfoTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/GeoInfoTable.java deleted file mode 100644 index 21ca1884f..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/GeoInfoTable.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; -import com.djrapitops.plan.utilities.formatting.Formatter; - -import java.util.List; - -/** - * Utility Class for creating IP Table for inspect page. - * - * @author Rsl1122 - */ -class GeoInfoTable extends TableContainer { - - private final boolean displayIP; - private final Formatter yearFormatter; - - GeoInfoTable(List geoInfo, boolean displayIP, Formatter yearFormatter) { - super("IP", "Geolocation", "Last Used"); - this.displayIP = displayIP; - this.yearFormatter = yearFormatter; - - if (geoInfo.isEmpty()) { - addRow("No Connections"); - } else { - addValues(geoInfo); - } - } - - private void addValues(List geoInfo) { - geoInfo.sort(new DateHolderRecentComparator()); - - for (GeoInfo info : geoInfo) { - addRow( - displayIP ? info.getIp() : "Hidden (Config)", - info.getGeolocation(), - yearFormatter.apply(info) - ); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/HtmlTables.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/HtmlTables.java deleted file mode 100644 index d0b8acb41..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/HtmlTables.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.data.container.*; -import com.djrapitops.plan.data.element.AnalysisContainer; -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.system.settings.config.PlanConfig; -import com.djrapitops.plan.system.settings.paths.DisplaySettings; -import com.djrapitops.plan.system.settings.paths.TimeSettings; -import com.djrapitops.plan.utilities.formatting.Formatters; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * Factory class for objects that represent HTML tables. - * - * @author Rsl1122 - */ -@Singleton -public class HtmlTables { - - private final PlanConfig config; - private final Formatters formatters; - - @Inject - public HtmlTables( - PlanConfig config, - Formatters formatters - ) { - this.config = config; - this.formatters = formatters; - } - - /** - * Create a new Command usage table. - * - * @param container Container that supports ServerKeys.COMMAND_USAGE. - * @return a new {@link CommandUseTable}. - */ - public TableContainer commandUseTable(DataContainer container) { - return new CommandUseTable(container); - } - - /** - * Create a new Deaths table. - * - * @param deaths List of {@link PlayerDeath}s to be added to the table. - * @return a new {@link DeathsTable}. - */ - public TableContainer deathsTable(List deaths) { - return new DeathsTable(deaths, formatters.year()); - } - - /** - * Create a new GeoInfo table. - * - * @param geoInfo List of {@link GeoInfo} to be added to the table. - * @return a new {@link GeoInfoTable}. - */ - public TableContainer geoInfoTable(List geoInfo) { - return new GeoInfoTable(geoInfo, config.isTrue(DisplaySettings.PLAYER_IPS), formatters.year()); - } - - /** - * Create a new Kill table. - * - * @param kills List of {@link PlayerKill}s to be added to the table. - * @param color Color the table header should be. - * @return a new {@link KillsTable}. - */ - public TableContainer killsTable(List kills, String color) { - return new KillsTable(kills, color, formatters.year()); - } - - /** - * Create a new Nickname table. - * - * @param nicknames List of {@link Nickname}s to be added to the table. - * @param serverNames Names of the servers, for the server column. - * @return a new {@link NicknameTable}. - */ - public TableContainer nicknameTable(List nicknames, Map serverNames) { - return new NicknameTable(nicknames, serverNames, formatters.year()); - } - - /** - * Create a new Country - Ping table. - * - * @param pingPerCountry Map of {@link Ping}s sorted by country names. - * @return a new {@link PingTable}. - */ - public TableContainer pingTable(Map> pingPerCountry) { - return new PingTable(pingPerCountry, formatters.decimals()); - } - - /** - * Create a new Session table for a player. - * - * @param playerName Name of the player. - * @param sessions List of {@link Session}s the player has. - * @return a new {@link PlayerSessionTable}. - */ - public TableContainer playerSessionTable(String playerName, List sessions) { - return new PlayerSessionTable( - playerName, sessions, - config.get(DisplaySettings.SESSIONS_PER_PAGE), config.getWorldAliasSettings(), formatters.year(), formatters.timeAmount() - ); - } - - /** - * Create a new Session table for a server. - * - * @param playerNames Map of UUID - Name pairs of the players. - * @param sessions List of {@link Session}s that occurred on the server. - * @return a new {@link ServerSessionTable}. - */ - public TableContainer serverSessionTable(Map playerNames, List sessions) { - return new ServerSessionTable( - playerNames, sessions, - config.get(DisplaySettings.SESSIONS_PER_PAGE), config.getWorldAliasSettings(), formatters.year(), formatters.timeAmount() - ); - } - - /** - * Create a Player table for a server. - * - * @param players List of {@link PlayerContainer}s of players who have played on the server. - * @return a new {@link PlayersTable}. - */ - public TableContainer playerTableForServerPage(List players) { - return new PlayersTable( - players, - config.get(DisplaySettings.PLAYERS_PER_SERVER_PAGE), - config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), - config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD), - config.get(DisplaySettings.OPEN_PLAYER_LINKS_IN_NEW_TAB), - formatters.timeAmount(), formatters.yearLong(), formatters.decimals() - ); - } - - /** - * Create a Player table for a players page. - * - * @param players List of {@link PlayerContainer}s of players. - * @return a new {@link PlayersTable}. - */ - public TableContainer playerTableForPlayersPage(List players) { - return new PlayersTable( - players, config.get(DisplaySettings.PLAYERS_PER_PLAYERS_PAGE), - config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), - config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD), - config.get(DisplaySettings.OPEN_PLAYER_LINKS_IN_NEW_TAB), - formatters.timeAmount(), formatters.yearLong(), formatters.decimals() - ); - } - - /** - * Create a new Player table that contains Plugin Data. - * - * @param containers PluginData AnalysisContainers. - * @param players List of {@link PlayerContainer}s of players. - * @return a new {@link PluginPlayersTable}. - */ - public TableContainer pluginPlayersTable(Map containers, Collection players) { - return new PluginPlayersTable( - containers, players, - config.get(DisplaySettings.PLAYERS_PER_SERVER_PAGE), - config.get(DisplaySettings.OPEN_PLAYER_LINKS_IN_NEW_TAB) - ); - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/KillsTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/KillsTable.java deleted file mode 100644 index 41e3e3f33..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/KillsTable.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.data.container.PlayerKill; -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plan.utilities.html.icon.Family; -import com.djrapitops.plan.utilities.html.icon.Icon; - -import java.util.List; - -/** - * Html table that displays kills Player has performed. - * - * @author Rsl1122 - */ -class KillsTable extends TableContainer { - - private final Formatter yearFormatter; - - KillsTable(List playerKills, String color, Formatter yearFormatter) { - super(Icon.called("clock").of(Family.REGULAR) + " Time", "Killed", "With"); - setColor(color); - - this.yearFormatter = yearFormatter; - - if (playerKills.isEmpty()) { - addRow("No Kills"); - } else { - addValues(playerKills); - } - } - - private void addValues(List playerKills) { - playerKills.sort(new DateHolderRecentComparator()); - - int i = 0; - for (PlayerKill kill : playerKills) { - if (i >= 40) { - break; - } - - String victimName = kill.getVictimName().orElse("Unknown"); - addRow( - yearFormatter.apply(kill), - Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(victimName), victimName), - kill.getWeapon() - ); - - i++; - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/NicknameTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/NicknameTable.java deleted file mode 100644 index 59ede0f0c..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/NicknameTable.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plan.utilities.html.HtmlUtils; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * Html table that displays player's nicknames and where they were seen. - * - * @author Rsl1122 - */ -class NicknameTable extends TableContainer { - - private final Formatter yearFormatter; - - NicknameTable(List nicknames, Map serverNames, Formatter yearFormatter) { - super("Nickname", "Server", "Last Seen"); - this.yearFormatter = yearFormatter; - - if (nicknames.isEmpty()) { - addRow("No Nicknames"); - } else { - addValues(nicknames, serverNames); - } - } - - private void addValues(List nicknames, Map serverNames) { - nicknames.sort(new DateHolderRecentComparator()); - - for (Nickname nickname : nicknames) { - UUID serverUUID = nickname.getServerUUID(); - String serverName = serverNames.getOrDefault(serverUUID, "Unknown"); - addRow( - Html.swapColorCodesToSpan(HtmlUtils.removeXSS(nickname.getName())), - serverName, - yearFormatter.apply(nickname) - ); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PingTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PingTable.java deleted file mode 100644 index 79ad8e0ac..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PingTable.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.data.container.Ping; -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.mutators.PingMutator; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.icon.Icon; -import com.djrapitops.plan.utilities.html.icon.Icons; - -import java.util.*; - -/** - * Html table that displays countries and their average, worst and best pings. - * - * @author Rsl1122 - */ -class PingTable extends TableContainer { - - private final Formatter decimalFormatter; - - PingTable(Map> pingPerCountry, Formatter decimalFormatter) { - super( - Icon.called("globe") + " Country", - Icons.SIGNAL + " Average Ping", - Icons.SIGNAL + " Worst Ping", - Icons.SIGNAL + " Best Ping" - ); - this.decimalFormatter = decimalFormatter; - setColor("amber"); - - addRows(pingPerCountry); - } - - private void addRows(Map> pingPerCountry) { - Map avg = new HashMap<>(); - Map max = new HashMap<>(); - Map min = new HashMap<>(); - - for (Map.Entry> entry : pingPerCountry.entrySet()) { - PingMutator pingMutator = new PingMutator(entry.getValue()); - String country = entry.getKey(); - avg.put(country, pingMutator.average()); - max.put(country, pingMutator.max()); - min.put(country, pingMutator.min()); - } - - List sortedKeys = new ArrayList<>(avg.keySet()); - Collections.sort(sortedKeys); - - for (String country : sortedKeys) { - Double average = avg.get(country); - Integer maximum = max.get(country); - Integer minimum = min.get(country); - addRow( - country, - average >= 0 ? decimalFormatter.apply(average) + " ms" : "-", - maximum >= 0 ? maximum + " ms" : "-", - minimum >= 0 ? minimum + " ms" : "-" - ); - } - } -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayerSessionTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayerSessionTable.java deleted file mode 100644 index a197ed755..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayerSessionTable.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.system.settings.config.WorldAliasSettings; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.Html; - -import java.util.List; - -/** - * Html table that can be used to replace a {@link com.djrapitops.plan.utilities.html.structure.SessionAccordion}. - * - * @author Rsl1122 - */ -class PlayerSessionTable extends TableContainer { - - private final int maxSessions; - private final WorldAliasSettings worldAliasSettings; - private final Formatter yearFormatter; - private final Formatter timeAmountFormatter; - - private final String playerName; - private final List sessions; - - PlayerSessionTable(String playerName, List sessions, - int maxSessions, - WorldAliasSettings worldAliasSettings, - Formatter yearFormatter, - Formatter timeAmountFormatter - ) { - super("Player", "Start", "Length", "World"); - this.playerName = playerName; - this.sessions = sessions; - this.maxSessions = maxSessions; - this.worldAliasSettings = worldAliasSettings; - this.yearFormatter = yearFormatter; - this.timeAmountFormatter = timeAmountFormatter; - - addRows(); - } - - private void addRows() { - String inspectUrl = PlanAPI.getInstance().getPlayerInspectPageLink(playerName); - - int i = 0; - for (Session session : sessions) { - if (i >= maxSessions) { - break; - } - - String start = yearFormatter.apply(session); - String length = session.supports(SessionKeys.END) - ? timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)) - : "Online"; - String world = worldAliasSettings.getLongestWorldPlayed(session); - - String toolTip = "Session ID: " + session.getValue(SessionKeys.DB_ID) - .map(Object::toString) - .orElse("Not Saved."); - addRow(Html.LINK_TOOLTIP.parse(inspectUrl, playerName, toolTip), start, length, world); - - i++; - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTable.java deleted file mode 100644 index 4e2708ec6..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTable.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.mutators.ActivityIndex; -import com.djrapitops.plan.data.store.mutators.GeoInfoMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.utilities.comparators.PlayerContainerLastPlayedComparator; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plan.utilities.html.icon.Family; -import com.djrapitops.plan.utilities.html.icon.Icon; - -import java.util.List; - -/** - * Html table that displays a lot of information about players. - * - * @author Rsl1122 - */ -class PlayersTable extends TableContainer { - - private final List players; - private final int maxPlayers; - private final long activeMsThreshold; - private final int activeLoginThreshold; - private final boolean openPlayerPageInNewTab; - - private final Formatter decimalFormatter; - - PlayersTable( - List players, - int maxPlayers, - long activeMsThreshold, - int activeLoginThreshold, - boolean openPlayerPageInNewTab, - Formatter timeAmountFormatter, - Formatter yearLongFormatter, - Formatter decimalFormatter - ) { - super( - Icon.called("user") + " Name", - Icon.called("check") + " Activity Index", - Icon.called("clock").of(Family.REGULAR) + " Playtime", - Icon.called("calendar-plus").of(Family.REGULAR) + " Sessions", - Icon.called("user-plus") + " Registered", - Icon.called("calendar-check").of(Family.REGULAR) + " Last Seen", - Icon.called("globe") + " Geolocation" - ); - this.players = players; - this.maxPlayers = maxPlayers; - this.activeMsThreshold = activeMsThreshold; - this.activeLoginThreshold = activeLoginThreshold; - this.openPlayerPageInNewTab = openPlayerPageInNewTab; - this.decimalFormatter = decimalFormatter; - useJqueryDataTables("player-table"); - - setFormatter(2, timeAmountFormatter); - setFormatter(4, yearLongFormatter); - setFormatter(5, yearLongFormatter); - addRows(); - } - - private void addRows() { - PlanAPI planAPI = PlanAPI.getInstance(); - long now = System.currentTimeMillis(); - - players.sort(new PlayerContainerLastPlayedComparator()); - - int i = 0; - for (PlayerContainer player : players) { - if (i >= maxPlayers) { - break; - } - String name = player.getValue(PlayerKeys.NAME).orElse("Unknown"); - String url = planAPI.getPlayerInspectPageLink(name); - - SessionsMutator sessionsMutator = SessionsMutator.forContainer(player); - int loginTimes = sessionsMutator.count(); - long playtime = sessionsMutator.toPlaytime(); - long registered = player.getValue(PlayerKeys.REGISTERED).orElse(0L); - long lastSeen = sessionsMutator.toLastSeen(); - - ActivityIndex activityIndex = player.getActivityIndex(now, activeMsThreshold, activeLoginThreshold); - boolean isBanned = player.getValue(PlayerKeys.BANNED).orElse(false); - String activityString = activityIndex.getFormattedValue(decimalFormatter) - + (isBanned ? " (Banned)" : " (" + activityIndex.getGroup() + ")"); - - String geolocation = GeoInfoMutator.forContainer(player).mostRecent().map(GeoInfo::getGeolocation).orElse("-"); - - Html link = openPlayerPageInNewTab ? Html.LINK_EXTERNAL : Html.LINK; - - addRow( - link.parse(url, name), - activityString, - playtime, - loginTimes, - registered, - lastSeen, - geolocation - ); - - i++; - } - - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTableJSONParser.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTableJSONParser.java deleted file mode 100644 index 0a4dee239..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTableJSONParser.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.data.container.GeoInfo; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.mutators.ActivityIndex; -import com.djrapitops.plan.data.store.mutators.GeoInfoMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.extension.FormatType; -import com.djrapitops.plan.extension.icon.Color; -import com.djrapitops.plan.extension.implementation.results.*; -import com.djrapitops.plan.utilities.comparators.PlayerContainerLastPlayedComparator; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.formatting.Formatters; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plan.utilities.html.icon.Family; -import com.djrapitops.plan.utilities.html.icon.Icon; - -import java.util.*; - -/** - * Parsing utility for creating jQuery Datatables JSON for a Players Table. - *

    - * See https://www.datatables.net/manual/data/orthogonal-data#HTML-5 for sort kinds - * - * @author Rsl1122 - */ -public class PlayersTableJSONParser { - - private final List players; - private final List extensionDescriptives; - private final Map extensionData; - - private final int maxPlayers; - private final long activeMsThreshold; - private final int activeLoginThreshold; - private final boolean openPlayerPageInNewTab; - - private Map> numberFormatters; - - private Formatter decimalFormatter; - - public PlayersTableJSONParser( - // Data - List players, - Map extensionData, - // Settings - int maxPlayers, long activeMsThreshold, int activeLoginThreshold, boolean openPlayerPageInNewTab, - // Formatters - Formatters formatters - ) { - // Data - this.players = players; - this.extensionData = extensionData; - - extensionDescriptives = new ArrayList<>(); - addExtensionDescriptives(extensionData); - extensionDescriptives.sort((one, two) -> String.CASE_INSENSITIVE_ORDER.compare(one.getName(), two.getName())); - - // Settings - this.maxPlayers = maxPlayers; - this.activeMsThreshold = activeMsThreshold; - this.activeLoginThreshold = activeLoginThreshold; - this.openPlayerPageInNewTab = openPlayerPageInNewTab; - // Formatters - numberFormatters = new EnumMap<>(FormatType.class); - numberFormatters.put(FormatType.DATE_SECOND, formatters.secondLong()); - numberFormatters.put(FormatType.DATE_YEAR, formatters.yearLong()); - numberFormatters.put(FormatType.TIME_MILLISECONDS, formatters.timeAmount()); - numberFormatters.put(FormatType.NONE, Object::toString); - - this.decimalFormatter = formatters.decimals(); - } - - private void addExtensionDescriptives(Map extensionData) { - Set foundDescriptives = new HashSet<>(); - for (ExtensionTabData tabData : extensionData.values()) { - for (ExtensionDescriptive descriptive : tabData.getDescriptives()) { - if (!foundDescriptives.contains(descriptive.getName())) { - extensionDescriptives.add(descriptive); - foundDescriptives.add(descriptive.getName()); - } - } - } - } - - public String toJSONString() { - String data = parseData(); - String columnHeaders = parseColumnHeaders(); - return "{\"columns\":" + columnHeaders + ",\"data\":" + data + '}'; - } - - private String parseData() { - StringBuilder dataJSON = new StringBuilder("["); - - PlanAPI planAPI = PlanAPI.getInstance(); - long now = System.currentTimeMillis(); - players.sort(new PlayerContainerLastPlayedComparator()); - - int currentPlayerNumber = 0; - for (PlayerContainer player : players) { - if (currentPlayerNumber >= maxPlayers) { - break; - } - UUID playerUUID = player.getValue(PlayerKeys.UUID).orElse(null); - if (playerUUID == null) { - continue; - } - - if (currentPlayerNumber > 0) { - dataJSON.append(','); // Previous item - } - dataJSON.append('{'); // Start new item - - appendPlayerData(dataJSON, planAPI, now, player); - appendExtensionData(dataJSON, extensionData.getOrDefault(playerUUID, new ExtensionTabData.Factory(null).build())); - - dataJSON.append('}'); // Close new item - - currentPlayerNumber++; - } - return dataJSON.append(']').toString(); - } - - private void appendPlayerData(StringBuilder dataJSON, PlanAPI planAPI, long now, PlayerContainer player) { - String name = player.getValue(PlayerKeys.NAME).orElse("Unknown"); - String url = planAPI.getPlayerInspectPageLink(name); - - SessionsMutator sessionsMutator = SessionsMutator.forContainer(player); - int loginTimes = sessionsMutator.count(); - long playtime = sessionsMutator.toPlaytime(); - long registered = player.getValue(PlayerKeys.REGISTERED).orElse(0L); - long lastSeen = sessionsMutator.toLastSeen(); - - ActivityIndex activityIndex = player.getActivityIndex(now, activeMsThreshold, activeLoginThreshold); - boolean isBanned = player.getValue(PlayerKeys.BANNED).orElse(false); - String activityString = activityIndex.getFormattedValue(decimalFormatter) - + (isBanned ? " (Banned)" : " (" + activityIndex.getGroup() + ")"); - - String geolocation = GeoInfoMutator.forContainer(player).mostRecent().map(GeoInfo::getGeolocation).orElse("-"); - - Html link = openPlayerPageInNewTab ? Html.LINK_EXTERNAL : Html.LINK; - - dataJSON - .append(makeDataEntry(link.parse(url, name), "name")).append(',') - .append(makeDataEntry(activityIndex.getValue(), activityString, "index")).append(',') - .append(makeDataEntry(playtime, numberFormatters.get(FormatType.TIME_MILLISECONDS).apply(playtime), "playtime")).append(',') - .append(makeDataEntry(loginTimes, "sessions")).append(',') - .append(makeDataEntry(registered, numberFormatters.get(FormatType.DATE_YEAR).apply(registered), "registered")).append(',') - .append(makeDataEntry(lastSeen, numberFormatters.get(FormatType.DATE_YEAR).apply(lastSeen), "seen")).append(',') - .append(makeDataEntry(geolocation, "geolocation")) - ; - } - - private String makeDataEntry(Object data, String dataName) { - return "\"" + dataName + "\":\"" + data.toString().replace('"', '\'') + "\""; - } - - private String makeDataEntry(Object data, String formatted, String dataName) { - return "\"" + dataName + "\":{\"v\":\"" + data.toString().replace('"', '\'') + "\", \"d\":\"" + formatted.replace('"', '\'') + "\"}"; - } - - private void appendExtensionData(StringBuilder dataJSON, ExtensionTabData tabData) { - for (ExtensionDescriptive descriptive : extensionDescriptives) { - dataJSON.append(','); - String key = descriptive.getName(); - - // If it's a double, append a double - Optional doubleValue = tabData.getDouble(key); - - if (doubleValue.isPresent()) { - dataJSON.append(makeDataEntry(doubleValue.get().getRawValue(), doubleValue.get().getFormattedValue(decimalFormatter), key)); - continue; - } - - Optional numberValue = tabData.getNumber(key); - if (numberValue.isPresent()) { - ExtensionNumberData numberData = numberValue.get(); - FormatType formatType = numberData.getFormatType(); - dataJSON.append(makeDataEntry(numberData.getRawValue(), numberData.getFormattedValue(numberFormatters.get(formatType)), key)); - continue; - } - - // If it's a String append a String, otherwise the player has no value for this extension provider. - String stringValue = tabData.getString(key).map(ExtensionStringData::getFormattedValue).orElse("-"); - dataJSON.append(makeDataEntry(stringValue, stringValue, key)); - } - } - - private String parseColumnHeaders() { - StringBuilder columnHeaders = new StringBuilder("["); - - // Is the data for the column formatted - - columnHeaders - .append(makeColumnHeader(Icon.called("user") + " Name", "name")).append(',') - .append(makeFColumnHeader(Icon.called("check") + " Activity Index", "index")).append(',') - .append(makeFColumnHeader(Icon.called("clock").of(Family.REGULAR) + " Playtime", "playtime")).append(',') - .append(makeColumnHeader(Icon.called("calendar-plus").of(Family.REGULAR) + " Sessions", "sessions")).append(',') - .append(makeFColumnHeader(Icon.called("user-plus") + " Registered", "registered")).append(',') - .append(makeFColumnHeader(Icon.called("calendar-check").of(Family.REGULAR) + " Last Seen", "seen")).append(',') - .append(makeColumnHeader(Icon.called("globe") + " Geolocation", "geolocation")); - - appendExtensionHeaders(columnHeaders); - - return columnHeaders.append(']').toString(); - } - - private String makeColumnHeader(String title, String dataProperty) { - return "{\"title\": \"" + title.replace('"', '\'') + "\",\"data\":\"" + dataProperty + "\"}"; - } - - private String makeFColumnHeader(String title, String dataProperty) { - return "{\"title\": \"" + title.replace('"', '\'') + "\",\"data\":{\"_\":\"" + dataProperty + ".v\",\"display\":\"" + dataProperty + ".d\"}}"; - } - - private void appendExtensionHeaders(StringBuilder columnHeaders) { - for (ExtensionDescriptive provider : extensionDescriptives) { - columnHeaders.append(','); - String headerText = Icon.fromExtensionIcon(provider.getIcon().setColor(Color.NONE)).toHtml().replace('"', '\'') + ' ' + provider.getText(); - columnHeaders.append(makeFColumnHeader(headerText, provider.getName())); - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PluginPlayersTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PluginPlayersTable.java deleted file mode 100644 index c68499443..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/PluginPlayersTable.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.data.element.AnalysisContainer; -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.utilities.html.Html; -import com.djrapitops.plugin.utilities.ArrayUtil; - -import java.io.Serializable; -import java.util.*; - -/** - * Html table that displays players data in various plugins. - * - * @author Rsl1122 - */ -class PluginPlayersTable extends TableContainer { - - private Collection players; - - private final int maxPlayers; - private final boolean openPlayerPageInNewTab; - - PluginPlayersTable( - Map containers, - Collection players, - int maxPlayers, - boolean openPlayerPageInNewTab - ) { - this(getPluginDataSet(containers), players, maxPlayers, openPlayerPageInNewTab); - } - - private PluginPlayersTable( - TreeMap> pluginDataSet, - Collection players, - int maxPlayers, - boolean openPlayerPageInNewTab - ) { - super(true, getHeaders(pluginDataSet.keySet())); - - this.players = players; - this.maxPlayers = maxPlayers; - this.openPlayerPageInNewTab = openPlayerPageInNewTab; - - useJqueryDataTables("player-plugin-table"); - - if (players.isEmpty()) { - addRow("No Players"); - } else { - Map rows = getRows(pluginDataSet); - addValues(rows); - } - } - - private static String[] getHeaders(Set columnNames) { - List header = new ArrayList<>(columnNames); - Collections.sort(header); - return header.toArray(new String[0]); - } - - private static TreeMap> getPluginDataSet(Map containers) { - TreeMap> data = new TreeMap<>(); - for (AnalysisContainer container : containers.values()) { - if (!container.hasPlayerTableValues()) { - continue; - } - data.putAll(container.getPlayerTableValues()); - } - return data; - } - - private void addValues(Map rows) { - int i = 0; - for (PlayerContainer profile : players) { - if (i >= maxPlayers) { - break; - } - - UUID uuid = profile.getUnsafe(PlayerKeys.UUID); - String name = profile.getValue(PlayerKeys.NAME).orElse("Unknown"); - Html link = openPlayerPageInNewTab ? Html.LINK_EXTERNAL : Html.LINK; - String linkHtml = link.parse(PlanAPI.getInstance().getPlayerInspectPageLink(name), name); - - Serializable[] playerData = ArrayUtil.merge(new Serializable[]{linkHtml}, rows.getOrDefault(uuid, new Serializable[]{})); - addRow(playerData); - - i++; - } - } - - private Map getRows(TreeMap> data) { - Map rows = new HashMap<>(); - - int size = header.length - 1; - for (PlayerContainer profile : players) { - UUID uuid = profile.getUnsafe(PlayerKeys.UUID); - - Serializable[] row = new Serializable[size]; - for (int i = 0; i < size; i++) { - String label = header[i + 1]; - - Map playerSpecificData = data.getOrDefault(label, new HashMap<>()); - Serializable value = playerSpecificData.get(uuid); - if (value != null) { - row[i] = value; - } - } - rows.put(uuid, row); - } - return rows; - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/ServerSessionTable.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/ServerSessionTable.java deleted file mode 100644 index a5b0f25cb..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/tables/ServerSessionTable.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.html.tables; - -import com.djrapitops.plan.api.PlanAPI; -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.system.settings.config.WorldAliasSettings; -import com.djrapitops.plan.utilities.formatting.Formatter; -import com.djrapitops.plan.utilities.html.Html; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * Html table that can be used to replace a {@link com.djrapitops.plan.utilities.html.structure.SessionAccordion}. - * - * @author Rsl1122 - */ -class ServerSessionTable extends TableContainer { - - private final int maxSessions; - private final WorldAliasSettings worldAliasSettings; - private final Formatter yearFormatter; - private final Formatter timeAmountFormatter; - - private final List sessions; - private Map playerNames; - - ServerSessionTable( - Map playerNames, List sessions, - int maxSessions, - WorldAliasSettings worldAliasSettings, - Formatter yearFormatter, - Formatter timeAmountFormatter - ) { - super("Player", "Start", "Length", "World"); - this.playerNames = playerNames; - this.sessions = sessions; - this.maxSessions = maxSessions; - this.worldAliasSettings = worldAliasSettings; - this.yearFormatter = yearFormatter; - this.timeAmountFormatter = timeAmountFormatter; - - addRows(); - } - - private void addRows() { - int i = 0; - for (Session session : sessions) { - if (i >= maxSessions) { - break; - } - - String start = yearFormatter.apply(session); - String length = session.supports(SessionKeys.END) - ? timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)) - : "Online"; - String world = worldAliasSettings.getLongestWorldPlayed(session); - - String toolTip = "Session ID: " + session.getValue(SessionKeys.DB_ID) - .map(Object::toString) - .orElse("Not Saved."); - - String playerName = playerNames.getOrDefault(session.getValue(SessionKeys.UUID).orElse(null), "Unknown"); - String inspectUrl = PlanAPI.getInstance().getPlayerInspectPageLink(playerName); - - addRow(Html.LINK_TOOLTIP.parse(inspectUrl, playerName, toolTip), start, length, world); - - i++; - } - } -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowableUtils.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowableUtils.java deleted file mode 100644 index ef610fef1..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowableUtils.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.java; - -import com.djrapitops.plugin.utilities.ArrayUtil; - -/** - * Utilities for manipulating different Throwables. - * - * @author Rsl1122 - */ -public class ThrowableUtils { - - private ThrowableUtils() { - /* Static method class */ - } - - public static void appendEntryPointToCause(Throwable throwable, Throwable originPoint) { - Throwable cause = throwable.getCause(); - while (cause.getCause() != null) { - cause = cause.getCause(); - } - cause.setStackTrace(ArrayUtil.merge(cause.getStackTrace(), originPoint.getStackTrace())); - } - - public static String findCallerAfterClass(StackTraceElement[] stackTrace, Class afterThis) { - boolean found = false; - for (StackTraceElement stackTraceElement : stackTrace) { - if (found) { - return stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName(); - } - if (stackTraceElement.getClassName().contains(afterThis.getName())) { - found = true; - } - } - return "Unknown"; - } - -} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowingVoidFunction.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowingVoidFunction.java deleted file mode 100644 index 951d08b12..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowingVoidFunction.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.java; - -/** - * Functional interface that performs an operation that might throw an exception. - *

    - * Follows naming scheme of Java 8 functional interfaces. - * - * @author Rsl1122 - */ -public interface ThrowingVoidFunction { - - void apply() throws T; - -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/VoidFunction.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/VoidFunction.java deleted file mode 100644 index 2479f9b39..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/VoidFunction.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.java; - -/** - * Functional interface that performs an operation that returns nothing. - *

    - * Follows naming scheme of Java 8 functional interfaces. - * - * @author Rsl1122 - */ -public interface VoidFunction { - void apply(); -} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/uuid/UUIDUtility.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/uuid/UUIDUtility.java deleted file mode 100644 index 53492f257..000000000 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/uuid/UUIDUtility.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of Player Analytics (Plan). - * - * Plan is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License v3 as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Plan is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Plan. If not, see . - */ -package com.djrapitops.plan.utilities.uuid; - -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plugin.api.utility.UUIDFetcher; -import com.djrapitops.plugin.logging.L; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.Optional; -import java.util.UUID; - -/** - * Utility for fetching a user's UUID. - *

    - * Attempts are made in order: - * - Parse UUID out of the given String - * - Find an UUID from the database matching the player name - * - Find an UUID from Mojang API that matches the player name - * - * @author Rsl1122 - */ -@Singleton -public class UUIDUtility { - - private final DBSystem dbSystem; - private final ErrorHandler errorHandler; - - @Inject - public UUIDUtility(DBSystem dbSystem, ErrorHandler errorHandler) { - this.dbSystem = dbSystem; - this.errorHandler = errorHandler; - } - - /** - * Get UUID of a player. - * - * @param playerName Player's name - * @return UUID of the player - */ - public UUID getUUIDOf(String playerName) { - UUID uuid = getUUIDFromString(playerName); - if (uuid != null) return uuid; - - return getUUIDFromDB(playerName) - .orElse(getUUIDViaUUIDFetcher(playerName)); - } - - private UUID getUUIDFromString(String playerName) { - try { - return UUID.fromString(playerName); - } catch (IllegalArgumentException ignore) { - return null; - } - } - - private UUID getUUIDViaUUIDFetcher(String playerName) { - try { - return UUIDFetcher.getUUIDOf(playerName); - } catch (Exception | NoClassDefFoundError ignored) { - return null; - } - } - - private Optional getUUIDFromDB(String playerName) { - try { - return dbSystem.getDatabase().query(UserIdentifierQueries.fetchPlayerUUIDOf(playerName)); - } catch (DBOpException e) { - errorHandler.log(L.ERROR, UUIDUtility.class, e); - return Optional.empty(); - } - } -} diff --git a/Plan/common/src/main/resources/Cert.keystore b/Plan/common/src/main/resources/Cert.keystore deleted file mode 100644 index 9f95d38078a346f829ad23ca06a128fd257d68a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2252 zcmchYc{tRI9>(W4izRzxi)g__GBd(a*%HR!)WKBdQg@PlUou*F7?NRz7z`tm?8_lb zvQ7?>C6#^OX{=*OVswn_p6A~CoagEP`^Wpo`}ynpywCf*UoM-=27y4}LjiwDq1gPG0={O{x) z7kS#ir{MMz37D?v9@Pz})8Xk-j!u0?t@rxIc)JqQZ&FrE@MIF@JGyhq+S^rjb?FLe;FZV1G-yb;!UU*IGlFn^dEp9)m z(i8`tbBztC1EoLlTh~4Cdvn9dGg<@PYpM^P9o90{e|cH1jv|L;M}-7QYZ|vi4*W3* zC%w1M{z`ESVL1CLFZ3K$;hQ!6y$RKmS5Hh%D&R}jJ#e?>$SUY&83XI942v|Wfc?hB ztCFrLEE4rvYIIQ?A~N0JF=FXpmRm#O2WJXNU&6JA8BOpT-N`WhvM`DfzVx9?3u~kY zt5ZPKSyIm!?zr;>mBx5%52ki@q^a}R+Wk0dnhPH{k}#+pR|uh>>(l0qJE>k`+u61M zEd@tuFrNEuasNjHN8q#1*!H|nFT8KC_S@rW$F-R zCC$z-V5MrT_^WK`OnO~aSY~n(r(BhDT2jN}*Ytnz;YI;JPl5I)YUV~LhM{`dS61@1&Z_7T~>`!-o%2f}m z7B#t=8Orl4HMxu9s0d=|Ht6XP4VZ+jh75~Je?n@Q;vlt_Pz}@9*~Li7g|5_FX?kIr zE3c^G(ZkDc0x`DI4~&R(bA9^VSbWv--YLku&gOz2`@!2!{*>PMxzA>jadpNg{%mLp zN_77;Sg^Ksi4ptmo*;24nHFNtMxIaAW~cWtKFU;hA26p|hJ1soXq)!*d1<}0ORbA? zE~SconeUCl!w2G`9$WPH&8jqo71-A;mpsj^@$t0yj7o?LWb}F#nsk!Lqp+sIq<~D` ztMsa>n3wX5op%uH_hS>H*nYZZD95|-bk9XAR>a-k!7eBZPSPRin^RJ3;^;00SXBk)nr-3Bf{n#Cfsa9^O6# z@Bb3Mp9t?yau5<==AbTpAD?Lc zfDi!@5P}FC0TTfL^v%TXc;uvIN(IoDV6n)n0ILIgS6(#d_SY|7W=DV-d2?To04%^zzwd#=sS>}eMuE4o?i`R#ERR>!%)y$qih zE@D57m$JhKq}7aBqq&bD-SO)lvN`#2qOmROuksOZjMZW=)#$Ft+@Y1XPgHy^qPI0H zJ4so!Iwi|zIoNrNu9>#sQ0t>ZBf>U*Ck}Snt=2>zHX^^>?g(!6`$al%V}R#KTS< zh6sSjXAVTR1gV}D^z%ju)a&QudP5>}!m6;LzC?WuURlewS2s4on1SN5;_V`p?m4~W z3xv%ZRgd6YJMA{|%R4N4$f{_hOL(O!Hhh2rs|+ZFm~l`r3J0B(g9}T@k{so zT8ig4xii%r!b5%`9nZ7pq7_yjy7iE8iv8oq6wXQ`PcpupdR-HUP(Q|lvs_O

    0~ Y7Mw!mBx(yM$4_Q7PDGLVaY~c_0?9r16951J diff --git a/Plan/common/src/main/resources/assets/plan/DefaultServerInfoFile.yml b/Plan/common/src/main/resources/assets/plan/DefaultServerInfoFile.yml deleted file mode 100644 index 3978cd4d5..000000000 --- a/Plan/common/src/main/resources/assets/plan/DefaultServerInfoFile.yml +++ /dev/null @@ -1,4 +0,0 @@ -# Changing the UUID in this file will make Plan regard your server as a completely new server -# Thread with caution. -Server: - UUID: diff --git a/Plan/common/src/main/resources/assets/plan/bungeeconfig.yml b/Plan/common/src/main/resources/assets/plan/bungeeconfig.yml deleted file mode 100644 index f63dc3d63..000000000 --- a/Plan/common/src/main/resources/assets/plan/bungeeconfig.yml +++ /dev/null @@ -1,180 +0,0 @@ -# ----------------------------------------------------- -# Plan Bungee Configuration file -# More information about each setting: -# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Bungee-Configuration -# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Bukkit-Configuration -# ----------------------------------------------------- -Server: - IP: 0.0.0.0 -Network: - Name: Plan -# ----------------------------------------------------- -Plugin: - Logging: - Locale: default - Create_new_locale_file_on_next_enable: false - Debug: false - Dev: false - Delete_logs_after_days: 7 - Update_notifications: - # Display update notification on the website - Check_for_updates: true - Notify_about_DEV_releases: false -# ----------------------------------------------------- -# Supported databases: MySQL -# ----------------------------------------------------- -Database: - MySQL: - Host: localhost - Port: 3306 - User: root - Password: minecraft - Database: Plan - # Launch options to append after mysql driver address - Launch_options: "?rewriteBatchedStatements=true&useSSL=false" -# ----------------------------------------------------- -# More information about SSL Certificate Settings: -# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/SSL-Certificate-%28HTTPS%29-Set-Up -# ----------------------------------------------------- -Webserver: - Port: 8804 - Alternative_IP: false - # %port% is replaced automatically with Webserver.Port - Address: your.domain.here:%port% - # InternalIP usually does not need to be changed, only change it if you know what you're doing! - # 0.0.0.0 allocates Internal (local) IP automatically for the WebServer. - Internal_IP: 0.0.0.0 - Security: - SSL_certificate: - KeyStore_path: Cert.jks - Key_pass: default - Store_pass: default - Alias: alias - # For those that want to serve Html from their own WebServer instead. - # Set up Html Export (https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/External-WebServer-Use) - # ATTENTION: On BungeeCord systems it is not possible to disable the WebServer on the plugin due to connection requirements. - # If the WebServer is disabled with this setting BungeeCord systems will cease to function. - Disable_Webserver: false - External_Webserver_address: "https://www.example.address" -# ----------------------------------------------------- -Data_gathering: - Geolocations: true - Ping: true -# ----------------------------------------------------- -# Supported time units: MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS -# ----------------------------------------------------- -Time: - # UTC used if false. Only affects Timestamps and graphs. - Use_server_timezone: true - Delays: - Ping_server_enable_delay: 300 - Unit: SECONDS - Ping_player_join_delay: 30 - Unit: SECONDS - Wait_for_DB_Transactions_on_disable: 20 - Unit: SECONDS - Thresholds: - # How long player needs to be idle until Plan considers them AFK - AFK_threshold: 3 - Unit: MINUTES - # Activity Index considers last 3 weeks and uses these thresholds in the calculation - # The index is a number from 0 to 5. - # These numbers were calibrated with data of 250 players (Small sample size). - Activity_index: - Login_threshold: 2 - Playtime_threshold: 30 - Unit: MINUTES - Remove_inactive_player_data_after: 180 - Unit: DAYS - # Includes players online, tps and performance time series - Remove_time_series_data_after: 90 - Unit: DAYS - Remove_ping_data_after: 14 - Unit: DAYS - Periodic_tasks: - Extension_data_refresh_every: 1 - Unit: HOURS - Check_DB_for_server_config_files_every: 1 - Unit: MINUTES - Clean_caches_every: 10 - Unit: MINUTES - Clean_Database_every: 1 - Unit: HOURS -# ----------------------------------------------------- -Display_options: - # More information about Themes: - # https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Themes - Theme: default - Sessions: - Replace_accordion_with_table: false - Show_most_played_world_in_title: true - Show_on_page: 50 - # By Default World playtime pie is ordered alphabetically. - # Colors will be determined alphabetically in any case. - Order_world_pies_by_percentage: false - Players_table: - Show_on_server_page: 2500 - Show_on_players_page: 25000 - Open_player_links_in_new_tab: false - Show_player_IPs: true - Graphs: - Show_gaps_in_data: false - Command_colors: - Main: '&2' - Secondary: '&7' - Highlight: '&f' -# ----------------------------------------------------- -Formatting: - Decimal_points: '#.##' - Time_amount: - Year: '1 year, ' - Years: '%years% years, ' - Month: '1 month, ' - Months: '%months% months, ' - Day: '1d ' - Days: '%days%d ' - Hours: '%hours%h ' - Minutes: '%minutes%m ' - Seconds: '%seconds%s' - Zero: '0s' - # Dates settings use Java SimpleDateFormat. - # You can find the patterns & examples here: - # https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html - Dates: - # Show_recent_day_names replaces day number with Today, Yesterday, Wednesday etc. - Show_recent_day_names: true - # Non-regex pattern to replace - DatePattern: 'MMM d YYYY' - Full: 'MMM d YYYY, HH:mm:ss' - NoSeconds: 'MMM d YYYY, HH:mm' - JustClock: 'HH:mm:ss' -# ----------------------------------------------------- -# World aliases can be used to rename worlds and to combine multiple worlds into a group. -# ----------------------------------------------------- -World_aliases: - world: world -# ----------------------------------------------------- -# These settings will make Plan write .js, .css, .json and .html files to some location on disk. -# Relative path will render to /plugins/Plan/path -# Make sure user running the server has write permissions to the path. -# ----------------------------------------------------- -Export: - HTML_Export_path: 'Analysis Results' - JSON_Export_path: 'Raw JSON' - Parts: - JavaScript_and_CSS: false - # Player pages/JSON are only written on join/leave. - Player_pages: false - Player_JSON: false - Players_page: false - Server_page: false - Server_JSON: false - Export_player_on_login_and_logout: false -# ----------------------------------------------------- -# These settings affect Plugin data integration. -# If a plugin is causing issues the integration can be disabled by setting Plugin_name.Enabled: false -# ----------------------------------------------------- -Plugins: - BuyCraft: - # http://help.buycraft.net/article/36-where-to-find-the-secret-key - Secret: "-" \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/config.yml b/Plan/common/src/main/resources/assets/plan/config.yml deleted file mode 100644 index 32d49a735..000000000 --- a/Plan/common/src/main/resources/assets/plan/config.yml +++ /dev/null @@ -1,200 +0,0 @@ -# ----------------------------------------------------- -# Plan Bukkit Configuration file -# More information about each setting: -# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Bukkit-Configuration -# ----------------------------------------------------- -Server: - ServerName: Plan -# ----------------------------------------------------- -Plugin: - Logging: - # More information about Locale - # https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Localization - Locale: default - Create_new_locale_file_on_next_enable: false - Debug: false - Dev: false - Delete_logs_after_days: 7 - Update_notifications: - # Display update notification on the website - Check_for_updates: true - Notify_about_DEV_releases: false - Configuration: - Allow_bungeecord_to_manage_settings: true -# ----------------------------------------------------- -# Supported databases: SQLite, H2, MySQL -# ----------------------------------------------------- -Database: - Type: SQLite - MySQL: - Host: localhost - Port: 3306 - User: root - Password: minecraft - Database: Plan - # Launch options to append after mysql driver address - Launch_options: ?rewriteBatchedStatements=true&useSSL=false -# ----------------------------------------------------- -# More information about SSL Certificate Settings: -# https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/SSL-Certificate-%28HTTPS%29-Set-Up -# ----------------------------------------------------- -Webserver: - Port: 8804 - Alternative_IP: false - # %port% is replaced automatically with Webserver.Port - Address: your.domain.here:%port% - # InternalIP usually does not need to be changed, only change it if you know what you're doing! - # 0.0.0.0 allocates Internal (local) IP automatically for the WebServer. - Internal_IP: 0.0.0.0 - Security: - SSL_certificate: - KeyStore_path: Cert.jks - Key_pass: default - Store_pass: default - Alias: alias - # For those that want to serve Html from their own WebServer instead. - # Set up Html Export (https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/External-WebServer-Use) - # ATTENTION: On BungeeCord systems it is not possible to disable the WebServer on the plugin due to connection requirements. - # If the WebServer is disabled with this setting BungeeCord systems will cease to function. - Disable_Webserver: false - External_Webserver_address: https://www.example.address -# ----------------------------------------------------- -Data_gathering: - Geolocations: true - Ping: true - Commands: - Log_unknown: false - Log_aliases_as_main_command: true -# ----------------------------------------------------- -# Supported time units: MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS -# ----------------------------------------------------- -Time: - # UTC used if false. Only affects Timestamps and graphs. - Use_server_timezone: true - Delays: - Ping_server_enable_delay: 300 - Unit: SECONDS - Ping_player_join_delay: 30 - Unit: SECONDS - Wait_for_DB_Transactions_on_disable: 20 - Unit: SECONDS - Thresholds: - # How long player needs to be idle until Plan considers them AFK - AFK_threshold: 3 - Unit: MINUTES - # Activity Index considers last 3 weeks and uses these thresholds in the calculation - # The index is a number from 0 to 5. - # These numbers were calibrated with data of 250 players (Small sample size). - Activity_index: - Login_threshold: 2 - Playtime_threshold: 30 - Unit: MINUTES - Remove_inactive_player_data_after: 180 - Unit: DAYS - # Includes players online, tps and performance time series - Remove_time_series_data_after: 90 - Unit: DAYS - Remove_ping_data_after: 14 - Unit: DAYS - Periodic_tasks: - Analysis_refresh_every: 60 - Unit: MINUTES - Extension_data_refresh_every: 1 - Unit: HOURS - Check_DB_for_server_config_files_every: 1 - Unit: MINUTES - Clean_caches_every: 10 - Unit: MINUTES - Clean_Database_every: 1 - Unit: HOURS -# ----------------------------------------------------- -Display_options: - # More information about Themes: - # https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki/Themes - Theme: default - Sessions: - Replace_accordion_with_table: false - Show_most_played_world_in_title: true - Show_on_page: 50 - # By Default World playtime pie is ordered alphabetically. - # Colors will be determined alphabetically in any case. - Order_world_pies_by_percentage: false - Players_table: - Show_on_server_page: 2500 - Show_on_players_page: 25000 - Open_player_links_in_new_tab: false - Show_player_IPs: true - Graphs: - Show_gaps_in_data: false - TPS: - High_threshold: 18 - Medium_threshold: 10 - Disk_space: - High_threshold: 500 - Medium_threshold: 100 - Command_colors: - Main: '&2' - Secondary: '&7' - Highlight: '&f' -# ----------------------------------------------------- -Formatting: - Decimal_points: '#.##' - Time_amount: - Year: '1 year, ' - Years: '%years% years, ' - Month: '1 month, ' - Months: '%months% months, ' - Day: '1d ' - Days: '%days%d ' - Hours: '%hours%h ' - Minutes: '%minutes%m ' - Seconds: %seconds%s - Zero: 0s - # Dates settings use Java SimpleDateFormat. - # You can find the patterns & examples here: - # https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html - Dates: - # Show_recent_day_names replaces day number with Today, Yesterday, Wednesday etc. - Show_recent_day_names: true - # Non-regex pattern to replace - DatePattern: 'MMM d YYYY' - Full: 'MMM d YYYY, HH:mm:ss' - NoSeconds: 'MMM d YYYY, HH:mm' - JustClock: HH:mm:ss -# ----------------------------------------------------- -# World aliases can be used to rename worlds and to combine multiple worlds into a group. -# ----------------------------------------------------- -World_aliases: - world: world -# ----------------------------------------------------- -# These settings will make Plan write .js, .css, .json and .html files to some location on disk. -# Relative path will render to /plugins/Plan/path -# Make sure user running the server has write permissions to the path. -# ----------------------------------------------------- -Export: - HTML_Export_path: 'Analysis Results' - JSON_Export_path: 'Raw JSON' - Parts: - JavaScript_and_CSS: false - # Player pages/JSON are only written on join/leave. - Player_pages: false - Player_JSON: false - Players_page: false - Server_page: false - Server_JSON: false - # All player pages/JSON can be exported by using /plan m export players - Export_player_on_login_and_logout: false -# ----------------------------------------------------- -# These settings affect Plugin data integration. -# If a plugin is causing issues the integration can be disabled by setting Plugin_name.Enabled: false -# ----------------------------------------------------- -Plugins: - BuyCraft: - # http://help.buycraft.net/article/36-where-to-find-the-secret-key - Secret: '-' - Factions: - HideFactions: - - ExampleFaction - Towny: - HideTowns: - - ExampleTown \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_CN.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_CN.txt deleted file mode 100644 index b8e38af5a..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_CN.txt +++ /dev/null @@ -1,337 +0,0 @@ -Cmd - Click Me || 请点击此处 -Cmd - Link || §7 •§2 链接:§f -Cmd Disable - Disabled || §a现已禁用计划系统。您仍可使用 /planbungee reload 重启插件。 -Cmd FAIL - Invalid Username || §c[计划] 此玩家不存在。 -Cmd FAIL - No Feature || §e请设置要禁用的功能!(当前支持 ${0}) -Cmd FAIL - No Permission || §c[计划] 您没有所需权限。 -Cmd FAIL - Require only one Argument || §c[计划] 命令需要一个参数。 -Cmd FAIL - Requires Arguments || §c[计划] 命令缺少参数。${0} -Cmd FAIL - Unknown Username || §c[计划] 未在数据库中找到此玩家。 -Cmd FAIL - WebUser does not exists || §c用户不存在! -Cmd FAIL - WebUser exists || §c用户已存在! -Cmd Header - Analysis || §f»§2 玩家统计 - 统计结果 -Cmd Header - Info || §f»§2 玩家统计 - 信息 -Cmd Header - Inspect || §f»§2 玩家统计 - 检视结果: -Cmd Header - Network || > §2网络页面 -Cmd Header - Players || > §2玩家 -Cmd Header - Search || §f»§2 玩家统计 - 搜索结果: -Cmd Header - Servers || > §2服务器 -Cmd Header - Web Users || > §2${0} 个网页用户 -Cmd Info - Bungee Connection || §2已连接至 Bungee:§f${0} -Cmd Info - Database || §2可用数据库:§f${0} -Cmd Info - Reload Complete || §a重新载入完毕 -Cmd Info - Reload Failed || §c重载插件时发生错误,建议重新启动服务器。 -Cmd Info - Update || §2更新可用:§f${0} -Cmd Info - Version || §2版本:§f${0} -Cmd Notify - No WebUser || 您可能还没有网页账户,请输入 /plan register <密码> -Cmd Notify - WebUser register || 已注册新用户:'${0}' 权限级别:${1} -Cmd Qinspect - Activity Index || §2活跃指数:§f${0} | ${1} -Cmd Qinspect - Deaths || §2死亡数:§f${0} -Cmd Qinspect - Geolocation || §2从 §f${0} 登录 -Cmd Qinspect - Last Seen || §2最后在线:§f${0} -Cmd Qinspect - Longest Session || §2最长在线时间:§f${0} -Cmd Qinspect - Mob Kills || §2怪物击杀数:§f${0} -Cmd Qinspect - Player Kills || §2玩家击杀数:§f${0} -Cmd Qinspect - Playtime || §2游玩时间:§f${0} -Cmd Qinspect - Registered || §2注册时间:§f${0} -Cmd Qinspect - Times Kicked || §2踢出次数:§f${0} -Cmd Setup - Allowed || §a现已允许安装 -Cmd Setup - Bad Request || §e连接成功,但接收服务器不是 Bungee 服务器。请使用 Bungee 地址。 -Cmd Setup - Disallowed || §c现已禁止安装 -Cmd Setup - Forbidden || §e连接成功,但 Bungee 已禁用安装模式 - 请使用 '/planbungee setup' 启用。 -Cmd Setup - Gateway Error || §e连接成功,但 Bungee 无法与此服务器建立连接(是否重启了当前网页服务器?)请使用 /plan m con 与 /planbungee con 进行调试。 -Cmd Setup - Generic Fail || §e连接失败:${0} -Cmd Setup - Internal Error || §e连接成功。${0},请检查接收服务器调试页面的错误日志。 -Cmd Setup - Success || §a连接成功,计划可能将在几秒内重启··· -Cmd Setup - Unauthorized || §e连接成功,但接收服务器并未授权此服务器。请在 Discord 上联系以寻求帮助 -Cmd Setup - Url mistake || §c请确保您所输入的是完整地址(以 http:// 或 https:// 开头)- 请检查 Bungee 启用日志获取完整地址。 -Cmd Setup - WebServer not Enabled || §c未在此服务器上启用网页服务器!请确保其在开机时启用! -Cmd SUCCESS - Feature disabled || §a已在下次插件重载前暂时禁用 '${0}'。 -Cmd SUCCESS - WebUser register || §a已成功添加新用户(${0})!您可以在以下链接中查看Web面板。 -Cmd Update - Cancel Success || §a已完成取消操作。 -Cmd Update - Cancelled || §c已取消更新。 -Cmd Update - Change log || 更新日志 版本${0}: -Cmd Update - Fail Cacnel || §c某个服务器更新失败,正在取消所有服务器的更新··· -Cmd Update - Fail Force Notify || §e${0} 无法更新,但使用了 -force,正在继续更新。 -Cmd Update - Fail Not Online || §c并非所有服务器均在线或可访问,您仍可通过使用 /plan update -u -force 的方式强制更新。 -Cmd Update - Notify Cancel || §a您可以使用 /plan update cancel 以取消尚未重启的服务器上的更新。 -Cmd Update - Online Check || 正在检查是否所有服务器均在线··· -Cmd Update - Scheduled || §a已为 ${0} 计划了更新。 -Cmd Update - Url mismatch || §c版本下载网址不以 ${0} 开头故可能不受信任。您可手动下载此版本(直接下载): -Cmd Web - Permission Levels || >\§70:访问所有页面\§71:访问 '/players' 及所有玩家页\§72:访问用户名与网页用户名一致的玩家页\§73+:无权限 -Command Help - /plan analyze || 查看服务器分析 -Command Help - /plan dev || 开发模式命令 -Command Help - /plan help || 查看命令列表。 -Command Help - /plan info || 查看计划版本 -Command Help - /plan inspect || 检视玩家数据 -Command Help - /plan manage || 数据库管理命令 -Command Help - /plan manage backup || 备份数据库至 .db 文件 -Command Help - /plan manage clear || 从数据库中清空所有数据 -Command Help - /plan manage con || 调试服务器至 Bungee 的连接 -Command Help - /plan manage disable || 暂时禁用功能 -Command Help - /plan manage hotswap || 热插拔数据库并重启插件 -Command Help - /plan manage import || 从插件中导入数据 -Command Help - /plan manage move || 在数据库间移动数据 -Command Help - /plan manage remove || 从活跃数据库中移除玩家数据 -Command Help - /plan manage restore || 恢复数据库 -Command Help - /plan manage setup || 设置服务器至 Bungee 的连接 -Command Help - /plan network || 查看网络页面 -Command Help - /plan players || 列出所有已缓存玩家名单 -Command Help - /plan qinspect || 在游戏内检视玩家数据 -Command Help - /plan register || 注册网页用户 -Command Help - /plan reload || 重新启动插件(重载配置) -Command Help - /plan search || 搜索玩家 -Command Help - /plan servers || 列出数据库中的服务器 -Command Help - /plan update || 获取更新日志链接或更新插件 -Command Help - /plan web check || 检查网页用户的权限级别。 -Command Help - /plan web delete || 删除网页用户 -Command Help - /plan web level || 权限级别信息 -Command Help - /plan web list || 列出网页用户 -Command Help - /plan webuser || 管理网页用户 -Command Help - /planbungee con || 调试 Bungee 至服务器的连接 -Command Help - /planbungee disable || 暂时禁用插件 -Command Help - /planbungee setup || 开关设置功能 -Database - Apply Patch || 正在应用更新:${0}··· -Database - Patches Applied || 已成功应用所有数据库补丁。 -Database - Patches Applied Already || 已应用所有数据库补丁。 -Database MySQL - Launch Options Error || 启动参数出错,正使用默认参数(${0}) -Database Notify - Clean || 移除了 ${0} 位用户的数据。 -Database Notify - SQLite No WAL || 此服务器版本不支持 SQLite WAL 模式,正使用默认模式。这可能会影响性能。 -Disable || 已禁用插件。 -Disable - Processing || 正在处理未处理的关键任务。(${0}) -Disable - Processing Complete || 处理完毕。 -Disable - WebServer || 正在关闭网页服务器··· -Enable || 已启用插件。 -Enable - Database || ${0}-已建立数据库连接。 -Enable - Notify Address Confirmation || 确保此地址指向此服务器:${0} -Enable - Notify Empty IP || server.properties 中的 IP 为空且未使用替代 IP。这将会导致地址出错! -Enable - Notify Geolocations disabled || 已关闭地理位置收集。(Data.Geolocations: false) -Enable - Notify Geolocations Internet Required || 插件需要在首次运行时访问互联网以下载 GeoLite2 地理位置数据库。 -Enable - Notify Webserver disabled || 未初始化网页服务器。(WebServer.DisableWebServer: true) -Enable - WebServer || 正在初始化网页服务器··· -Enable FAIL - Database || ${0}-连接数据库失败:${1} -Enable FAIL - Database Patch || 数据库补丁失败,插件必须被禁用。请汇报此问题 -Enable FAIL - GeoDB Write || 保存已下载的 GeoLite2 地理位置数据库时发生问题 -Enable FAIL - WebServer (Bungee) || 网页服务器未初始化 -Enable FAIL - Wrong Database Type || ${0} 此数据类型不存在。 -HTML - ACTIVITY_INDEX || 活跃指数 -HTML - ALL || 全部 -HTML - ALL_TIME_PEAK || 所有时间峰值 -HTML - AVERAGE_PING || 平均延迟 -HTML - AVG || 平均 -HTML - BANNED || 已封禁 -HTML - BEST_PING || 最低延迟 -HTML - CALENDAR || 日历 -HTML - CALENDAR_TEXT || 日历 -HTML - CHUNKS || 区块 -HTML - COMMAND || 命令 -HTML - COMMNAND_USAGE || 使用命令 -HTML - CONNECTION_INFORMATION || 连接信息 -HTML - COUNTRY || 国家 -HTML - CURRENT_PLAYERBASE || 当前玩家 -HTML - DEATHS || 死亡数 -HTML - ENTITIES || 实体数 -HTML - ERROR || 认证时发生错误 -HTML - FAVORITE_SERVER || 喜爱的服务器 -HTML - GEOLOCATION || 地理位置 -HTML - GEOLOCATION_TEXT || 地理位置 -HTML - HEALTH_ESTIMATE || 预计健康度 -HTML - INDEX_ACTIVE || 活跃 -HTML - INDEX_INACTIVE || 不活跃 -HTML - INDEX_IRREGULAR || 偶尔上线 -HTML - INDEX_REGULAR || 经常上线 -HTML - INDEX_VERY_ACTIVE || 非常活跃 -HTML - IP_ADDRESS || IP 地址 -HTML - KILLED || 被击杀 -HTML - KILLED_BY || 击杀者 -HTML - LAST_24_HOURS || 过去 24 小时 -HTML - LAST_30_DAYS || 过去 30 天 -HTML - LAST_30_DAYS_TEXT || 过去 30 天 -HTML - LAST_7_DAYS || 过去 7 天 -HTML - LAST_CONNECTED || 最后连接 -HTML - LAST_PEAK || 上次峰值 -HTML - LAST_SEEN || 最后在线 -HTML - LAST_SEEN_TEXT || 最后在线 -HTML - LOADED_CHUNKS || 已加载的区块 -HTML - LOADED_ENTITIES || 已加载的实体 -HTML - LOCAL_MACHINE || 本机 -HTML - LONGEST || 最长 -HTML - LOW_TPS_SPIKES || 最低 TPS 值 -HTML - MOB_CAUSED_DEATHS || 被怪物击杀数 -HTML - MOB_KDR || 怪物击杀比 -HTML - MOB_KILLS || 怪物击杀数 -HTML - MOST_RECENT_SESSIONS || 最近时域 -HTML - NAME || 名称 -HTML - NAV_COMMAND_USAGE || 使用指令 -HTML - NAV_GEOLOCATIONS || 地理位置 -HTML - NAV_INFORMATION || 信息 -HTML - NAV_NETWORK_PLAYERS || 网络玩家 -HTML - NAV_ONLINE_ACTIVITY || 在线玩家 -HTML - NAV_OVERVIEW || 预览 -HTML - NAV_PERFORMANCE || 性能 -HTML - NAV_PLAYERS || 玩家 -HTML - NAV_PLUGINS || 插件 -HTML - NAV_SESSIONS || 时域 -HTML - NAV_SEVER_HEALTH || 服务器健康度 -HTML - NETWORK || 服务器网络 -HTML - NETWORK_INFORMATION || 服务器网络信息 -HTML - NEW || 新建 -HTML - NEW_CALENDAR || 新: -HTML - NEW_PLAYERS_TEXT || 新玩家 -HTML - NEW_RETENTION || 新玩家留坑率 -HTML - NEW_TEXT || 新建 -HTML - NICKNAME || 昵称 -HTML - NO_KILLS || 无击杀数 -HTML - NO_PLAYER_CAUSED_DEATHS || 无被玩家击杀数 -HTML - OFFLINE || 离线 -HTML - ONLINE || 在线 -HTML - ONLINE_ACTIVITY || 在线活动 -HTML - OPERATOR || 管理员 -HTML - OVERVIEW || 预览 -HTML - PER_DAY || / 天 -HTML - PLAYER_CAUSED_DEATHS || 被玩家击杀数 -HTML - PLAYER_KILLS || 玩家击杀数 -HTML - PLAYER_LIST || 玩家列表 -HTML - PLAYERBASE_DEVELOPMENT || 玩家发展 -HTML - PLAYERS || 玩家 -HTML - PLAYERS_ONLINE || 在线玩家 -HTML - PLAYERS_ONLINE_TEXT || 在线玩家 -HTML - PLAYERS_TEXT || 玩家 -HTML - PLAYTIME || 游玩时间 -HTML - PLEASE_WAIT || 请稍候··· -HTML - PREDICETED_RETENTION || 预计留坑率 -HTML - PUNCH_CARD || 打卡签到 -HTML - PUNCHCARD || 打卡签到 -HTML - RECENT_LOGINS || 近期登陆 -HTML - REGISTERED || 已注册 -HTML - REGISTERED_TEXT || 已注册 -HTML - REGULAR || 经常 -HTML - SEEN_NICKNAMES || 可视昵称 -HTML - SERVER || 服务器 -HTML - SERVER_ANALYSIS || 服务器分析 -HTML - SERVER_HEALTH_ESTIMATE || 服务器健康估计 -HTML - SERVER_INFORMATION || 服务器信息 -HTML - SERVER_PREFERENCE || 服务器偏好设置 -HTML - SERVERS || 服务器 -HTML - SESSION || 时域 -HTML - SESSION_ENDED || 时域之末 -HTML - SESSION_LENGTH || 时域长度 -HTML - SESSION_MEDIAN || 平均时域 -HTML - SESSIONS || 时域 -# Not sure if this is the time or count of numbers. -HTML - TIME || 次数 -HTML - TIMES_KICKED || 被踢次数 -HTML - TIMES_USED || 占用 -HTML - TOTAL_ACTIVE_TEXT || 总活跃玩家 -HTML - TOTAL_AFK || 总挂机玩家 -HTML - TOTAL_PLAYERS || 总玩家 -HTML - TOTAL_PLAYTIME || 总在线时长 -HTML - UNIQUE || 普通 -HTML - UNIQUE_CALENDAR || 普通玩家: -HTML - UNIQUE_PLAYERS || 普通玩家 -HTML - UNIQUE_PLAYERS_TEXT || 普通玩家 -HTML - UNIQUE_TEXT || 普通玩家 -HTML - USAGE || 占用 -HTML - USED_COMMANDS || 使用的命令 -HTML - USER_AND_PASS_NOT_SPECIFIED || 未指定用户名与密码 -HTML - USER_DOES_NOT_EXIST || 用户不存在 -HTML - USER_INFORMATION || 用户信息 -HTML - USER_PASS_MISMATCH || 用户名与密码不匹配 -HTML - WITH ||

    "+(this.isRTL?"":this.renderHeadIntroHtml())+this.renderHeadDateCellsHtml()+(this.isRTL?this.renderHeadIntroHtml():"")+""},e.prototype.renderHeadDateCellsHtml=function(){var t,e,n=[];for(t=0;t1?' colspan="'+e+'"':"")+(n?" "+n:"")+">"+(a?s.buildGotoAnchorHtml({date:t,forceOff:o.rowCnt>1||1===o.colCnt},i):i)+""},e.prototype.renderBgTrHtml=function(t){return""+(this.isRTL?"":this.renderBgIntroHtml(t))+this.renderBgCellsHtml(t)+(this.isRTL?this.renderBgIntroHtml(t):"")+""},e.prototype.renderBgIntroHtml=function(t){return this.renderIntroHtml()},e.prototype.renderBgCellsHtml=function(t){var e,n,i=[];for(e=0;e"},e.prototype.renderIntroHtml=function(){},e.prototype.bookendCells=function(t){var e=this.renderIntroHtml();e&&(this.isRTL?t.append(e):t.prepend(e))},e}(o.default);e.default=s},function(t,e){Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e){this.component=t,this.fillRenderer=e}return t.prototype.render=function(t){var e=this.component,n=e._getDateProfile().activeUnzonedRange,i=t.buildEventInstanceGroup(e.hasAllDayBusinessHours,n),r=i?e.eventRangesToEventFootprints(i.sliceRenderRanges(n)):[];this.renderEventFootprints(r)},t.prototype.renderEventFootprints=function(t){var e=this.component.eventFootprintsToSegs(t);this.renderSegs(e),this.segs=e},t.prototype.renderSegs=function(t){this.fillRenderer&&this.fillRenderer.renderSegs("businessHours",t,{getClasses:function(t){return["fc-nonbusiness","fc-bgevent"]}})},t.prototype.unrender=function(){this.fillRenderer&&this.fillRenderer.unrender("businessHours"),this.segs=null},t.prototype.getSegs=function(){return this.segs||[]},t}();e.default=n},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(3),r=n(4),o=function(){function t(t){this.fillSegTag="div",this.component=t,this.elsByFill={}}return t.prototype.renderFootprint=function(t,e,n){this.renderSegs(t,this.component.componentFootprintToSegs(e),n)},t.prototype.renderSegs=function(t,e,n){var i;return e=this.buildSegEls(t,e,n),i=this.attachSegEls(t,e),i&&this.reportEls(t,i),e},t.prototype.unrender=function(t){var e=this.elsByFill[t];e&&(e.remove(),delete this.elsByFill[t])},t.prototype.buildSegEls=function(t,e,n){var r,o=this,s="",a=[];if(e.length){for(r=0;r"},t.prototype.attachSegEls=function(t,e){},t.prototype.reportEls=function(t,e){this.elsByFill[t]?this.elsByFill[t]=this.elsByFill[t].add(e):this.elsByFill[t]=i(e)},t}();e.default=o},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(13),r=n(36),o=n(6),s=function(){function t(t,e){this.view=t._getView(),this.component=t,this.eventRenderer=e}return t.prototype.renderComponentFootprint=function(t){this.renderEventFootprints([this.fabricateEventFootprint(t)])},t.prototype.renderEventDraggingFootprints=function(t,e,n){this.renderEventFootprints(t,e,"fc-dragging",n?null:this.view.opt("dragOpacity"))},t.prototype.renderEventResizingFootprints=function(t,e,n){this.renderEventFootprints(t,e,"fc-resizing")},t.prototype.renderEventFootprints=function(t,e,n,i){var r,o=this.component.eventFootprintsToSegs(t),s="fc-helper "+(n||"");for(o=this.eventRenderer.renderFgSegEls(o),r=0;r
    ${0}${1}${2}${3}
    ${0}${1}
    ${0}${1}${2}
    ${0}${1}${2}${3}
    ${0}${1}${3}${4}${6}${8}${9}
    ${0}${2}${3}${4}${5}${6}
    ${1}${3}${5}
    ${1}${2}${3}
    与 -HTML - WORLD || 世界 -HTML - WORLD_LOAD || 世界加载 -HTML - WORLD_PLAYTIME || 世界游玩时间 -HTML - WORST_PING || 最高延迟 -HTML ERRORS - ACCESS_DENIED_403 || 拒绝访问 -HTML ERRORS - ANALYSIS_REFRESH || 正在刷新分析··· -HTML ERRORS - ANALYSIS_REFRESH_LONG || 正在执行分析,请在几秒后刷新页面··· -HTML ERRORS - AUTH_FAIL_TIPS_401 || - 确保您已使用 /plan register 注册用户
    - 检查用户名与密码是否正确
    - 用户名与密码区分大小写

    若您忘记了密码,请让工作人员删除您的旧密码并重新注册。 -HTML ERRORS - AUTHENTICATION_FAILED_401 || 认证失败。 -HTML ERRORS - FORBIDDEN_403 || 禁止访问 -HTML ERRORS - NO_SERVERS_404 || 无可执行此请求的在线服务器。 -HTML ERRORS - NOT_FOUND_404 || 未找到 -HTML ERRORS - NOT_PLAYED_404 || 玩家从未在此服务器上游玩过。 -HTML ERRORS - PAGE_NOT_FOUND_404 || 页面不存在。 -HTML ERRORS - UNAUTHORIZED_401 || 未认证 -HTML ERRORS - UNKNOWN_PAGE_404 || 请确保您正通过命令所给出的链接访问,示例:

    /player/玩家名
    /server/服务器名

    -HTML ERRORS - UUID_404 || 未在数据库中找到玩家的 UUID。 -In Depth Help - /plan ? || §2/plan - 主命令\§f 用于访问所有子命令及帮助\§7 /plan - 列出子命令\§7 /plan <子命令> ? - 详细帮助 -In Depth Help - /plan analyze ? || §2分析命令\§f 用于刷新分析缓存及访问结果页面\§7 /plan status 可用于在网页在线时检查分析状态fen.\§7 别名:analyze, analyse, analysis, a -In Depth Help - /plan inspect ? || §2检视命令\§f 用于获取用户检视页链接。\§7 个人检视页可通过输入 /plan inspect 访问\§7 别名:/plan <名称> -In Depth Help - /plan manage ? || §2管理命令\§f 用于管理插件数据库。\§7 别名:/plan m\§7 /plan m - Auflistung der Unterbefehle\§7 /plan m <子命令> ? - 详细帮助 -In Depth Help - /plan manage backup ? || > §2备份命令\ 用于建立新 SQLite 数据库(.db 文件)并包含当前在计划插件文件夹中所有的活跃数据库内容。 -In Depth Help - /plan manage clear ? || §2管理清除命令\§f 用于清除活跃数据库中的所有数据。\§7 插件在清理完毕后应被重载。\§7 别名:/plan pl -In Depth Help - /plan manage con ? || > §2调试连接命令\ 用于调试网络间的连接。\ 向数据库中的每个服务器发送请求。 -In Depth Help - /plan manage disable ? || > §2禁用命令\ 用于在下次重新载入之前禁用插件的部分特性。\ 接受的参数:\ §2kickcount §f禁用在关闭服务器时 /kickall 的踢出计数。 -In Depth Help - /plan manage import ? || §2管理导入命令\§f 用于从其它来源导入数据\§7 在导入过程中将禁用数据分析。 -In Depth Help - /plan manage move ? || > §2移动指令\ 将数据从 SQLite 移动至 MySQL,反之亦然。\ 目标数据库将在转移前被清除。 -In Depth Help - /plan manage remove ? || §2管理移除命令\§f 用于从活跃数据库中移除用户数据。 -In Depth Help - /plan manage restore ? || > §2恢复命令\ 从先前备份的 SQLite 数据库中恢复数据(.db 文件)\ 您也可以从其他服务器中恢复 database.db 到 MySQL。\ 目标数据库将在传输前被清除。 -In Depth Help - /plan manage setup ? || > §2安装命令\ 设置 Bungee 与此服务器之间的网络连接。\ Bungee 地址可在计划于 Bungee 上启动时的控制台日志中找到。 -In Depth Help - /plan network ? || > §2网络命令\ 显示到网络页的链接。\ 若不在群组网络上,此页面将显示为服务器页面。 -In Depth Help - /plan players ? || > §2玩家命令\ 显示到玩家页的链接。 -In Depth Help - /plan qinspect ? || §2快速检视命令\§f 用于获取游戏内关于检视的信息。\§7 相比检视网页有着更少的信息。\§7 别名:/plan qi -In Depth Help - /plan reload ? || > §2重载命令\ 使用 onDisable 与 onEnable 重新载入插件。\ §b不支持运行时热切换插件 -In Depth Help - /plan search ? || §2搜索命令\§f 用于获取匹配特定参数的玩家名列表。\§7 示例:/plan search 123 - 搜索名称中包含 123 的所有玩家。 -In Depth Help - /plan servers ? || > §2服务器命令\ 显示数据库中的计划服务器列表。\ 可用于调试在网络上数据库注册的问题。 -In Depth Help - /plan update ? || > §2更新命令\ 用于在下次关闭服务器时更新插件\ /plan update - 更新日志链接\ /plan update -u - 在所有在线的网络服务器上预定在下次重新启动时更新。\ /plan update cancel - 取消尚未重启的服务器上的更新。 -In Depth Help - /plan web ? || < §2网页用户管理命令。\ §2/plan web §f列出子命令\ §2/plan web <子命令> ? §f详细帮助 -In Depth Help - /plan web register ? || > §2注册命令\ 注册一位新的网页用户。\ 为其他用户注册需要 plan.webmanage 权限。\ 密码通过使用随机密码盐的 PBKDF2 哈希方法加密(重复 64000 次 SHA1)。 -In Depth Help - /planbungee disable ? || > §2禁用命令\ 在 PlanBungee 上运行 onDisable。\ 插件之后需要运行 /planbungee reload 以重新启用。\ §b不支持运行时热切换插件 -In Depth Help - /planbungee setup ? || > §2设置开关命令\ 开关 Bungee 上的安装功能。\ 用来防止与其他服务器之间未授权的 MySQL 监听。 -Manage - Confirm Overwrite || 数据库 ${0} 中的数据将被覆盖! -Manage - Confirm Removal || 数据库 ${0} 中的数据将被移除! -Manage - Fail || > §c[计划] 处理数据时发生错误! ${0} -Manage - Fail File not found || > §c[计划] 备份文件不存在! ${0} -Manage - Fail Incorrect Database || > §c'${0}' 不是一个支持的数据库。 -Manage - Fail No Importer || §e导入器 '${0}' 不存在 -Manage - Fail Same Database || > §c[计划] 无法移动至相同的数据库! -Manage - Fail, Confirmation || > §c[计划] 请添加 -a 以确认执行!${0} -Manage - Fail, Connection Exception || §e失败原因: -Manage - Fail, No Servers || §c未在数据库中找到服务器。 -Manage - Fail, Old version || §e失败原因:接收服务器使用了旧版本的插件。 -Manage - Fail, Unauthorized || §e失败原因:未获得授权。服务器可能使用不同的数据库。 -Manage - Fail, Unexpected Exception || §e异常例外:${0} -Manage - List Importers || 导入器: -Manage - Notify External Url || §e非本地地址,请检查端口是否开放 -Manage - Remind HotSwap || §e[计划] 请记住要切换至新数据库并重新载入插件(/plan m hotswap ${0}) -Manage - Start || »§7 正在处理数据··· -Manage - Success || §f» §2 成功! -Negative || 否 -Positive || 是 -Unknown || 未知 -Version - DEV || 这是开发者版本。 -Version - Latest || 您正使用最新版本。 -Version - New || 新版本(${0})可用 ${1} -Version - New (old) || 新版本在 ${0} 可用 -Version FAIL - Read info (old) || 无法检查最新版本号 -Version FAIL - Read versions.txt || 无法从 Github/versions.txt 载入版本信息 -Web User Listing || §2${0} §7:§f${1} -WebServer - Notify HTTP || 网页服务器:无证书 -> 正使用 HTTP 服务器提供可视化效果。 -WebServer - Notify HTTP User Auth || 网页服务器:已禁用用户认证!(HTTP 方式不安全) -WebServer - Notify no Cert file || 网页服务器:未找到证书密钥存储文件:${0} -WebServer FAIL - Port Bind || 未成功初始化网页服务器。端口(${0})是否被占用? -WebServer FAIL - SSL Context || 网页服务器:SSL 环境初始化失败。 -WebServer FAIL - Store Load || 网页服务器:SSL 证书载入失败。 -Yesterday || '昨天' -Today || '今天' -Health - Active Playtime Comparison Decrease || 玩家可能闲得没事干了 (活跃玩家数 ${0} vs ${1}, 最近2周 vs 2-4周) -Health - Active Playtime Comparison Increase || 玩家可能有很多事要做 (活跃玩家数 ${0} vs ${1}, 最近2周 vs 2-4周) -Health - Downtime || 服务器停机时间为 (无数据传输的时间) ${0} -Health - New Player Join Players, No || 新玩家里也许很少有人继续玩下去 (平均为 ${0} ) -Health - New Player Join Players, Yes || 新玩家里有人玩了下去 (平均为 ${0} ) -Health - New Player Stickiness || ${0} 的新玩家留了下来 (${1}/${2}) -Health - No Servers Inaccuracy || 没有可收集数据的 Bukkit/Sponge 服务器 - 这些数据不准确. -Health - Player Play on Network || 在这个服务器网络内游玩的玩家: -Health - Player Register Server || 平均每日每服务器注册玩家数. -Health - Player Visit Server || 平均每日每服务器登录服务器玩家数. -Health - Regular Activity Change || 普通玩家数 -Health - Regular Activity Change Decrease || 减少了 (${0}) -Health - Regular Activity Change Increase || 增加了 (+${0}) -Health - Regular Activity Change Zero || 保持不变 (+${0}) -Health - Regular Activity Remain || ${0} 普通玩家仍保持活跃 (${1}/${2}) -Health - Single Servers Inaccuracy || 收集单个 Bukkit/Sponge 服务器的时域数据. -Health - TPS Above Low Threshold || ${0} 的平均TPS超过了最低门槛 -Health - TPS Low Dips || 平均TPS低于最低门槛 (${0}) ${1} 此 -HTML - FREE_DISK_SPACE || 剩余磁盘空间 -HTML - DISK_SPACE || 磁盘空间 \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_DE.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_DE.txt deleted file mode 100644 index 548b8a099..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_DE.txt +++ /dev/null @@ -1,336 +0,0 @@ -Cmd - Click Me || Klicke hier -Cmd - Link || §2Link: §f -Cmd Disable - Disabled || §aPlan ist nun deaktiviert. Nutze /planbungee reload um das Plugin neu zu starten. -Cmd FAIL - Invalid Username || §cDieser Benutzer besitzt keine UUID. -Cmd FAIL - No Feature || §eWelches Feature soll deaktiviert werden? (momentan unterstützt: ${0}) -Cmd FAIL - No Permission || §cDafür fehlt dir die Berechtigung. -Cmd FAIL - Require only one Argument || §cNur ein Argument erforderlich ${1} -Cmd FAIL - Requires Arguments || §cArgumente erforderlich (${0}) ${1} -Cmd FAIL - Unknown Username || §cDieser Benutzer war noch nie auf dem Server. -Cmd FAIL - WebUser does not exists || §cDieser Benutzer existiert nicht! -Cmd FAIL - WebUser exists || §cDieser Benutzer existiert schon! -Cmd Header - Analysis || > §2Analyse-Ergebnis: -Cmd Header - Info || > §2Benutzeranalyse: -Cmd Header - Inspect || > §2Benutzer: §f${0} -Cmd Header - Network || > §2Netzwerkseite -Cmd Header - Players || > §2Spieler -Cmd Header - Search || > §2${0} Ergebnisse für §f${1}§2: -Cmd Header - Servers || > §2Server -Cmd Header - Web Users || > §2${0} Accounts -Cmd Info - Bungee Connection || §2Verbunden mit Bungee: §f${0} -Cmd Info - Database || §2Genutzte Datenbank: §f${0} -Cmd Info - Reload Complete || §aReload erfolgreich. -Cmd Info - Reload Failed || §cBeim Reload ist etwas schief gelaufen. Es wird empfohlen, den Server neuzustarten. -Cmd Info - Update || §2Update verfügbar: §f${0} -Cmd Info - Version || §2Version: §f${0} -Cmd Notify - No WebUser || Möglicherweise hast du keinen Account. Erstelle einen mit /plan register -Cmd Notify - WebUser register || Neuer Account hinzugefügt: '${0}' Rechte-Level: ${1} -Cmd Qinspect - Activity Index || §2Aktivitätsindex: §f${0} | ${1} -Cmd Qinspect - Deaths || §2Tode: §f${0} -Cmd Qinspect - Geolocation || §2Eingeloggt aus: §f${0} -Cmd Qinspect - Last Seen || §2Zuletzt gesehen: §f${0} -Cmd Qinspect - Longest Session || §2Längste Session: §f${0} -Cmd Qinspect - Mob Kills || §2Getötete Mobs: §f${0} -Cmd Qinspect - Player Kills || §2Getötete Spieler: §f${0} -Cmd Qinspect - Playtime || §Spielzeit: §f${0} -Cmd Qinspect - Registered || §2Registrierung: §f${0} -Cmd Qinspect - Times Kicked || §2Kicks: §f${0} -Cmd Setup - Allowed || §aSetupmodus wurde aktiviert. -Cmd Setup - Bad Request || §eVerbindung hergestellt. Der empfangende Server ist ein Bukkit- oder Sponge-server. Nutze stattdessen die andere Adresse. -Cmd Setup - Disallowed || §cSet-up wurde deaktiviert. -Cmd Setup - Forbidden || §eVerbindung hergestellt aber der Bungeecordserver hat den Setupmodus nicht aktiviert. Nutze '/planbungee setup' um ihn zu aktivieren. -Cmd Setup - Gateway Error || §eVerbindung hergestellt, aber der Bungeecordserver konnte sich nicht mit diesem Server verbinden (Wurde der aktuelle Server neugestartet?). Nutze /plan m con & /planbungee con zum debuggen. -Cmd Setup - Generic Fail || §eVerbindung fehlgeschlagen: ${0} -Cmd Setup - Internal Error || §eVerbindung hergestellt. ${0}, eventuelle Fehler kannst du dem Error-Log auf der Debugseite des empfangenden Servers entnehmen. -Cmd Setup - Success || §aVerbindung erfolgreich, Plan startet eventuell in ein paar Sekunden neu. -Cmd Setup - Unauthorized || §eVerbindung erfolgreich, aber der empfangende Server hat diesen Server nicht autorisiert. Auf dem Plan-Discord bekommst du Hilfe. -Cmd Setup - Url mistake || §cNutze die gesamte Adresse (Beginnend mit http:// oder https://) - Diese kannst du dem Bungee enable log entnehmen. -Cmd Setup - WebServer not Enabled || §cWebServer ist auf diesem Server deaktiviert! Dies sollte beim Start aktiviert werden! -Cmd SUCCESS - Feature disabled || §a'${0}' wurde bis zum nächsten Reload des Plugins deaktiviert. -Cmd SUCCESS - WebUser register || §aNeuer Account (${0}) erfolgreich hinzugefügt! Sie können das Web-Panel über den folgenden Link anzeigen. -Cmd Update - Cancel Success || §aErfolgreich abgebrochen. -Cmd Update - Cancelled || §cUpdate abgebrochen. -Cmd Update - Change log || Change Log v${0}: -Cmd Update - Fail Cacnel || §cAuf einem Server war das Update nicht erfolgreich. Das Update wird auf allen Servern abgebrochen -Cmd Update - Fail Force Notify || §e${0} wurde nicht geupdated, -force wurde angegeben, fahre mit Updates fort. -Cmd Update - Fail Not Online || §cNicht alle Server sind online oder erreichbar. Erreichbare Server kannst du mit /plan update -u -force updaten -Cmd Update - Notify Cancel || §aDu kannst das Update auf Servern, die noch nicht neugestartet wurden, verwerfen mit: /plan update cancel. -Cmd Update - Online Check || Überprüfe ob alle Server online sind. -Cmd Update - Scheduled || §aUpdate für ${0} geplant. -Cmd Update - Url mismatch || §cDie Download-URL beginnt nicht mit ${0} und ist evtl. nicht vertrauenswürdig. Du kannst diese Version manuell hier downloaden (direkter Download): -Cmd Web - Permission Levels || >\§70: Zugriff auf alle Seiten\§71: Zugriff auf '/players' Und alle Spielerseiten\§72: Zugriff auf alle Spielerseiten mit dem gleichen Username wie der Web-Account\§73+: Keine Berechtigung -Command Help - /plan analyze || Server-Übersicht -Command Help - /plan dev || Entwicklungsmodus-Befehl -Command Help - /plan help || Zeigt eine Befehlsliste an -Command Help - /plan info || Zeigt die Version von Plan an -Command Help - /plan inspect || Zeigt eine Spielerseite an -Command Help - /plan manage || Verwaltet die Plan-Datenbank -Command Help - /plan manage backup || Erstellt ein Backup der Datenbank -Command Help - /plan manage clear || Datenbank leeren -Command Help - /plan manage con || Debug Server-Bungee Verbindungen -Command Help - /plan manage disable || Schalte eine Funktion temporär aus -Command Help - /plan manage hotswap || Ändere die Datenbank schnell -Command Help - /plan manage import || Daten importieren -Command Help - /plan manage move || Bewege die Daten zwischen den Datenbanken -Command Help - /plan manage remove || Entferne die Daten eines Spielers -Command Help - /plan manage restore || Spiele ein Backup ein -Command Help - /plan manage setup || Stelle die Server-Bungee-Verbindung her -Command Help - /plan network || Netzwerk-Seite -Command Help - /plan players || Spieler-Seite -Command Help - /plan qinspect || Zeigt die Spielerinfo im Spiel -Command Help - /plan register || Registriere einen Account -Command Help - /plan reload || Plan neuladen -Command Help - /plan search || Nach einem Spieler suchen -Command Help - /plan servers || Liste die Server in der Datenbank auf -Command Help - /plan update || Zeige das Änderungsprotokoll oder update den Server -Command Help - /plan web check || Infos über einen Account -Command Help - /plan web delete || Lösche einen Account -Command Help - /plan web level || Informationen über Rechte -Command Help - /plan web list || Liste Accounts -Command Help - /plan webuser || Verwalte Accounts -Command Help - /planbungee con || Debug Bungee-Server Verbindungen -Command Help - /planbungee disable || Deaktiviert das Plugin temporär -Command Help - /planbungee setup || Schaltet Setup-Modus an oder aus -Database - Apply Patch || Wende Patch an: ${0}.. -Database - Patches Applied || Alle Datenbankpatches wurden erfolgreich angewendet. -Database - Patches Applied Already || Alle Datenbankpatches wurden bereits angewendet. -Database MySQL - Launch Options Error || Startoptionen sind falsch, nutze Voreinstellungen (${0}) -Database Notify - Clean || Daten von ${0} Spielern gelöscht. -Database Notify - SQLite No WAL || SQLite WAL wird auf dieser Serverversion nicht unterstützt, nutze Voreinstellungen. Dies beeinträchtigt möglicherweise die Serverperformance. -Disable || Player Analytics ausgeschaltet. -Disable - Processing || Verarbeite kritische unverarbeitete Aufgaben. (${0}) -Disable - Processing Complete || Verarbeitung komplett. -Disable - WebServer || Webserver deaktiviert. -Enable || Player Analytics eingeschaltet. -Enable - Database || ${0}-dDatenbankverbindung hergestellt. -Enable - Notify Address Confirmation || Versichere dich, dass die Adresse auf DIESEN Server verweist: ${0} -Enable - Notify Empty IP || IP in der server.properties ist leer & AlternativeIP ist nicht in Verwendung. Es werden falsche Links verwendet! -Enable - Notify Geolocations disabled || Geolocation wird nicht aufgezeichnet (Data.Geolocations: false) -Enable - Notify Geolocations Internet Required || Plan braucht einen Internetzugang um die GeoLite2 Geolocation Datenbank runterzuladen. -Enable - Notify Webserver disabled || WebServer wurde nicht geladen. (WebServer.DisableWebServer: true) -Enable - WebServer || Webserver läuft auf PORT ${0} (${1}) -Enable FAIL - Database || ${0}-Datenbankverbindung fehlgeschlagen: ${1} -Enable FAIL - Database Patch || Datenbank-Patch ist fehlgeschlagen. Plugin wurde deaktiviert. Wir bitten dich, uns diesen Vorfall mitzuteilen. -Enable FAIL - GeoDB Write || Etwas ist beim Speichern der GeoLite2 Geolocation Datenbank fehlgeschlagen -Enable FAIL - WebServer (Bungee) || Webserver ist nicht geladen -Enable FAIL - Wrong Database Type || ${0} ist keine gültige Datenbank -HTML - ACTIVITY_INDEX || Aktivitätsindex -HTML - ALL || Gesamt -HTML - ALL_TIME_PEAK || Rekord -HTML - AVERAGE_PING || Durchschnittlicher Ping -HTML - AVG || AVG -HTML - BANNED || Gebannt -HTML - BEST_PING || Bester Ping -HTML - CALENDAR || KALENDER -HTML - CALENDAR_TEXT || Kalender -HTML - CHUNKS || Chunks -HTML - COMMAND || Befehl -HTML - COMMNAND_USAGE || Befehlsverwendung -HTML - CONNECTION_INFORMATION || Verbindungsinformationen -HTML - COUNTRY || Land -HTML - CURRENT_PLAYERBASE || Aktuelle Playerbase -HTML - DEATHS || Tode -HTML - ENTITIES || Entitäten -HTML - ERROR || Authentifikation fehlgeschlagen -HTML - FAVORITE_SERVER || Lieblingsserver -HTML - GEOLOCATION || Geolocation -HTML - GEOLOCATION_TEXT || Geolocation -HTML - HEALTH_ESTIMATE || Geschätzte Gesundheit -HTML - INDEX_ACTIVE || Aktiv -HTML - INDEX_INACTIVE || Inaktiv -HTML - INDEX_IRREGULAR || Unregelmäßig -HTML - INDEX_REGULAR || Regelmäßig -HTML - INDEX_VERY_ACTIVE || Sehr aktiv -HTML - IP_ADDRESS || IP-Adresse -HTML - KILLED || Getötet -HTML - KILLED_BY || Getötet von -HTML - LAST_24_HOURS || Letzte 24 Stunden -HTML - LAST_30_DAYS || Letzte 30 Tage -HTML - LAST_30_DAYS_TEXT || Letzte 30 Tage -HTML - LAST_7_DAYS || Letzte 7 Tage -HTML - LAST_CONNECTED || Letzte Verbindung -HTML - LAST_PEAK || Letzter Höchststand -HTML - LAST_SEEN || Zuletzt gesehen -HTML - LAST_SEEN_TEXT || Zuletzt gesehen -HTML - LOADED_CHUNKS || Geladene Chunks -HTML - LOADED_ENTITIES || Geladenen Entitäten -HTML - LOCAL_MACHINE || Lokale Maschine -HTML - LONGEST || Längste -HTML - LOW_TPS_SPIKES || Geringe TPS Spikes -HTML - MOB_CAUSED_DEATHS || Tode durch Mobs -HTML - MOB_KDR || Mob KDR -HTML - MOB_KILLS || Mob Kills -HTML - MOST_RECENT_SESSIONS || Letzte Sessions -HTML - NAME || Name -HTML - NAV_COMMAND_USAGE || Befehlsverwendung -HTML - NAV_GEOLOCATIONS || Geolocations -HTML - NAV_INFORMATION || Information -HTML - NAV_NETWORK_PLAYERS || Netzwerk Spieler -HTML - NAV_ONLINE_ACTIVITY || Onlineaktivität -HTML - NAV_OVERVIEW || Übersicht -HTML - NAV_PERFORMANCE || Performance -HTML - NAV_PLAYERS || Spieler -HTML - NAV_PLUGINS || Plugins -HTML - NAV_SESSIONS || Sessions -HTML - NAV_SEVER_HEALTH || Servergesundheit -HTML - NETWORK || Netzwerk -HTML - NETWORK_INFORMATION || Netzwerkinformationen -HTML - NEW || Neu -HTML - NEW_CALENDAR || Neu: -HTML - NEW_PLAYERS_TEXT || Neue Spieler -HTML - NEW_RETENTION || Erhaltung neuer Spieler -HTML - NEW_TEXT || Neu -HTML - NICKNAME || Nickname -HTML - NO_KILLS || Keine Kills -HTML - NO_PLAYER_CAUSED_DEATHS || Keine Tode durch Spieler -HTML - OFFLINE || Offline -HTML - ONLINE || Online -HTML - ONLINE_ACTIVITY || ONLINE AKTIVITÄT -HTML - OPERATOR || Operator -HTML - OVERVIEW || ÜBERSICHT -HTML - PER_DAY || / Tag -HTML - PLAYER_CAUSED_DEATHS || Tode durch Spieler -HTML - PLAYER_KILLS || Getötete Spieler -HTML - PLAYER_LIST || Spielerliste -HTML - PLAYERBASE_DEVELOPMENT || Entwicklung der Playerbase -HTML - PLAYERS || SPIELER -HTML - PLAYERS_ONLINE || SPIELER ONLINE -HTML - PLAYERS_ONLINE_TEXT || Spieler Online -HTML - PLAYERS_TEXT || Spieler -HTML - PLAYTIME || Spielzeit -HTML - PLEASE_WAIT || Bitte warten... -HTML - PREDICETED_RETENTION || Vorhersage Erhaltung -HTML - PUNCH_CARD || Lochkarte -HTML - PUNCHCARD || LOCHKARTE -HTML - RECENT_LOGINS || Letzte LOGINS -HTML - REGISTERED || REGISTRIERT -HTML - REGISTERED_TEXT || Registriert -HTML - REGULAR || REGELMÄSSIGE -HTML - SEEN_NICKNAMES || Registrierte Nicknames -HTML - SERVER || Server -HTML - SERVER_ANALYSIS || Server Analyse -HTML - SERVER_HEALTH_ESTIMATE || Server Gesundheitsschätzung -HTML - SERVER_INFORMATION || SERVER Information -HTML - SERVER_PREFERENCE || Bevorzugter Server -HTML - SERVERS || Server -HTML - SESSION || Session -HTML - SESSION_ENDED || Session beendet -HTML - SESSION_LENGTH || Session Länge -HTML - SESSION_MEDIAN || Session Durchschnitt -HTML - SESSIONS || Sessions -HTML - TIME || Zeit -HTML - TIMES_KICKED || Mal gekickt -HTML - TIMES_USED || Mal benutzt -HTML - TOTAL_ACTIVE_TEXT || Gesamte Aktive Spielzeit -HTML - TOTAL_AFK || Gesamte AFK-Zeit -HTML - TOTAL_PLAYERS || Gesamte Spieler -HTML - TOTAL_PLAYTIME || Gesamte Spielzeit -HTML - UNIQUE || EINZIGARTIG -HTML - UNIQUE_CALENDAR || Einzigartig: -HTML - UNIQUE_PLAYERS || EINZIGARTIGE SPIELER -HTML - UNIQUE_PLAYERS_TEXT || Einzigartige Spieler -HTML - UNIQUE_TEXT || Einzigartig -HTML - USAGE || Nutzung -HTML - USED_COMMANDS || Benutzte Befehle -HTML - USER_AND_PASS_NOT_SPECIFIED || User und Passwort nicht spezifiziert -HTML - USER_DOES_NOT_EXIST || User existiert nicht -HTML - USER_INFORMATION || USER INFORMATION -HTML - USER_PASS_MISMATCH || User und Password stimmen nicht überein -HTML - WITH ||
    Breite -HTML - WORLD || Welt -HTML - WORLD_LOAD || Weltenladung -HTML - WORLD_PLAYTIME || Spielzeit in der Welt -HTML - WORST_PING || Schlechtester Ping -HTML ERRORS - ACCESS_DENIED_403 || Zugriff verweigert -HTML ERRORS - ANALYSIS_REFRESH || Plan wird aktualisiert... -HTML ERRORS - ANALYSIS_REFRESH_LONG || Plan wird ausgeführt. Es wird in ein paar Sekunden neu geladen. -HTML ERRORS - AUTH_FAIL_TIPS_401 || - Stelle sicher, dass du einen Account mit /plan register hinzugefügt hast.
    - Überprüfe, ob Passwort und Benutzername korrekt sind
    - Bei Benutzername und Passwort auf Groß- und Kleinschreibung achten!

    - Wenn du dein Passwort vergessen hast, bitte ein Teammitglied deinen Account zu löschen und neu zu erstellen. -HTML ERRORS - AUTHENTICATION_FAILED_401 || Authentifizierung fehlgeschlagen. -HTML ERRORS - FORBIDDEN_403 || Verboten -HTML ERRORS - NO_SERVERS_404 || Keine Server online, die die Anfrage ausführen können. -HTML ERRORS - NOT_FOUND_404 || Nicht gefunden. -HTML ERRORS - NOT_PLAYED_404 || Der Spieler war nie auf dem Server. -HTML ERRORS - PAGE_NOT_FOUND_404 || Diese Seite existiert nicht. -HTML ERRORS - UNAUTHORIZED_401 || Unautorisiert -HTML ERRORS - UNKNOWN_PAGE_404 || Stelle sicher, dass du einen Link benutzt, der von einem Befehl generiert wurde. Beispielsweise:

    /player/PlayerName
    /server/ServerName

    -HTML ERRORS - UUID_404 || Die UUID des Spielers wurde nicht in der Datenbank gefunden. -In Depth Help - /plan ? || > §2Hauptbefehl\ Zugriff auf Unterbefehle und Hilfe\ §2/plan §fListe Unterbefehle\ §2/plan ? §fAusführliche Hilfe -In Depth Help - /plan analyze ? || > §2Analysebefehl\ Aktualisiert die Serverseite und stellt einen Zugriffslink bereit. -In Depth Help - /plan inspect ? || > §2Inspect-Befehl\ Aktualisiert die Spielerseite und stellt einen Zugriffslink bereit. -In Depth Help - /plan manage ? || > §2Manage-Befehl\ Verwalte die MySQL und SQLite Datenbank von Plan.\ §2/plan m §fListe Unterbefehle\ §2/plan m ? §fAusführliche Hilfe -In Depth Help - /plan manage backup ? || > §2Backup-Unterbefehl\ Erstellt eine neue SQLite Datenbank (.db file) mit dem Inhalt der aktuell aktiven Datenbank im Plugin-Ordner -In Depth Help - /plan manage clear ? || > §2Clear-Unterbefehl\ Entfernt ALLES aus der aktuellen Datenbank. Vorsicht! -In Depth Help - /plan manage con ? || > §2Verbindungs-Debug-Unterbefehl\ Zum debuggen der Verbindungen im Netzwerk.\ Schickt eine Anfrage an jeden Server in der Datenbank. -In Depth Help - /plan manage disable ? || > §2Ausschalten-Subcommand\ Damit können Teile des Plugins bis zum nächsten Neustart ausgeschaltet werden.\ Akzeptierte Argumente:\ §2kickcount §fDeaktiviert den Zähler für Kicks falls /kickall im Ausschalt-Makro genutzt wird. -In Depth Help - /plan manage import ? || > §2Import-Unterbefehl\ Importiere Daten aus anderen Quellen.\ Akzeptierte Argumente:\ §2offline §fBukkit Spielerdaten, registriere nur Name und Datum. -In Depth Help - /plan manage move ? || > §2Move-Unterbefehl\ Verschiebe die Daten von SQLite zu MySQL oder andersherum\ Zieldatenbank wird vor dem Transfer geleert. -In Depth Help - /plan manage remove ? || > §2Remove-Unterbefehl\ Löscht die Daten eines Spielers aus der Datenbank. -In Depth Help - /plan manage restore ? || > §2Restore-Unterbefehl\ Stellt ein Backup einer SQLite Datenbank (.db file) wieder her\ Die database.db kann auch von einem anderen Server zu MySQL wiederhergestellt werden.\ Zieldatenbank wird vor dem Transfer geleert. -In Depth Help - /plan manage setup ? || > §2Setup Unterbefehl\ Richte eine Verbindung zwischen Bungee und diesem Server für Netzwerkfunktionalität ein.\ Die Bungee-Adresse kann dem Log in der Bungee-Konsole entnommen werden, wenn Plan aktiviert wird. -In Depth Help - /plan network ? || > §2Netzwerk-Befehl\ Erstellt einen Link zur Netzwerkseite. Wenn du in einem Netzwerk bist, wird die Serverseite angezeigt. -In Depth Help - /plan players ? || > §2Spieler-Befehl\ Erstellt einen Link zur Spielerseite. -In Depth Help - /plan qinspect ? || > §2Schnell-Untersuchungs-Befehl\ Zeigt einige Informationen zu einem Spieler im Spiel. -In Depth Help - /plan reload ? || > §2Reload-Befehl\ Restartet das plugin mit onDisable and onEnable.\ §bDamit kann NICHT die jar getauscht werden -In Depth Help - /plan search ? || > §2Such-Befehl\ Erstellt eine Liste mit Spielernamen, die mit der Suche übereinstimmen.\§7 Beispiel: /plan search 123 - Gibt alle Spieler mit 123 im Namen aus. -In Depth Help - /plan servers ? || > §2Server-Command\ Zeigt eine Liste mit allen Servern in der datenbank.\ Kann verwendet werden, um Probleme mit Registrierungen in der Datenbank in einem Netzwerk zu beheben. -In Depth Help - /plan update ? || > §2Update-Befehl\ Updatet das Plugin beim nächsten Restart\ /plan update - Link zum Änderungsprotokoll\ /plan update -u - Plant das Update auf allen Servern im Netzwerk, die online sind, wenn sie das nächste Mal restarten.\ /plan update cancel - Bricht das geplante Update ab, solange der Server noch nicht restartet wurde. -In Depth Help - /plan web ? || > §2Account-Verwaltungs-Befehl.\ §2/plan web §fListe Unterbefehle\ §2/plan web ? §fAusfürliche Hilfe -In Depth Help - /plan web register ? || > §2Registrierungs-Unterbefehl\ Registriert einen neuen Account.\ Um einen Account für einen anderen Usernamen als den eigenen zu erstellen wird plan.webmanage Berechtigung benötigt.\ Passwörter werden mit PBKDF2 (64,000 iterations of SHA1) gehashed dazu wird ein cryptographically-random salt verwendet. -In Depth Help - /planbungee disable ? || > §2Deaktivierungs-Befehl\ Führt onDisable auf PlanBungee aus.\ Plugin kann mit /planbungee reload wieder geladen werden.\ §bDabei kann NICHT die jar ausgetauscht werden. -In Depth Help - /planbungee setup ? || > §2Set-up-Umschalt-Befehl\ Schaltet den Set-Up Modus auf dem Bungee an oder aus.\ Stellt sicher, dass keine unautorisierte MySQL bei einem anderen Server ausschnüffelt. -Manage - Confirm Overwrite || Daten in ${0} werden überschrieben! -Manage - Confirm Removal || Daten in ${0} werden gelöscht! -Manage - Fail || > §cEtwas ist schiefgelaufen: ${0} -Manage - Fail File not found || > §cKeine Daten in ${0} gefunden -Manage - Fail Incorrect Database || > §c'${0}' ist keine unterstützte Datenbank. -Manage - Fail No Importer || §eImporter '${0}' existiert nicht -Manage - Fail Same Database || > §cKann nicht von und zu der gleichen Datenbank agieren! -Manage - Fail, Confirmation || > §cFüge '-a' zum Befehl hinzu um die Ausführung zu bestätigen: ${0} -Manage - Fail, Connection Exception || §eFehlgeschlagen: -Manage - Fail, No Servers || §cKein Server in der Datenbank. -Manage - Fail, Old version || §eFehlgeschlagen: Veraltete Version von Plan auf dem empfangenden Server. -Manage - Fail, Unauthorized || §eFehlgeschlagen: Zugriff verweigert. Server verwendet möglicherweise eine andere Datenbank. -Manage - Fail, Unexpected Exception || §eUnerwartete Ausnahme: ${0} -Manage - List Importers || Importer: -Manage - Notify External Url || §eNicht-lokale Adresse. Ist der Port offen? -Manage - Remind HotSwap || §eDenk dran, zur neuen Datenbank zu wechseln (/plan m hotswap ${0}) und um das Plugin neu zu laden. -Manage - Start || > §2Verarbeite Daten... -Manage - Success || > §aErfolgreich! -Negative || Nein -Positive || Ja -Unknown || Unbekannt -Version - DEV || Dies ist eine Entwicklungsversion! -Version - Latest || Du verwendest die neuste Version -Version - New || Eine neue Version (${0}) ist verfügbar! ${1} -Version - New (old) || Eine Neue Version ist hier verfügbar: ${0} -Version FAIL - Read info (old) || Überprüfung auf die neuste Versionsnummer fehlgeschlagen. -Version FAIL - Read versions.txt || Versionsinformationen konnten nicht ovn Github/versions.txt gelesen werden. -Web User Listing || §2${0} §7: §f${1} -WebServer - Notify HTTP || WebServer: Kein Zertifikat -> Benutze HTTP-server zur Visualisierung. -WebServer - Notify HTTP User Auth || WebServer: Benutzer-Authentifizierung abgeschaltet! (Nicht sicher über HTTP) -WebServer - Notify no Cert file || WebServer: Zertifikat KeyStore Datei nicht gefunden: ${0} -WebServer FAIL - Port Bind || WebServer wurde nicht erfolgreich initalisiert. Ist der Port (${0}) schon benutzt? -WebServer FAIL - SSL Context || WebServer: SSL Context Initialisierung fehlgeschlagen. -WebServer FAIL - Store Load || WebServer: SSL Zertifikat konnte nicht geladen werden. -Yesterday || 'Gestern' -Today || 'Heute' -Health - Active Playtime Comparison Decrease || Aktive Spieler haben möglicherweise nichts mehr zu tun (Vergleich der letzten zwei Wochen: ${0} zu den vorletzten zwei Wochen: ${1}. -Health - Active Playtime Comparison Increase || Aktive Spieler haben möglicherweise mehr zu tun (Vergleich der letzten zwei Wochen: ${0} ; zu den vorletzten zwei Wochen: ${1}. -Health - Downtime || Gesamte Serverdowntime (Keine Daten) war ${0} -Health - New Player Join Players, No || Neue Spieler haben möglicherweise keine anderen Spielern, mit denen sie spielen können. (${0} im Durchschnitt) -Health - New Player Join Players, Yes || Neue Spieler haben andere Spieler, mit denen Spielen können. (${0} im Durchschnitt) -Health - New Player Stickiness || ${0} von den neuen Spieler sind geblieben (${1}/${2}) -Health - No Servers Inaccuracy || Es sind keine Bukkit/Sponge-Server verfügbar um Sessiondaten zu sammeln - Diese Messungen sind ungenau. -Health - Player Play on Network || Spieler spielten im Netzwerk. Auf den Servern sieht's wie folgt aus: -Health - Player Register Server || Spieler wurden auf dem Server pro Tag/Server im Durchschnitt registriert. -Health - Player Visit Server || Spieler haben den Server am Tag/Server im Durchschnitt besucht. -Health - Regular Activity Change || Anzahl an regelmässigen Spielern -Health - Regular Activity Change Decrease || verringert um (${0}) -Health - Regular Activity Change Increase || erhöht um (+${0}) -Health - Regular Activity Change Zero || Bleibt gleich (+${0}) -Health - Regular Activity Remain || ${0} von den regelmässigen Spielern sind aktiv geblieben (${1}/${2}) -Health - Single Servers Inaccuracy || Einzelner Bukkit/Sponge um Sessiondaten zu sammeln. -Health - TPS Above Low Threshold || Durchschnittliche TPS war über der unteren Grenze ${0} in der Zeit. -Health - TPS Low Dips || Durchschnittliche TPS war unter der unteren Grenze. (${0}) ${1} male. -HTML - FREE_DISK_SPACE || Freier Festplattenspeicher -HTML - DISK_SPACE || Festplattenspeicher diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_EN.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_EN.txt deleted file mode 100644 index 58024ecce..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_EN.txt +++ /dev/null @@ -1,336 +0,0 @@ -Cmd - Click Me || Click me -Cmd - Link || §2Link: §f -Cmd Disable - Disabled || §aPlan systems are now disabled. You can still use /planbungee reload to restart the plugin. -Cmd FAIL - Invalid Username || §cUser does not have an UUID. -Cmd FAIL - No Feature || §eDefine a feature to disable! (currently supports ${0}) -Cmd FAIL - No Permission || §cYou do not have the required permission. -Cmd FAIL - Require only one Argument || §cSingle Argument required ${1} -Cmd FAIL - Requires Arguments || §cArguments required (${0}) ${1} -Cmd FAIL - Unknown Username || §cUser has not been seen on this server -Cmd FAIL - WebUser does not exists || §cUser does not exists! -Cmd FAIL - WebUser exists || §cUser already exists! -Cmd Header - Analysis || > §2Analysis Results -Cmd Header - Info || > §2Player Analytics -Cmd Header - Inspect || > §2Player: §f${0} -Cmd Header - Network || > §2Network Page -Cmd Header - Players || > §2Players -Cmd Header - Search || > §2${0} Results for §f${1}§2: -Cmd Header - Servers || > §2Servers -Cmd Header - Web Users || > §2${0} Web Users -Cmd Info - Bungee Connection || §2Connected to Proxy: §f${0} -Cmd Info - Database || §2Active Database: §f${0} -Cmd Info - Reload Complete || §aReload Complete -Cmd Info - Reload Failed || §cSomething went wrong during reload of the plugin, a restart is recommended. -Cmd Info - Update || §2Update Available: §f${0} -Cmd Info - Version || §2Version: §f${0} -Cmd Notify - No WebUser || You might not have a web user, use /plan register -Cmd Notify - WebUser register || Registered new user: '${0}' Perm level: ${1} -Cmd Qinspect - Activity Index || §2Activity Index: §f${0} | ${1} -Cmd Qinspect - Deaths || §2Deaths: §f${0} -Cmd Qinspect - Geolocation || §2Logged in from: §f${0} -Cmd Qinspect - Last Seen || §2Last Seen: §f${0} -Cmd Qinspect - Longest Session || §2Longest Session: §f${0} -Cmd Qinspect - Mob Kills || §2Mob Kills: §f${0} -Cmd Qinspect - Player Kills || §2Player Kills: §f${0} -Cmd Qinspect - Playtime || §2Playtime: §f${0} -Cmd Qinspect - Registered || §2Registered: §f${0} -Cmd Qinspect - Times Kicked || §2Times Kicked: §f${0} -Cmd Setup - Allowed || §aSet-up is now Allowed -Cmd Setup - Bad Request || §eConnection succeeded, but Receiving server was a Bukkit or Sponge server. Use another address instead. -Cmd Setup - Disallowed || §cSet-up is now Forbidden -Cmd Setup - Forbidden || §eConnection succeeded, but Proxy has set-up mode disabled - use '/planbungee setup' to enable it. -Cmd Setup - Gateway Error || §eConnection succeeded, but Proxy failed to connect to this server (Did current web server restart?). Use /plan m con & /planbungee con to debug. -Cmd Setup - Generic Fail || §eConnection failed: ${0} -Cmd Setup - Internal Error || §eConnection succeeded. ${0}, check possible ErrorLog on receiving server's debug page. -Cmd Setup - Success || §aConnection successful, Plan may restart in a few seconds.. -Cmd Setup - Unauthorized || §eConnection succeeded, but Receiving server didn't authorize this server. Contact Discord for support -Cmd Setup - Url mistake || §cMake sure you're using the full address (Starts with http:// or https://) - Check Proxy enable log for the full address. -Cmd Setup - WebServer not Enabled || §cWebServer is not enabled on this server! Make sure it enables on boot! -Cmd SUCCESS - Feature disabled || §aDisabled '${0}' temporarily until next plugin reload. -Cmd SUCCESS - WebUser register || §aAdded a new user (${0}) successfully! You can view the web panel in the following link. -Cmd Update - Cancel Success || §aCancel operation performed. -Cmd Update - Cancelled || §cUpdate cancelled. -Cmd Update - Change log || Change Log v${0}: -Cmd Update - Fail Cacnel || §cUpdate failed on a server, cancelling update on all servers.. -Cmd Update - Fail Force Notify || §e${0} failed to update, -force specified, continuing update. -Cmd Update - Fail Not Online || §cNot all servers were online or accessible, you can still update available servers using /plan update -u -force -Cmd Update - Notify Cancel || §aYou can cancel the update on servers that haven't rebooted yet with /plan update cancel. -Cmd Update - Online Check || Checking that all servers are online.. -Cmd Update - Scheduled || §a${0} scheduled for update. -Cmd Update - Url mismatch || §cVersion download url did not start with ${0} and might not be trusted. You can download this version manually here (Direct download): -Cmd Web - Permission Levels || >\§70: Access all pages\§71: Access '/players' and all player pages\§72: Access player page with the same username as the webuser\§73+: No permissions -Command Help - /plan analyze || View the Server Page -Command Help - /plan dev || Development mode command -Command Help - /plan help || Show command list -Command Help - /plan info || Check the version of Plan -Command Help - /plan inspect || View a Player Page -Command Help - /plan manage || Manage Plan Database -Command Help - /plan manage backup || Backup a Database -Command Help - /plan manage clear || Clear a Database -Command Help - /plan manage con || Debug Server-Proxy connections -Command Help - /plan manage disable || Disable a feature temporarily -Command Help - /plan manage hotswap || Change Database quickly -Command Help - /plan manage import || Import data from elsewhere -Command Help - /plan manage move || Move data between Databases -Command Help - /plan manage remove || Remove Player's data -Command Help - /plan manage restore || Restore a previous Backup -Command Help - /plan manage setup || Set-up Server-Proxy connection -Command Help - /plan network || View the Network Page -Command Help - /plan players || View the Players Page -Command Help - /plan qinspect || View Player info in game -Command Help - /plan register || Register a Web User -Command Help - /plan reload || Restart Plan -Command Help - /plan search || Search for a player name -Command Help - /plan servers || List servers in Database -Command Help - /plan update || Get change log link or update plugin -Command Help - /plan web check || Inspect a Web User -Command Help - /plan web delete || Delete a Web User -Command Help - /plan web level || Information about permission levels -Command Help - /plan web list || List Web Users -Command Help - /plan webuser || Manage Web Users -Command Help - /planbungee con || Debug Proxy-Server connections -Command Help - /planbungee disable || Disable the plugin temporarily -Command Help - /planbungee setup || Toggle set-up mode -Database - Apply Patch || Applying Patch: ${0}.. -Database - Patches Applied || All database patches applied successfully. -Database - Patches Applied Already || All database patches already applied. -Database MySQL - Launch Options Error || Launch Options were faulty, using default (${0}) -Database Notify - Clean || Removed data of ${0} players. -Database Notify - SQLite No WAL || SQLite WAL mode not supported on this server version, using default. This may or may not affect performance. -Disable || Player Analytics Disabled. -Disable - Processing || Processing critical unprocessed tasks. (${0}) -Disable - Processing Complete || Processing complete. -Disable - WebServer || Webserver has been disabled. -Enable || Player Analytics Enabled. -Enable - Database || ${0}-database connection established. -Enable - Notify Address Confirmation || Make sure that this address points to THIS Server: ${0} -Enable - Notify Empty IP || IP in server.properties is empty & AlternativeIP is not in use. Incorrect links will be given! -Enable - Notify Geolocations disabled || Geolocation gathering is not active. (Data.Geolocations: false) -Enable - Notify Geolocations Internet Required || Plan Requires internet access on first run to download GeoLite2 Geolocation database. -Enable - Notify Webserver disabled || WebServer was not initialized. (WebServer.DisableWebServer: true) -Enable - WebServer || Webserver running on PORT ${0} (${1}) -Enable FAIL - Database || ${0}-Database Connection failed: ${1} -Enable FAIL - Database Patch || Database Patching failed, plugin has to be disabled. Please report this issue -Enable FAIL - GeoDB Write || Something went wrong saving the downloaded GeoLite2 Geolocation database -Enable FAIL - WebServer (Bungee) || WebServer did not initialize! -Enable FAIL - Wrong Database Type || ${0} is not a supported Database -HTML - ACTIVITY_INDEX || Activity Index -HTML - ALL || ALL -HTML - ALL_TIME_PEAK || All Time Peak -HTML - AVERAGE_PING || Average Ping -HTML - AVG || AVG -HTML - BANNED || Banned -HTML - BEST_PING || Best Ping -HTML - CALENDAR || CALENDAR -HTML - CALENDAR_TEXT || Calendar -HTML - CHUNKS || Chunks -HTML - COMMAND || Command -HTML - COMMNAND_USAGE || Command Usage -HTML - CONNECTION_INFORMATION || Connection Information -HTML - COUNTRY || Country -HTML - CURRENT_PLAYERBASE || Current Playerbase -HTML - DEATHS || Deaths -HTML - ENTITIES || Entities -HTML - ERROR || Authentication failed due to error -HTML - FAVORITE_SERVER || Favorite Server -HTML - GEOLOCATION || Geolocation -HTML - GEOLOCATION_TEXT || Geolocation -HTML - HEALTH_ESTIMATE || Health Estimate -HTML - INDEX_ACTIVE || Active -HTML - INDEX_INACTIVE || Inactive -HTML - INDEX_IRREGULAR || Irregular -HTML - INDEX_REGULAR || Regular -HTML - INDEX_VERY_ACTIVE || Very Active -HTML - IP_ADDRESS || IP-address -HTML - KILLED || Killed -HTML - KILLED_BY || Killed by -HTML - LAST_24_HOURS || LAST 24 HOURS -HTML - LAST_30_DAYS || LAST 30 DAYS -HTML - LAST_30_DAYS_TEXT || Last 30 Days -HTML - LAST_7_DAYS || LAST 7 DAYS -HTML - LAST_CONNECTED || Last Connected -HTML - LAST_PEAK || Last Peak -HTML - LAST_SEEN || LAST SEEN -HTML - LAST_SEEN_TEXT || Last Seen -HTML - LOADED_CHUNKS || Loaded Chunks -HTML - LOADED_ENTITIES || Loaded Entities -HTML - LOCAL_MACHINE || Local Machine -HTML - LONGEST || Longest -HTML - LOW_TPS_SPIKES || Low TPS Spikes -HTML - MOB_CAUSED_DEATHS || Mob caused Deaths -HTML - MOB_KDR || Mob KDR -HTML - MOB_KILLS || Mob Kills -HTML - MOST_RECENT_SESSIONS || Most Recent Sessions -HTML - NAME || Name -HTML - NAV_COMMAND_USAGE || Command Usage -HTML - NAV_GEOLOCATIONS || Geolocations -HTML - NAV_INFORMATION || Information -HTML - NAV_NETWORK_PLAYERS || Network Players -HTML - NAV_ONLINE_ACTIVITY || Online Activity -HTML - NAV_OVERVIEW || Overview -HTML - NAV_PERFORMANCE || Performance -HTML - NAV_PLAYERS || Players -HTML - NAV_PLUGINS || Plugins -HTML - NAV_SESSIONS || Sessions -HTML - NAV_SEVER_HEALTH || Server Health -HTML - NETWORK || Network -HTML - NETWORK_INFORMATION || NETWORK INFORMATION -HTML - NEW || NEW -HTML - NEW_CALENDAR || New: -HTML - NEW_PLAYERS_TEXT || New Players -HTML - NEW_RETENTION || New Player Retention -HTML - NEW_TEXT || New -HTML - NICKNAME || Nickname -HTML - NO_KILLS || No Kills -HTML - NO_PLAYER_CAUSED_DEATHS || No Player caused Deaths -HTML - OFFLINE || Offline -HTML - ONLINE || Online -HTML - ONLINE_ACTIVITY || ONLINE ACTIVITY -HTML - OPERATOR || Operator -HTML - OVERVIEW || OVERVIEW -HTML - PER_DAY || / Day -HTML - PLAYER_CAUSED_DEATHS || Player caused Deaths -HTML - PLAYER_KILLS || Player Kills -HTML - PLAYER_LIST || Player List -HTML - PLAYERBASE_DEVELOPMENT || Playerbase Development -HTML - PLAYERS || PLAYERS -HTML - PLAYERS_ONLINE || PLAYERS ONLINE -HTML - PLAYERS_ONLINE_TEXT || Players Online -HTML - PLAYERS_TEXT || Players -HTML - PLAYTIME || Playtime -HTML - PLEASE_WAIT || Please wait... -HTML - PREDICETED_RETENTION || Predicted Retention -HTML - PUNCH_CARD || Punchcard -HTML - PUNCHCARD || PUNCHCARD -HTML - RECENT_LOGINS || RECENT LOGINS -HTML - REGISTERED || REGISTERED -HTML - REGISTERED_TEXT || Registered -HTML - REGULAR || REGULAR -HTML - SEEN_NICKNAMES || Seen Nicknames -HTML - SERVER || Server -HTML - SERVER_ANALYSIS || Server Analysis -HTML - SERVER_HEALTH_ESTIMATE || Server Health Estimate -HTML - SERVER_INFORMATION || SERVER INFORMATION -HTML - SERVER_PREFERENCE || Server Preference -HTML - SERVERS || Servers -HTML - SESSION || Session -HTML - SESSION_ENDED || Session Ended -HTML - SESSION_LENGTH || Session Lenght -HTML - SESSION_MEDIAN || Session Median -HTML - SESSIONS || Sessions -HTML - TIME || Time -HTML - TIMES_KICKED || Times Kicked -HTML - TIMES_USED || Times Used -HTML - TOTAL_ACTIVE_TEXT || Total Active -HTML - TOTAL_AFK || Total AFK -HTML - TOTAL_PLAYERS || Total Players -HTML - TOTAL_PLAYTIME || Total Playtime -HTML - UNIQUE || UNIQUE -HTML - UNIQUE_CALENDAR || Unique: -HTML - UNIQUE_PLAYERS || UNIQUE PLAYERS -HTML - UNIQUE_PLAYERS_TEXT || Unique Players -HTML - UNIQUE_TEXT || Unique -HTML - USAGE || Usage -HTML - USED_COMMANDS || Used Commands -HTML - USER_AND_PASS_NOT_SPECIFIED || User and Password not specified -HTML - USER_DOES_NOT_EXIST || User does not exist -HTML - USER_INFORMATION || USER INFORMATION -HTML - USER_PASS_MISMATCH || User and Password did not match -HTML - WITH ||
    With -HTML - WORLD || World -HTML - WORLD_LOAD || WORLD LOAD -HTML - WORLD_PLAYTIME || World Playtime -HTML - WORST_PING || Worst Ping -HTML ERRORS - ACCESS_DENIED_403 || Access Denied -HTML ERRORS - ANALYSIS_REFRESH || Analysis is being refreshed.. -HTML ERRORS - ANALYSIS_REFRESH_LONG || Analysis is being run, refresh the page after a few seconds.. -HTML ERRORS - AUTH_FAIL_TIPS_401 || - Ensure you have registered a user with /plan register
    - Check that the username and password are correct
    - Username and password are case-sensitive

    If you have forgotten your password, ask a staff member to delete your old user and re-register. -HTML ERRORS - AUTHENTICATION_FAILED_401 || Authentication Failed. -HTML ERRORS - FORBIDDEN_403 || Forbidden -HTML ERRORS - NO_SERVERS_404 || No Servers online to perform the request. -HTML ERRORS - NOT_FOUND_404 || Not Found -HTML ERRORS - NOT_PLAYED_404 || Player has not played on this server. -HTML ERRORS - PAGE_NOT_FOUND_404 || Page does not exist. -HTML ERRORS - UNAUTHORIZED_401 || Unauthorized -HTML ERRORS - UNKNOWN_PAGE_404 || Make sure you're accessing a link given by a command, Examples:

    /player/PlayerName
    /server/ServerName

    -HTML ERRORS - UUID_404 || Player UUID was not found in the database. -In Depth Help - /plan ? || > §2Main Command\ Access to subcommands and help\ §2/plan §fList subcommands\ §2/plan ? §fIn depth help -In Depth Help - /plan analyze ? || > §2Analysis Command\ Refreshes server page and displays link to the web page. -In Depth Help - /plan inspect ? || > §2Inspect Command\ Refreshes player page and displays link to the web page. -In Depth Help - /plan manage ? || > §2Manage Command\ Manage MySQL and SQLite database of Plan.\ §2/plan m §fList subcommands\ §2/plan m ? §fIn depth help -In Depth Help - /plan manage backup ? || > §2Backup Subcommand\ Creates a new SQLite database (.db file) with contents of currently active database in the Plan plugin folder. -In Depth Help - /plan manage clear ? || > §2Clear Subcommand\ Removes everything in the active database. Use with caution. -In Depth Help - /plan manage con ? || > §2Connection Debug Subcommand\ Used to debug connections in the network.\ Sends a request to each server in the database. -In Depth Help - /plan manage disable ? || > §2Disable Subcommand\ Can disable parts of the plugin until next reload.\ Accepted arguments:\ §2kickcount §fDisables kick counts in case /kickall is used on shutdown macro. -In Depth Help - /plan manage import ? || > §2Import Subcommand\ Import data from other sources.\ Accepted Arguments:\ §2offline §fBukkit player data, only register date and name. -In Depth Help - /plan manage move ? || > §2Move Subcommand\ Move data from SQLite to MySQL or other way around.\ Target database is cleared before transfer. -In Depth Help - /plan manage remove ? || > §2Remove Subcommand\ Remove player's data from the active database. -In Depth Help - /plan manage restore ? || > §2Restore Subcommand\ Restore a previous backup SQLite database (.db file)\ You can also restore database.db from another server to MySQL.\ Target database is cleared before transfer. -In Depth Help - /plan manage setup ? || > §2Setup Subcommand\ Set-up a connection between Proxy and this server for network functionality.\ BungeeAddress can be found in the enable log on console when Plan enables on Bungee. -In Depth Help - /plan network ? || > §2Network Command\ Displays link to the network page.\ If not on a network, this page displays the server page. -In Depth Help - /plan players ? || > §2Players Command\ Displays link to the players page. -In Depth Help - /plan qinspect ? || > §2Quick Inspect Command\ Displays some information about the player in game. -In Depth Help - /plan reload ? || > §2Reload Command\ Restarts the plugin using onDisable and onEnable.\ §bDoes not support swapping jar on the fly -In Depth Help - /plan search ? || > §2Search Command\ Get a list of Player names that match the given argument.\§7 Example: /plan search 123 - Finds all users with 123 in their name. -In Depth Help - /plan servers ? || > §2Servers Command\ Displays list of Plan servers in the Database.\ Can be used to debug issues with database registration on a network. -In Depth Help - /plan update ? || > §2Update Command\ Used to update the plugin on the next shutdown\ /plan update - Changelog link\ /plan update -u - Schedule update to happen on all network servers that are online, next time they reboot.\ /plan update cancel - Cancel scheduled update on servers that haven't rebooted yet. -In Depth Help - /plan web ? || < §2Web User Manage Command.\ §2/plan web §fList subcommands\ §2/plan web ? §fIn Depth help -In Depth Help - /plan web register ? || > §2Register Subcommand\ Registers a new Web User.\ Registering a user for another player requires plan.webmanage permission.\ Passwords are hashed with PBKDF2 (64,000 iterations of SHA1) using a cryptographically-random salt. -In Depth Help - /planbungee disable ? || > §2Disable Command\ Runs Plan onDisable on Proxy servers.\ Plugin can be enabled with /planbungee reload afterwards.\ §bDoes not support swapping jar on the fly -In Depth Help - /planbungee setup ? || > §2Set-up toggle Command\ Toggles set-up mode on Proxy.\ Safeguard against unauthorized MySQL snooping with another server. -Manage - Confirm Overwrite || Data in ${0} will be overwritten! -Manage - Confirm Removal || Data in ${0} will be removed! -Manage - Fail || > §cSomething went wrong: ${0} -Manage - Fail File not found || > §cNo File found at ${0} -Manage - Fail Incorrect Database || > §c'${0}' is not a supported database. -Manage - Fail No Importer || §eImporter '${0}' doesn't exist -Manage - Fail Same Database || > §cCan not operate on to and from the same database! -Manage - Fail, Confirmation || > §cAdd '-a' argument to confirm execution: ${0} -Manage - Fail, Connection Exception || §eFail reason: -Manage - Fail, No Servers || §cNo Servers found in the database. -Manage - Fail, Old version || §eFail reason: Older Plan version on receiving server -Manage - Fail, Unauthorized || §eFail reason: Unauthorized. Server might be using different database. -Manage - Fail, Unexpected Exception || §eOdd Exception: ${0} -Manage - List Importers || Importers: -Manage - Notify External Url || §eNon-local address, check that port is open -Manage - Remind HotSwap || §eRemember to swap to the new database (/plan m hotswap ${0}) & reload the plugin. -Manage - Start || > §2Processing data.. -Manage - Success || > §aSuccess! -Negative || No -Positive || Yes -Unknown || Unknown -Version - DEV || This is a DEV release. -Version - Latest || You're using the latest version. -Version - New || New Release (${0}) is available ${1} -Version - New (old) || New Version is available at ${0} -Version FAIL - Read info (old) || Failed to check newest version number -Version FAIL - Read versions.txt || Version information could not be loaded from Github/versions.txt -Web User Listing || §2${0} §7: §f${1} -WebServer - Notify HTTP || WebServer: No Certificate -> Using HTTP-server for Visualization. -WebServer - Notify HTTP User Auth || WebServer: User Authorization Disabled! (Not secure over HTTP) -WebServer - Notify no Cert file || WebServer: Certificate KeyStore File not Found: ${0} -WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? -WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. -WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. -Yesterday || 'Yesterday' -Today || 'Today' -Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) -Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) -Health - Downtime || Total Server downtime (No Data) was ${0} -Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) -Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) -Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) -Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. -Health - Player Play on Network || players played on the network: -Health - Player Register Server || players register on servers per day/server on average. -Health - Player Visit Server || players visit on servers per day/server on average. -Health - Regular Activity Change || Number of regular players has -Health - Regular Activity Change Decrease || decreased (${0}) -Health - Regular Activity Change Increase || increased (+${0}) -Health - Regular Activity Change Zero || stayed the same (+${0}) -Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) -Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. -Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time -Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times -HTML - FREE_DISK_SPACE || Free Disk Space -HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_FI.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_FI.txt deleted file mode 100644 index 873509163..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_FI.txt +++ /dev/null @@ -1,335 +0,0 @@ -Cmd - Click Me || Klikkaa minua -Cmd - Link || §2Linkki: §f -Cmd Disable - Disabled || §aPlan on nyt poissa päältä. Voit käyttää /planbungee reload komentoa uudelleenkäynnistykseen. -Cmd FAIL - Invalid Username || §cPelaajalla ei löytynyt UUID:ta. -Cmd FAIL - No Feature || §eValitse sammutettava osa! (tällähetkellä tuetut: ${0}) -Cmd FAIL - No Permission || §cSinulla ei ole lupaa. -Cmd FAIL - Require only one Argument || §cAnna ainakin yksi muuttuja ${1} -Cmd FAIL - Requires Arguments || §cMääritä enemmän muuttujia (${0}) ${1} -Cmd FAIL - Unknown Username || §cPleaajaa ei ole nähty tällä palvelimella. -Cmd FAIL - WebUser does not exists || §cKäyttäjää ei ole olemassa! -Cmd FAIL - WebUser exists || §cKäyttäjä on jo olemassa! -Cmd Header - Analysis || > §2Analyysin tulokset -Cmd Header - Info || > §2Player Analytics -Cmd Header - Inspect || > §2Pelaaja: §f${0} -Cmd Header - Network || > §2Verkoston Sivu -Cmd Header - Players || > §2Pelaajat -Cmd Header - Search || > §2${0} Tulosta haulle §f${1}§2: -Cmd Header - Servers || > §2Palvelimet -Cmd Header - Web Users || > §2${0} Web Käyttäjät -Cmd Info - Bungee Connection || §2Yhdistetty BungeeCord:iin: §f${0} -Cmd Info - Database || §2Aktiivinen Tietokanta: §f${0} -Cmd Info - Reload Complete || §aUudelleenlataus onnistui! -Cmd Info - Reload Failed || §cUudelleenlatauksessa esiintyi ongelmia. Käynnistystä uudelleen suositellaan. -Cmd Info - Update || §2Päivitys saatavilla: §f${0} -Cmd Info - Version || §2Versio: §f${0} -Cmd Notify - No WebUser || Sinulla ei ehkä ole Web Käyttäjää, käytä /plan register -komentoa -Cmd Notify - WebUser register || Rekisteröitiin uusi Web Käyttäjä: '${0}' Lupa taso: ${1} -Cmd Qinspect - Activity Index || §2Aktiivisuus Indeksi: §f${0} | ${1} -Cmd Qinspect - Deaths || §2Kuolemat: §f${0} -Cmd Qinspect - Geolocation || §2Kirjautui sisään maasta: §f${0} -Cmd Qinspect - Last Seen || §2Viimeksi nähty: §f${0} -Cmd Qinspect - Longest Session || §2Pisin istunto: §f${0} -Cmd Qinspect - Mob Kills || §2Otusten Tappoja: §f${0} -Cmd Qinspect - Player Kills || §2Pelaajien Tappoja: §f${0} -Cmd Qinspect - Playtime || §2Peliaika: §f${0} -Cmd Qinspect - Registered || §2Rekisteröitynyt: §f${0} -Cmd Qinspect - Times Kicked || §2Potkittu Pellolle: §f${0} -Cmd Setup - Allowed || §aYhteydenotto on nyt sallittu. -Cmd Setup - Bad Request || §eYhteys onnistui, mutta Vastaanottava palvelin oli Bukkit tai Sponge-palvelin. Käytä toista osoitetta. -Cmd Setup - Disallowed || §cYhteydenotto on nyt kielletty. -Cmd Setup - Forbidden || §eYhteys onnistui, mutta BungeeCord:n set-up tila oli poissa käytöstä - käytä '/planbungee setup' laittaaksesi sen päälle. -Cmd Setup - Gateway Error || §eYhteys onnistui, mutta BungeeCord ei saanut yhteyttä tähän palvelimeen (Käynnistyikö Web palvelin uudelleen?). Käytä /plan m con & /planbungee con tutkiaksesi ongelmia. -Cmd Setup - Generic Fail || §eYhteys ei onnistunut: ${0} -Cmd Setup - Internal Error || §eYhteys onnistui. ${0}, tarkista mahdollinen virheloki vastaanottavalla palvelimella. -Cmd Setup - Success || §aYhteys onnistui, Plan saattaa käynnistyä uudelleen muutaman sekunnin kuluttua.. -Cmd Setup - Unauthorized || §eYhteys onnistui, mutta Vastaanottava palvelin ei hyväksynyt tätä palvelinta. Pyydä apua Discordissa. -Cmd Setup - Url mistake || §cVarmista käyttäväsi kokonaista osoitetta (http:// tai https:// alkuinen) - Tarkista osoite BungeeCord:in käynnistyslokista. -Cmd Setup - WebServer not Enabled || §cWeb Palevlin ei ole käynnissä tällä palvelimella! Varmista että se käynnistyy pelin mukana! -Cmd SUCCESS - Feature disabled || §aSammutettiin '${0}' toistaiseksi, kunnes Plan ladataan uudelleen. -Cmd SUCCESS - WebUser register || §aLisättiin uusi Web Käyttäjä (${0})! Voit tarkastella web-paneelia seuraavasta linkistä. -Cmd Update - Cancel Success || §aPeruutettu. -Cmd Update - Cancelled || §cPäivitys peruutettu. -Cmd Update - Change log || Muutosloki v${0}: -Cmd Update - Fail Cacnel || §cPäivitys epäonnistui palvelimella, peruutetaan päivitys kaikilla palvelimilla.. -Cmd Update - Fail Force Notify || §e${0} ei voitu päivittää, -force käytössä, jatketaan päivitystä. -Cmd Update - Fail Not Online || §cKaikki palvelimet eivät olleet saatavilla, voit silti päivittää käyttämällä komentoa /plan update -u -force -Cmd Update - Notify Cancel || §aVoit peruuttaa päivityksen palvelimilla, joita ei ole käynnistetty uudelleen, komennolla /plan update cancel. -Cmd Update - Online Check || Varmistetaan että palvelimet ovat päällä.. -Cmd Update - Scheduled || §a${0} astettu päivittymään. -Cmd Update - Url mismatch || §cVersio URL ei alkanut ${0} joten siihen ei voi ehkä luottaa. Voit ladata sen manuaalisesti täältä (Suora lataus): -Cmd Web - Permission Levels || >\§70: Pääsy kaikille sivuille\§71: Pääsy '/players' ja pelaajien sivuille\§72: Pääsy pelaajan sivulle, jolla on sama nimi kuin Web Käyttäjällä\§73+: Ei pääsyä -Command Help - /plan analyze || Katso Palvelimen sivua -Command Help - /plan dev || Kehitys komento -Command Help - /plan help || Komentojen lista -Command Help - /plan info || Tarkista Plan versio -Command Help - /plan inspect || Katso Pelaajan sivua -Command Help - /plan manage || Hallitse Plan tietokantaa -Command Help - /plan manage backup || Varmuuskopioi tietokanta -Command Help - /plan manage clear || Tyhjennä tietokanta -Command Help - /plan manage con || Tutki Palvelin-BungeeCord yhteys ongelmia -Command Help - /plan manage disable || Sammuta osa toistaiseksi -Command Help - /plan manage hotswap || Vaihda tietokantaa lennosta -Command Help - /plan manage import || Tuo tietoa muualta -Command Help - /plan manage move || Siirrä tietoa tietokantojen välillä -Command Help - /plan manage remove || Poista pelaajan tiedot -Command Help - /plan manage restore || Palauta teitokannan varmuuskopio -Command Help - /plan manage setup || Muodosta Palvelin-BungeeCord yhteys -Command Help - /plan network || Katso Verkoston sivua -Command Help - /plan players || Katso Pelaajat sivua -Command Help - /plan qinspect || Katso pelaajan tietoja pelissä -Command Help - /plan register || Rekisteröi Web Käyttäjä -Command Help - /plan reload || Käynnistä Plan uudelleen -Command Help - /plan search || Etsi pelaajan nimeä -Command Help - /plan servers || Listaa tietokannassa olevat palvelimet -Command Help - /plan update || Muutosloki linkki tai Plan:in päivitys -Command Help - /plan web check || Tarkista Web Käyttäjän tiedot -Command Help - /plan web delete || Poista Web Käyttäjä -Command Help - /plan web level || Tietoa Web lupatasoista -Command Help - /plan web list || Listaa Web Käyttäjät -Command Help - /plan webuser || Halliste Web Käyttäjiä -Command Help - /planbungee con || Tutki BungeeCord-Palvelin yhteys ongelmia -Command Help - /planbungee disable || Sammuta Plan toistaiseksi -Command Help - /planbungee setup || Vaihda asennustilaa -Database - Apply Patch || Muutetaan Tietokantaa: ${0}.. -Database - Patches Applied || Tietokannan muutokset suoritettu onnistuneesti. -Database - Patches Applied Already || Kaikki tietokannan muutokset oli jo tehty. -Database MySQL - Launch Options Error || LauchOptions-asetus oli virheellinen, käytetään oletusta (${0}) -Database Notify - Clean || Poistetiin ${0}n pelaajan tiedot. -Database Notify - SQLite No WAL || SQLite WAL tilaa ei tueta tällä versiolla, Käytetään perustilaa. Tämä voi vaikuttaa suorituskykyyn. -Disable || Player Analytics Sammutettu. -Disable - Processing || Suoritetaan kriittisiä suorittamattomia toimintoja. (${0}) -Disable - Processing Complete || Suoritus valmis. -Disable - WebServer || Web palvelin on sammutettu. -Enable || Player Analytics Käynnistetty. -Enable - Database || ${0}-tietokanta yhteys luotu. -Enable - Notify Address Confirmation || Varmista että tämä osoite osoittaa TÄHÄN palvelimeen: ${0} -Enable - Notify Empty IP || IP server.properties tiedostossa on tyhjä & AlternativeIP ei ole käytössä. Linkit ovat virheellisiä! -Enable - Notify Geolocations disabled || Sijaintien keräys ei ole päällä. (Data.Geolocations: false) -Enable - Notify Geolocations Internet Required || Plan Vaatii internetin ensimmäisellä käynnistyskerralla GeoLite2 tietokannan lataamiseen. -Enable - Notify Webserver disabled || Web Palvelinta ei käynnistetty. (WebServer.DisableWebServer: true) -Enable - WebServer || Web Palvelin pyörii PORTILLA ${0} (${1}) -Enable FAIL - Database || ${0}-Tietokanta yhteys epäonnistui: ${1} -Enable FAIL - Database Patch || Tietokannan muutokset epäonnistuivat, Plan jouduttiin sulkemaan. Ilmoita tästä ongelmasta -Enable FAIL - GeoDB Write || Jokin meni pieleen tallentaessa GeoLite2 tietokantaa -Enable FAIL - WebServer (Bungee) || Web Palvelin ei käynnistynyt! -Enable FAIL - Wrong Database Type || ${0} ei ole tuettu Tietokanta -HTML - ACTIVITY_INDEX || Aktiivisuus Indeksi -HTML - ALL || KAIKKI -HTML - ALL_TIME_PEAK || Paras Huippu -HTML - AVERAGE_PING || Keskimääräinen Ping -HTML - AVG || AVG -HTML - BANNED || Pannassa -HTML - BEST_PING || Paras Ping -HTML - CALENDAR || KALENTERI -HTML - CALENDAR_TEXT || Kalenteri -HTML - CHUNKS || Chunkit -HTML - COMMAND || Komento -HTML - COMMNAND_USAGE || Komentojen Käyttö -HTML - CONNECTION_INFORMATION || Yhteydet -HTML - COUNTRY || Maa -HTML - CURRENT_PLAYERBASE || Nykyiset pelaajat -HTML - DEATHS || Kuolemat -HTML - ENTITIES || Entiteetit -HTML - ERROR || Autentisointi epäonnistui virheen vuoksi -HTML - FAVORITE_SERVER || Lempipalvelin -HTML - GEOLOCATION || Sijainti -HTML - GEOLOCATION_TEXT || Sijainti -HTML - HEALTH_ESTIMATE || Terveysarvio -HTML - INDEX_ACTIVE || Aktiivinen -HTML - INDEX_INACTIVE || Inaktiivinen -HTML - INDEX_IRREGULAR || Epäsäännöllinen -HTML - INDEX_REGULAR || Säännöllinen -HTML - INDEX_VERY_ACTIVE || Todella Aktiivinen -HTML - IP_ADDRESS || IP-osoite -HTML - KILLED || Tappanut -HTML - KILLED_BY || Tappanut -HTML - LAST_24_HOURS || VIIMEISET 24 TUNTIA -HTML - LAST_30_DAYS || VIIMEISET 30 PÄIVÄÄ -HTML - LAST_30_DAYS_TEXT || Viimeiset 30 Päivää -HTML - LAST_7_DAYS || VIIMEISET 7 PÄIVÄÄ -HTML - LAST_CONNECTED || Viimeisin yhteys -HTML - LAST_PEAK || Viimeisin huippu -HTML - LAST_SEEN || NÄHTY VIIMEKSI -HTML - LAST_SEEN_TEXT || Nähty Viimeksi -HTML - LOADED_CHUNKS || Ladatut Chunkit -HTML - LOADED_ENTITIES || Ladatut Entiteetit -HTML - LOCAL_MACHINE || Paikallinen laite -HTML - LONGEST || Pisin -HTML - LOW_TPS_SPIKES || Matalat TPS Harjat -HTML - MOB_CAUSED_DEATHS || Otusten aiheuttamat Kuolemat -HTML - MOB_KILLS || Tapetut Otukset -HTML - MOST_RECENT_SESSIONS || Viimeisimmät Istunnot -HTML - NAME || Nimi -HTML - NAV_COMMAND_USAGE || Komentojen Käyttö -HTML - NAV_GEOLOCATIONS || Sijainnit -HTML - NAV_INFORMATION || Tiedot -HTML - NAV_NETWORK_PLAYERS || Verkoston Pelaajat -HTML - NAV_ONLINE_ACTIVITY || Aktiivisuus -HTML - NAV_OVERVIEW || Yhteenveto -HTML - NAV_PERFORMANCE || Suorituskyky -HTML - NAV_PLAYERS || Pelaajat -HTML - NAV_PLUGINS || Lisäosat -HTML - NAV_SESSIONS || Istunnot -HTML - NAV_SEVER_HEALTH || Palvelimen Terveys -HTML - NETWORK || Verkosto -HTML - NETWORK_INFORMATION || VERKOSTON TIEDOT -HTML - NEW || UUDET -HTML - NEW_CALENDAR || Uudet: -HTML - NEW_PLAYERS_TEXT || Uudet Pelaajat -HTML - NEW_RETENTION || Uusien Pelaajien pysyvyys -HTML - NEW_TEXT || Uudet -HTML - NICKNAME || Lempinimi -HTML - NO_KILLS || Ei Tappoja -HTML - NO_PLAYER_CAUSED_DEATHS || Ei Pelaajien auheuttamia kuolemia -HTML - OFFLINE || Ei Paikalla -HTML - ONLINE || Paikalla -HTML - ONLINE_ACTIVITY || AKTIIVISUUS -HTML - OPERATOR || Operaattori -HTML - OVERVIEW || YHTEENVETO -HTML - PER_DAY || / Päivä -HTML - PLAYER_CAUSED_DEATHS || Pelaajien aiheuttamat Kuolemat -HTML - PLAYER_KILLS || Tapetut Pelaajat -HTML - PLAYER_LIST || Pelaajalista -HTML - PLAYERBASE_DEVELOPMENT || Pelaajakunnan kehitys -HTML - PLAYERS || PELAAJAT -HTML - PLAYERS_ONLINE || PELAAJIA PAIKALLA -HTML - PLAYERS_ONLINE_TEXT || Pelaajia Paikalla -HTML - PLAYERS_TEXT || Pelaajia -HTML - PLAYTIME || Peliaika -HTML - PLEASE_WAIT || Odota Hetki... -HTML - PREDICETED_RETENTION || Pysyvyyden Ennuste -HTML - PUNCH_CARD || Reikäkortti -HTML - PUNCHCARD || REIKÄKORTTI -HTML - RECENT_LOGINS || VIIMEAIKAISET KIRJAUTUMISET -HTML - REGISTERED || REKISTERÖITYNYT -HTML - REGISTERED_TEXT || Rekisteröitynyt -HTML - REGULAR || SÄÄNNÖLLISET -HTML - SEEN_NICKNAMES || Nähdyt Lempinimet -HTML - SERVER || Palvelin -HTML - SERVER_ANALYSIS || Palvelimen Analyysi -HTML - SERVER_HEALTH_ESTIMATE || Palvelimen Terveysarvio -HTML - SERVER_INFORMATION || PALVELIMEN TIEDOT -HTML - SERVER_PREFERENCE || Palvelinten mieleisyys -HTML - SERVERS || Palvelimet -HTML - SESSION || Istunto -HTML - SESSION_ENDED || Istunto Päättyi -HTML - SESSION_LENGTH || Istunnon Pituus -HTML - SESSION_MEDIAN || Istuntojen Mediaani -HTML - SESSIONS || Istunnot -HTML - TIME || Aika -HTML - TIMES_KICKED || Potkimis Kerrat -HTML - TIMES_USED || Käyttökerrat -HTML - TOTAL_ACTIVE || Aktiivinen Peliaika -HTML - TOTAL_AFK || AFK -HTML - TOTAL_PLAYERS || Kaikki Pelaajat -HTML - TOTAL_PLAYTIME || Peliaika -HTML - UNIQUE || UNIIKIT -HTML - UNIQUE_CALENDAR || Uniikit: -HTML - UNIQUE_PLAYERS || UNIIKIT PELAAJAT -HTML - UNIQUE_PLAYERS_TEXT || Uniikit Pelaajat -HTML - UNIQUE_TEXT || Uniikit -HTML - USAGE || Käyttö -HTML - USED_COMMANDS || Käytetyt Komennot -HTML - USER_AND_PASS_NOT_SPECIFIED || Käyttäjää ja salasana vaaditaan. -HTML - USER_DOES_NOT_EXIST || Käyttäjää ei ole olemassa -HTML - USER_INFORMATION || KÄYTTÄJIEN TIEDOT -HTML - USER_PASS_MISMATCH || Käyttäjä ja salasana ei täsmää -HTML - WITH ||
    Millä -HTML - WORLD || Maailma -HTML - WORLD_LOAD || MAAILMAN VARAUS -HTML - WORLD_PLAYTIME || Maailman Peliaika -HTML - WORST_PING || Huonoin Ping -HTML ERRORS - ACCESS_DENIED_403 || Pääsy Kielletty -HTML ERRORS - ANALYSIS_REFRESH || Analyysiä suoritetaan.. -HTML ERRORS - ANALYSIS_REFRESH_LONG || Analyysiä suoritetaan, sivu päivittyy hetken kuluttua.. -HTML ERRORS - AUTH_FAIL_TIPS_401 || - Varmista että olet rekisteröinyt käyttäjän komennolla /plan register
    - Tarkista että käyttäjänimi ja salaasana ovat oikein
    - Nimi ja salasana ovat CASE SENSITIVE

    Jos unohdit salasanasi, pyydä valvojia poistamaan käyttäjäsi ja uudelleenrekisteröidy. -HTML ERRORS - AUTHENTICATION_FAILED_401 || Autentikaatio ei onnistunut. -HTML ERRORS - FORBIDDEN_403 || Kielletty -HTML ERRORS - NO_SERVERS_404 || Ei palvelimia jolla toiminto voitaisiin suorittaa. -HTML ERRORS - NOT_FOUND_404 || Ei löytynyt -HTML ERRORS - NOT_PLAYED_404 || Pelaaja ei ole pelannut palvelimella. -HTML ERRORS - PAGE_NOT_FOUND_404 || Sivua ei ole olemassa. -HTML ERRORS - UNAUTHORIZED_401 || Ei Autentikoitu -HTML ERRORS - UNKNOWN_PAGE_404 || Varmista menneeesi komennon antamaan osoitteeseen, Esim:

    /player/PelaajanNimi
    /server/PalvelimenNimi

    -HTML ERRORS - UUID_404 || Pelaajan UUID:ta ei löytynyt tietokannasta. -In Depth Help - /plan ? || > §2Pääkomento\ Käytä alikomentoja ja apua\ §2/plan §fListaa alikomennot\ §2/plan ? §fYksityiskohtainen apu -In Depth Help - /plan analyze ? || > §2Analyysi Komento\ Päivittää palvelin sivun ja näyttää linkin sivustolle. -In Depth Help - /plan inspect ? || > §2Tutkimus Komento\ Päivittää pelaajan sivun ja näyttää linkin sivustolle -In Depth Help - /plan manage ? || > §2Hallinto Komento\ Hallitse Plan MySQL and SQLite tietokantoja.\ §2/plan m §fListaa alikomennot\ §2/plan m ? §fYksityiskohtainen apu -In Depth Help - /plan manage backup ? || > §2Varmuuskopio Alikomento\ Luo uuden SQLite tietokannan (.db file) nykyisen tietokannan tiedoilla Plan plugins kansioon.. -In Depth Help - /plan manage clear ? || > §2Poisto Alikomento\ Poistaa kaiken aktiivisesta tietokannasta. Käytä varoen -In Depth Help - /plan manage con ? || > §2Yhteyksien tutkimus Alikomento\ Käytetään yhteys ongelmien tutkimiseen verkostoissa.\ Lähettää viestin jokaiselle palvelimelle tietokannassa. -In Depth Help - /plan manage disable ? || > §2Sammutus Alikomento\ Voi poistaa osia käytöstä tilapäisesti.\ Hyväksytyt muuttujat:\ §2kickcount §fSulkee potkimisten laskun, mikäli /kickall komentoa käytetään sammutus makrossa. -In Depth Help - /plan manage import ? || > §2Tuonti Alikomento\ Tuo tietoa muualta.\ Hyväksytyt muuttujat:\ §2offline §fBukkitin pelaajatiedot, rekisteröitymispäivä ja nimi. -In Depth Help - /plan manage move ? || > §2Siirto Alikomento\ Siirrä tietoa SQLite ja MySQL tietokantojen välillä.\ Kohde tietokanta tyhjennetään ennen siirtoa. -In Depth Help - /plan manage remove ? || > §2Poisto Alikomento\ Poistaa pelaajan tiedot aktiivisesta tietokannasta. -In Depth Help - /plan manage restore ? || > §2Palautus Alikomento\ Palauta edellinen varmuuskopio SQLite tietokanta (.db tiedosto)\ Voit myös palauttaa database.db tiedoston toiselta palvelimelta MySQL-tietokantan.\ Kohde tietokanta tyhjennetään ennen siirtoa. -In Depth Help - /plan manage setup ? || > §2Asennus Alikomento\ Muodosta yhteys BungeeCordin ja tämän palvelimen välille.\ BungeeAddress löytyy BungeeCordin käynnistyslokista -In Depth Help - /plan network ? || > §2Verkosto Komento\ Näyttää linkin verkosto sivulle.\ Jos palvelin ei ole verkostossa, näyttää tämä sivu palvelimen sivun. -In Depth Help - /plan players ? || > §2Pelaajat Komento\ Näyttää linkin pelaajan sivulle. -In Depth Help - /plan qinspect ? || > §2Pika-tutkimus Komento\ Näyttää tietoja pelaajasta pelin sisällä. -In Depth Help - /plan reload ? || > §2Uudelleenlataus Komento\ Käynnistää Plan:in uudelleen.\ §bEi tue jar:in vaihtoa lennosta -In Depth Help - /plan search ? || > §2Haku Komento\ Hae pelaajannimiä jollain hakusanalla.\§7 Esim: /plan search 123 - Etsii kaikki pelaajat joilla on 123 nimessään. -In Depth Help - /plan servers ? || > §2Palvelimet Komento\ Näyttää tietokannassa olevat Plan palvelimet.\ Voidaan käyttää yhteys ongelmien tutkimiseen. -In Depth Help - /plan update ? || > §2Päivitys Komento\ Päivittää Plan:in seuraavan käynnistyksen yhteydessä\ /plan update - Muutosloki linkki\ /plan update -u - Ajoita päivitys kaikissa päällä olevissa palvelimissa seuraavalle käynnistyskerralle.\ /plan update cancel - Peruuta ajoitettu päivitys palvelimilla jotka eivät ole vielä käynnistyneet uudelleen. -In Depth Help - /plan web ? || < §2Web Käyttäjähallinto Komento.\ §2/plan web §fList alikomentos\ §2/plan web ? §fYksityiskohtainen apu -In Depth Help - /plan web register ? || > §2Rekisteröinti Alikomento\ Rekisteröi uuden Web Käyttäjän.\ Toiselle pelaajalle käyttäjän rekisteröinti vaatii plan.webmanage permission.\ Salasanat salataan PBKDF2 (64,000 iterations of SHA1) algoritmilla. -In Depth Help - /planbungee disable ? || > §2Sammutus Komento\ Sammuttaa PlanBungee:n.\ /planbungee reload käynnistää Plan:in uudelleen.\ §bEi tue jar:in vaihtoa lennossa -In Depth Help - /planbungee setup ? || > §2Asennustilan vaihto Komento\ Vaihtaa asennustilaa Bungee:lla.\ Turvatoimi MySQL haistelulle toisella Plan palvelimella. -Manage - Confirm Overwrite || Tiedot ${0}:ssa ylikirjoitetaan! -Manage - Confirm Removal || Tiedot ${0}:ssa poistetaan! -Manage - Fail || > §cJokin meni vikaan: ${0} -Manage - Fail File not found || > §cTiedostoa ei löytynyt ${0} -Manage - Fail Incorrect Database || > §c'${0}' ei ole tuettu tietokanta. -Manage - Fail No Importer || §eTuojaa '${0}' ei ole olemassa -Manage - Fail Same Database || > §cEi voi käyttää samaa tietokantaa molempiin asioihin! -Manage - Fail, Confirmation || > §cLisää '-a' vahvistaaksesi: ${0} -Manage - Fail, Connection Exception || §eEpäonnistumisen syy: -Manage - Fail, No Servers || §cEi Palvelimia tietokannassa. -Manage - Fail, Old version || §eSyy: Vanhempi versio vastaanottavalla palvelimella -Manage - Fail, Unauthorized || §eSyy: Ei authentikoitu, palvelin voi käyttää toista tietokantaa -Manage - Fail, Unexpected Exception || §eKummallinen Virhe: ${0} -Manage - List Importers || Tuojat: -Manage - Notify External Url || §eEi-lokaali osoite, tarkista että portti on auki -Manage - Remind HotSwap || §eMuista vaihtaa tietokantaa (/plan m hotswap ${0}) & käynnistä Plan uudelleen. -Manage - Start || > §2Prosessoidaan tietoa.. -Manage - Success || > §aOnnistui! -Negative || Ei -Positive || Kyllä -Unknown || Tuntematon -Version - DEV || Tämä on KEHITYS julkaisu. -Version - Latest || Käytät uusinta versiota. -Version - New || Uusi Julkaisu (${0}) on saatavilla ${1} -Version - New (old) || Uusi Versio on saatavilla ${0} -Version FAIL - Read info (old) || Uuden version tarkistus epäonnistui -Version FAIL - Read versions.txt || Uuden version tarkistus epäonnistui Github/versions.txt:ta -Web User Listing || §2${0} §7: §f${1} -WebServer - Notify HTTP || Web Palvelin: Ei Sertifikaattia -> Käytetään HTTP-Palvelinta. -WebServer - Notify HTTP User Auth || Web Palvelin: Käyttäjien varmennus ei käytössä! (Ei turvallista HTTP-protokollalla) -WebServer - Notify no Cert file || Web Palvelin: Sertifikaatti AvainKirjasto tiedostoa ei löytynyt: ${0} -WebServer FAIL - Port Bind || Web Palvelin ei käynnistynyt. Onko portti (${0}) käytössä? -WebServer FAIL - SSL Context || Web Palvelin: SSL Kontekstin käynnistys ei onnistunut. -WebServer FAIL - Store Load || Web Palvelin: SSL Sertifikaatin lataus ei onnistunut. -Yesterday || 'Eilen' -Today || 'Tänään' -Health - Active Playtime Comparison Decrease || Aktiivisilta pelaajilta voi olla loppumassa tekeminen (Pelasivat ${0} vs ${1}, viimeisen kahden viikon vs viikot 2-4) -Health - Active Playtime Comparison Increase || Aktiivisilta pelaajilta vaikuttaa olevan tekemistä (Pelasivat ${0} vs ${1}, viimeisen kahden viikon vs viikot 2-4) -Health - Downtime || Palvelimen downtime (Ei Dataa) oli ${0} -Health - New Player Join Players, No || Uusilla pelaajilla voi olla yksinäistä (${0} paikalla keskimäärin) -Health - New Player Join Players, Yes || Uusilla pelaajilla on kavereita liittyessä (${0} paikalla keskimäärin) -Health - New Player Stickiness || ${0} uusista pelaajista jäi pelaamaan (${1}/${2}) -Health - No Servers Inaccuracy || Ei Bukkit/Sponge palvelimia sessio tietojen keräykseen - Nämä arviot ovat epätarkkoja. -Health - Player Play on Network || pelaajaa pelasi verkossa: -Health - Player Register Server || pelaajaa rekisteröityi palvelimille per päivä/palvelin keskimäärin. -Health - Player Visit Server || pelaajaa käy palvelimilla per päivä/palvelin keskimäärin. -Health - Regular Activity Change || Kestopelaajien määrä on -Health - Regular Activity Change Decrease || pienentynyt (${0}) -Health - Regular Activity Change Increase || kasvanut (+${0}) -Health - Regular Activity Change Zero || pysynyt samana (+${0}) -Health - Regular Activity Remain || ${0} kestopelaajista on pysynyt aktiivisena (${1}/${2}) -Health - Single Servers Inaccuracy || Yksi Bukkit/Sponge palvelin sessio tietojen keräykseen. -Health - TPS Above Low Threshold || Keskimääräinen TPS oli alarajan yläpuolella ${0} ajasta -Health - TPS Low Dips || Keskimääräinen TPS putosi alarajan alapuolelle (${0}) ${1} kertaa -HTML - FREE_DISK_SPACE || Vapaa Levytila -HTML - DISK_SPACE || LEVYTILA \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_FR.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_FR.txt deleted file mode 100644 index 999c093fb..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_FR.txt +++ /dev/null @@ -1,336 +0,0 @@ -Cmd - Click Me || Cliquez ici -Cmd - Link || §2Lien : §f -Cmd Disable - Disabled || §aLes systèmes de Plan sont maintenant désactivés. Vous pouvez toujours exécuter la commande '/planbungee reload' pour les redémarrer. -Cmd FAIL - Invalid Username || §cCet utilisateur ne possède pas d'UUID. -Cmd FAIL - No Feature || §eDéfinir une fonctionnalité à désactiver ! (supporte actuellement ${0}) -Cmd FAIL - No Permission || §cVous ne possédez pas la permission requise. -Cmd FAIL - Require only one Argument || §cUn argument est requis ${1} -Cmd FAIL - Requires Arguments || §cDes arguments sont requis (${0}) ${1} -Cmd FAIL - Unknown Username || §cCet utilisateur ne s'est jamais connecté sur ce serveur. -Cmd FAIL - WebUser does not exists || §cCet utilisateur n'existe pas ! -Cmd FAIL - WebUser exists || §cCet utilisateur existe déjà ! -Cmd Header - Analysis || > §2Résultats de l'analyse -Cmd Header - Info || > §2Analyse du joueur -Cmd Header - Inspect || > §2Joueur : §f${0} -Cmd Header - Network || > §2Page du réseau -Cmd Header - Players || > §2Joueurs -Cmd Header - Search || > §2${0} Résultats pour §f${1}§2: -Cmd Header - Servers || > §2Serveurs -Cmd Header - Web Users || > §2${0} Utilisateurs Web -Cmd Info - Bungee Connection || §2Connecté à Bungee : §f${0} -Cmd Info - Database || §2Base de données active : §f${0} -Cmd Info - Reload Complete || §aRechargement terminé. -Cmd Info - Reload Failed || §cUne erreur s'est produite lors du rechargement du plugin, un redémarrage total est recommandé. -Cmd Info - Update || §2Mise à jour disponible : §f${0} -Cmd Info - Version || §2Version : §f${0} -Cmd Notify - No WebUser || Vous n'avez peut-être pas d'utilisateur Web, essayez d'exécuter '/plan register ' afin d'y remédier. -Cmd Notify - WebUser register || Nouvel utilisateur enregistré : '${0}' Niveau de permission : ${1}. -Cmd Qinspect - Activity Index || §2Indice d'activité : §f${0} | ${1} -Cmd Qinspect - Deaths || §2Morts : §f${0} -Cmd Qinspect - Geolocation || §2Connecté depuis : §f${0} -Cmd Qinspect - Last Seen || §2Vu pour la dernière fois : §f${0} -Cmd Qinspect - Longest Session || §2Session la plus longue : §f${0} -Cmd Qinspect - Mob Kills || §2Kills de Mobs : §f${0} -Cmd Qinspect - Player Kills || §2Kills de Joueurs : §f${0} -Cmd Qinspect - Playtime || §2Temps de jeu : §f${0} -Cmd Qinspect - Registered || §2Incrit depuis : §f${0} -Cmd Qinspect - Times Kicked || §2Nombre d'éjections : §f${0} -Cmd Setup - Allowed || §aLa configuration est maintenant autorisée. -Cmd Setup - Bad Request || §eLa connexion a réussi, mais le serveur de réception n'était un serveur Bukkit ou Sponge. Utilisez une autre adresse à la place. -Cmd Setup - Disallowed || §cLa configuration est maintenant interdite. -Cmd Setup - Forbidden || §eConnexion réussie, mais le mode de configuration de Bungee est désactivé. Exécutez '/plan bungee setup' pour l'activer. -Cmd Setup - Gateway Error || §eConnexion réussie, mais Bungee n'a pas réussi à se connecter à ce serveur (Le serveur Web actuel a-t-il redémarré ?). Exécutez '/plan m con' et '/planbungee con' pour déboguer. -Cmd Setup - Generic Fail || §eConnexion échouée : ${0} -Cmd Setup - Internal Error || §eConnexion échouée : ${0}, Vérifiez des possibles erreurs sur la page de débogage du serveur de réception. -Cmd Setup - Success || §aConnexion réussie, Plan peut redémarrer dans quelques secondes. -Cmd Setup - Unauthorized || §eConnexion réussie, mais le serveur de réception n'a pas autorisé ce serveur. Contactez-nous sur Discord pour obtenir de l'aide. -Cmd Setup - Url mistake || §cAssurez-vous d'utiliser l'adresse complète (commençant par http:// ou https://). Consultez les logs du Bungee pour la connaître. -Cmd Setup - WebServer not Enabled || §cLe serveur Web n'est pas activé sur ce serveur ! Assurez-vous qu'il se soit démarré lors du lancement du serveur ! -Cmd SUCCESS - Feature disabled || §aFontionnalité '${0}' temporairement désactivée jusqu'au prochain rechargement du plugin. -Cmd SUCCESS - WebUser register || §aAjout d'un nouvel utilisateur (${0}) avec succès ! Vous pouvez afficher le panneau Web dans le lien suivant. -Cmd Update - Cancel Success || §aAnnulation de l'opération... -Cmd Update - Cancelled || §cMise à jour annulée. -Cmd Update - Change log || Changements v${0}: -Cmd Update - Fail Cacnel || §cLa mise à jour a échoué sur un serveur, annulant la mise à jour sur tous les serveurs. -Cmd Update - Fail Force Notify || §e${0} échec de la mise à jour : force spécifiée, continuation. -Cmd Update - Fail Not Online || §cTous les serveurs n'étant pas en ligne ou accessibles, vous pouvez toujours mettre à jour les serveurs disponibles en exécutant '/plan update -u -force'. -Cmd Update - Notify Cancel || §aVous pouvez annuler la mise à jour sur des serveurs n'ayant pas encore redémarré en exécutant '/plan update cancel'. -Cmd Update - Online Check || Vérification que tous les serveurs soient en ligne... -Cmd Update - Scheduled || §a${0} prévu pour la mise à jour. -Cmd Update - Url mismatch || §cL'URL de téléchargement de la version ne commence pas par ${0} et n'est peut-être pas fiable. Vous pouvez télécharger cette version manuellement ici (téléchargement direct) : -Cmd Web - Permission Levels || >\§70: Accéder à toutes les pages.\§71: Accéder au '/players' et à toutes les pages des joueurs.\§72: Accéder à la page du joueur avec le même nom d'utilisateur que l'utilisateur Web.\§73+: Pas de permission. -Command Help - /plan analyze || Voir la page du serveur. -Command Help - /plan dev || Commande du mode de développement. -Command Help - /plan help || Afficher la liste des commandes. -Command Help - /plan info || Vérifier la version de Plan. -Command Help - /plan inspect || Visionner la page d'un joueur. -Command Help - /plan manage || Gérer la base de données de Plan. -Command Help - /plan manage backup || Sauvegarder une base de données. -Command Help - /plan manage clear || Effacer une base de données. -Command Help - /plan manage con || Déboguer la connexion Serveur -> Bungee. -Command Help - /plan manage disable || Désactiver temporairement une fonctionnalité. -Command Help - /plan manage hotswap || Changer rapidement de base de données. -Command Help - /plan manage import || Importer des données externes. -Command Help - /plan manage move || Déplacer des données entre des bases de données. -Command Help - /plan manage remove || Supprimer les données d'un joueur. -Command Help - /plan manage restore || Restaurer une sauvegarde précédente. -Command Help - /plan manage setup || Configuration de la connexion Serveur -> Bungee. -Command Help - /plan network || Visionner la page du réseau. -Command Help - /plan players || Visionner la page des joueurs. -Command Help - /plan qinspect || Visionner les informations d'un joueur (en jeu). -Command Help - /plan register || Enregistrer un utilisateur Web. -Command Help - /plan reload || Recharger Plan. -Command Help - /plan search || Rechercher un joueur. -Command Help - /plan servers || Obtenir la liste des serveurs dans la base de données. -Command Help - /plan update || Obtenir le lien des modifications ou du plugin mis à jour. -Command Help - /plan web check || Inspecter un utilisateur Web. -Command Help - /plan web delete || Supprimer un utilisateur Web. -Command Help - /plan web level || Informations sur les niveaux de permission. -Command Help - /plan web list || Liste des utilisateurs Web. -Command Help - /plan webuser || Gérer les utilisateurs Web. -Command Help - /planbungee con || Déboguer la connexion Bungee -> Serveur. -Command Help - /planbungee disable || Désactiver temporairement Plan. -Command Help - /planbungee setup || Basculer le mode de configuration (on/off). -Database - Apply Patch || Application de correctifs : ${0}... -Database - Patches Applied || Tous les correctifs pour la base de données ont été appliqués avec succès. -Database - Patches Applied Already || Tous les correctifs pour la base de données ont déjà été appliqués. -Database MySQL - Launch Options Error || Configurations défectueuses, utilisation de celles par défaut (${0}) -Database Notify - Clean || Suppression des données de ${0} joueurs. -Database Notify - SQLite No WAL || Le mode WAL de SQLite n'est pas pris en charge sur cette version du serveur, en utilisant le mode par défaut. Cela peut possiblement affecter les performances. -Disable || Plan a été désactivé. -Disable - Processing || Traitement des tâches critiques non traitées. (${0}) -Disable - Processing Complete || Traitement complété. -Disable - WebServer || Le serveur Web a été désactivé. -Enable || Plan a été activé. -Enable - Database || Connexion à la base de données établie. (${0}) -Enable - Notify Address Confirmation || Assurez-vous que cette adresse pointe vers ce serveur : ${0}. -Enable - Notify Empty IP || L'adresse IP située dans le fichier 'server.properties' est vide et l'option 'AlternativeIP' n'est pas utilisée. Attention, des liens incorrects seront donnés ! -Enable - Notify Geolocations disabled || La géolocalisation n'est pas active. (Data.Geolocations: false) -Enable - Notify Geolocations Internet Required || Plan nécessite un accès à Internet lors de sa première utilisation pour télécharger la base de données 'GeoLite2 Geolocation'. -Enable - Notify Webserver disabled || Le serveur Web n'a pas été initialisé. (WebServer.DisableWebServer: true) -Enable - WebServer || Le serveur Web communique à travers le port ${0} (${1}). -Enable FAIL - Database || La connexion à la base de données a échoué. (${0}) : ${1} -Enable FAIL - Database Patch || L'application de correctifs pour la base de données a échoué, le plugin doit être désactivé. Merci de signaler ce problème. -Enable FAIL - GeoDB Write || Une erreur s'est produite lors de l'enregistrement de la base de données 'GeoLite2 Geolocation' téléchargée précédemment. -Enable FAIL - WebServer (Bungee) || Le serveur Web n'a pas été initialisé ! -Enable FAIL - Wrong Database Type || ${0} n'est pas une base de données prise en charge. -HTML - ACTIVITY_INDEX || Indice d'activité -HTML - ALL || TOUT -HTML - ALL_TIME_PEAK || Pic maximal de joueurs connectés -HTML - AVERAGE_PING || Latence moyenne -HTML - AVG || MOYEN.NE -HTML - BANNED || Banni -HTML - BEST_PING || Meilleure latence -HTML - CALENDAR || CALENDRIER -HTML - CALENDAR_TEXT || Calendrier -HTML - CHUNKS || Tronçons -HTML - COMMAND || Commande -HTML - COMMNAND_USAGE || Utilisation des commandes -HTML - CONNECTION_INFORMATION || Informations de connexion -HTML - COUNTRY || Pays -HTML - CURRENT_PLAYERBASE || Base de joueurs actuelle -HTML - DEATHS || Morts -HTML - ENTITIES || Entités -HTML - ERROR || Authentification échouée à cause d'une erreur -HTML - FAVORITE_SERVER || Serveur favori -HTML - GEOLOCATION || Géolocalisation -HTML - GEOLOCATION_TEXT || Géolocalisation -HTML - HEALTH_ESTIMATE || Estimation de la santé du serveur -HTML - INDEX_ACTIVE || Actif -HTML - INDEX_INACTIVE || Inactif -HTML - INDEX_IRREGULAR || Irrégulier -HTML - INDEX_REGULAR || Régulier -HTML - INDEX_VERY_ACTIVE || Très actif -HTML - IP_ADDRESS || Adresse IP -HTML - KILLED || Tué -HTML - KILLED_BY || Tué par -HTML - LAST_24_HOURS || 24 DERNIÈRES HEURES -HTML - LAST_30_DAYS || 30 DERNIERS JOURS -HTML - LAST_30_DAYS_TEXT || 30 derniers jours -HTML - LAST_7_DAYS || 7 DERNIERS JOURS -HTML - LAST_CONNECTED || Dernier connecté -HTML - LAST_PEAK || Dernier pic de joueurs connectés -HTML - LAST_SEEN || DERNIÈRE CONNEXION -HTML - LAST_SEEN_TEXT || Dernière connexion -HTML - LOADED_CHUNKS || Tronçons chargés -HTML - LOADED_ENTITIES || Entités chargés -HTML - LOCAL_MACHINE || Machine locale -HTML - LONGEST || Plus long.ue -HTML - LOW_TPS_SPIKES || Pointes basses des TPS -HTML - MOB_CAUSED_DEATHS || Morts causées par un Mob -HTML - MOB_KDR || Mob KDR -HTML - MOB_KILLS || Kills de Mobs -HTML - MOST_RECENT_SESSIONS || Sessions récentes -HTML - NAME || Nom -HTML - NAV_COMMAND_USAGE || Utilisation des commandes -HTML - NAV_GEOLOCATIONS || Géolocalisation -HTML - NAV_INFORMATION || Informations -HTML - NAV_NETWORK_PLAYERS || Joueurs du réseau -HTML - NAV_ONLINE_ACTIVITY || Activité en ligne -HTML - NAV_OVERVIEW || Vue d'ensemble -HTML - NAV_PERFORMANCE || Performance -HTML - NAV_PLAYERS || Joueurs -HTML - NAV_PLUGINS || Plugins -HTML - NAV_SESSIONS || Sessions -HTML - NAV_SEVER_HEALTH || Santé du serveur -HTML - NETWORK || Réseau -HTML - NETWORK_INFORMATION || INFORMATIONS SUR LE RÉSEAU -HTML - NEW || NOUVEAU(X) -HTML - NEW_CALENDAR || Nouveau : -HTML - NEW_PLAYERS_TEXT || Nouveaux joueurs -HTML - NEW_RETENTION || Rétention des nouveaux joueurs -HTML - NEW_TEXT || Nouveau -HTML - NICKNAME || Surnom -HTML - NO_KILLS || Pas de Kills -HTML - NO_PLAYER_CAUSED_DEATHS || Aucun joueur n'a causé de mort -HTML - OFFLINE || Hors-ligne -HTML - ONLINE || En ligne -HTML - ONLINE_ACTIVITY || ACTIVITÉ EN LIGNE -HTML - OPERATOR || Opérateur -HTML - OVERVIEW || Vue d'ensemble -HTML - PER_DAY || / Jour -HTML - PLAYER_CAUSED_DEATHS || Décès causés par le joueur -HTML - PLAYER_KILLS || Kills de joueurs -HTML - PLAYER_LIST || Liste des joueurs -HTML - PLAYERBASE_DEVELOPMENT || Évolution de la base de joueurs -HTML - PLAYERS || JOUEURS -HTML - PLAYERS_ONLINE || JOUEURS EN LIGNE -HTML - PLAYERS_ONLINE_TEXT || Joueurs en ligne -HTML - PLAYERS_TEXT || Joueurs -HTML - PLAYTIME || Temps de jeu -HTML - PLEASE_WAIT || Merci de patienter... -HTML - PREDICETED_RETENTION || Rétention prévue -HTML - PUNCH_CARD || Carte perforée -HTML - PUNCHCARD || CARTE PERFORÉE -HTML - RECENT_LOGINS || CONNEXIONS RÉCENTES -HTML - REGISTERED || INSCRIPTION -HTML - REGISTERED_TEXT || Inscription -HTML - REGULAR || RÉGULIER(S) -HTML - SEEN_NICKNAMES || Surnoms Vus -HTML - SERVER || Serveur -HTML - SERVER_ANALYSIS || Analyse du serveur -HTML - SERVER_HEALTH_ESTIMATE || Estimation de la santé du serveur -HTML - SERVER_INFORMATION || INFORMATIONS SUR LE SERVEUR -HTML - SERVER_PREFERENCE || Préférence de serveur -HTML - SERVERS || Serveurs -HTML - SESSION || Session -HTML - SESSION_ENDED || Session terminée -HTML - SESSION_LENGTH || Durée de la session -HTML - SESSION_MEDIAN || Session médiane -HTML - SESSIONS || Sessions -HTML - TIME || Temps -HTML - TIMES_KICKED || Nombre d'éjections -HTML - TIMES_USED || Nombre d'utilisations -HTML - TOTAL_ACTIVE_TEXT || Temps actif total -HTML - TOTAL_AFK || Temps inactif total -HTML - TOTAL_PLAYERS || Joueurs totaux -HTML - TOTAL_PLAYTIME || Temps de jeu total -HTML - UNIQUE || UNIQUE -HTML - UNIQUE_CALENDAR || Unique : -HTML - UNIQUE_PLAYERS || JOUEURS UNIQUES -HTML - UNIQUE_PLAYERS_TEXT || Joueurs uniques -HTML - UNIQUE_TEXT || Unique(s) -HTML - USAGE || Utilisation -HTML - USED_COMMANDS || Commandes utilisées -HTML - USER_AND_PASS_NOT_SPECIFIED || Utilisateur et mot de passe non spécifiés -HTML - USER_DOES_NOT_EXIST || Cet utilisateur n'existe pas -HTML - USER_INFORMATION || INFORMATIONS SUR L'UTILISATEUR -HTML - USER_PASS_MISMATCH || L'utilisateur et le mot de passe ne correspondent pas -HTML - WITH ||
    Avec -HTML - WORLD || Monde -HTML - WORLD_LOAD || CHARGE DU MONDE -HTML - WORLD_PLAYTIME || Temps de jeu par monde -HTML - WORST_PING || Pire latence -HTML ERRORS - ACCESS_DENIED_403 || Accès refusé. -HTML ERRORS - ANALYSIS_REFRESH || L'analyseur est en cours de rafraîchissement... -HTML ERRORS - ANALYSIS_REFRESH_LONG || L'analyse est en cours d'exécution, actualisez la page après quelques secondes.... -HTML ERRORS - AUTH_FAIL_TIPS_401 || - Assurez-vous d'avoir enregistré un utilisateur avec :'/plan register'.
    - Vérifiez que le nom d'utilisateur et le mot de passe soient corrects.
    - Le nom d'utilisateur et le mot de passe sont sensibles au format majuscule/minuscule.

    Si vous avez oublié votre mot de passe, demandez à un membre du staff de supprimer votre ancien utilisateur puis de vous réinscrire. -HTML ERRORS - AUTHENTICATION_FAILED_401 || Authentification échouée. -HTML ERRORS - FORBIDDEN_403 || Accès interdit. -HTML ERRORS - NO_SERVERS_404 || Aucun serveur en ligne pour exécuter la demande. -HTML ERRORS - NOT_FOUND_404 || Non trouvé. -HTML ERRORS - NOT_PLAYED_404 || Cet utilisateur ne s'est jamais connecté sur ce serveur. -HTML ERRORS - PAGE_NOT_FOUND_404 || Cette page n'existe pas. -HTML ERRORS - UNAUTHORIZED_401 || Non autorisé. -HTML ERRORS - UNKNOWN_PAGE_404 || Assurez-vous que vous accédez à un lien donné par une commande. Exemples :

    /player/PlayerName
    /server/ServerName

    -HTML ERRORS - UUID_404 || L'UUID de cet utilisateur n'a pas été trouvé dans la base de données. -In Depth Help - /plan ? || > §2Commande principale\ Accès aux sous-commandes et à l'aide\ §2/plan §fListe des sous-commandes\ §2/plan ? §fAide profonde -In Depth Help - /plan analyze ? || > §2Commande d'analyse\ Actualise la page du serveur et affiche un lien vers la page Web. -In Depth Help - /plan inspect ? || > §2Commande d'inspection\ Actualise la page du joueur et affiche un lien vers la page Web. -In Depth Help - /plan manage ? || > §2Commande de gestion\ Gestion des bases de données MySQL et SQLite de Plan.\ §2/plan m §fListe des sous-commandes\ §2/plan m ? §fAide en profondeur -In Depth Help - /plan manage backup ? || > §2Sous-commande de sauvegarde\ Crée une nouvelle base de données SQLite (fichier .db) avec le contenu de la base de données actuellement active dans la configuration de Plan. -In Depth Help - /plan manage clear ? || > §2Sous-commande d'effacement\ Supprime l'intégralité de la base de données active. À utiliser avec précaution. -In Depth Help - /plan manage con ? || > §2Sous-commande de débogage de connexion\ Utilisée pour déboguer les connexions du réseau.\ Envoie une demande à chaque serveur présent dans la base de données. -In Depth Help - /plan manage disable ? || > §2Sous-commande de désactivation\ Peut désactiver des parties du plugin jusqu'au prochain rechargement.\ Arguments acceptés :\§2kickcount §fDésactive le comptage d'éjections dans le cas où tous les joueurs ont été expulsés par un arrêt. -In Depth Help - /plan manage import ? || > §2Sous-commande d'importation\ Importe des données depuis d'autres sources.\ Arguments acceptés :\ §2offline §fDonnées du joueur Bukkit, uniquement la date d'enregistrement et le nom. -In Depth Help - /plan manage move ? || > §2Sous-commande de déplacement\ Déplace les données de SQLite vers MySQL ou autre.\ La base de données cible est effacée avant le transfert. -In Depth Help - /plan manage remove ? || > §2Sous-commande de suppression\ Supprime les données d'un joueur de la base de données active. -In Depth Help - /plan manage restore ? || > §2Sous-commande de restauration\ Restaure une sauvegarde de base de données SQLite précédente (fichier .db)\ Vous pouvez également restaurer le fichier database.db d'un autre serveur vers MySQL.\ La base de données cible est effacée avant le transfert. -In Depth Help - /plan manage setup ? || > §2Sous-commande de configuration\ Configure une connexion entre Bungee et ce serveur pour la fonctionnalité réseau.\ Vous pouvez trouver l'adresse du Bungee dans les logs de la la console lorsque Plan est activé sur Bungee. -In Depth Help - /plan network ? || > §2Sous-commande du réseau\ Affiche le lien vers la page du réseau.\ S'il ne s'agit pas d'un réseau, elle affiche la page du serveur. -In Depth Help - /plan players ? || > §2Commande des joueurs\ Affiche un lien vers la page des joueurs. -In Depth Help - /plan qinspect ? || > §2Quick Inspect CommandCommande d'inspection rapide\ Affiche des informations sur un joueur en jeu. -In Depth Help - /plan reload ? || > §2Commande de rechargement\ Redémarre le plugin en utilisant onDisable et onEnable.\ §bNe supporte pas l'échange de .jar à la volée (sans redémarrage complet) -In Depth Help - /plan search ? || > §2Commande de recherches\ Obtient une liste des joueurs correspondant à l'argument donné.\§7 Exemple: /plan search 123 - Recherche tous les utilisateurs dont le nom comporte '123'. -In Depth Help - /plan servers ? || > §2Commande des serveurs\ Affiche la liste des serveurs de Plan présents dans la base de données.\ Peut être utilisé pour résoudre les problèmes d'enregistrement de base de données sur un réseau. -In Depth Help - /plan update ? || > §2Commande de mise à jour\ Utilisé pour mettre à jour le plugin lors du prochain arrêt\ /plan update - Lien des modifications\ /plan update -u - Planifie la mise à jour sur tous les serveurs de réseau en ligne, au prochain redémarrage.\ /plan update cancel - Annule la mise à jour programmée sur les serveurs qui n'ont pas encore redémarré. -In Depth Help - /plan web ? || < §2Commande de la gestion d'utilisateurs Web\ §2/plan web §fListe des sous-commandes\ §2/plan web ? §fAide en profondeure -In Depth Help - /plan web register ? || > §2Commande d'enregistrement\ Enregistre un nouvel utilisateur Web.\ L'enregistrement d'un utilisateur pour un autre joueur nécessite l'autorisation 'plan.webmanage'.\ Les mots de passe sont hachés avec PBKDF2 (64000 itérations de SHA1) en utilisant 'un sel cryptographiquement aléatoire'. -In Depth Help - /planbungee disable ? || > §2Commande de désactivation\ Lance onDisable pour PlanBungee.\ Le plugin peut être activé par la suite en exécutant la commande /planbungee reload.\ §bNe supporte pas l'échange de .jar à la volée (sans redémarrage complet) -In Depth Help - /planbungee setup ? || > §2Commande de bascule de configuration\ Bascule le mode de configuration sur Bungee.\ Protégez-vous contre le 'fouinage' non autorisée de MySQL avec un autre serveur. -Manage - Confirm Overwrite || Les données ${0} seront écrasées ! -Manage - Confirm Removal || Les données ${0} seront supprimées ! -Manage - Fail || > §cUne erreur est survenue : ${0}. -Manage - Fail File not found || > §cAucun fichier trouvé depuis ${0}. -Manage - Fail Incorrect Database || > §c'${0}' n'est pas une base de données prise en charge. -Manage - Fail No Importer || §eL'importateur '${0}' n'existe pas. -Manage - Fail Same Database || > §cNe peut pas opérer sur et depuis la même base de données ! -Manage - Fail, Confirmation || > §cAjoutez l'argmenter '-a' afin de confirmer l'éxécution : ${0} -Manage - Fail, Connection Exception || §eRaison de l'échec : -Manage - Fail, No Servers || §cAucun serveur trouvé dans la base de données. -Manage - Fail, Old version || §eRaison de l'échec : Le serveur de réception utilise une ancienne version de Plan. -Manage - Fail, Unauthorized || §eRaison de l'échec : Non autorisé. Le serveur utilise peut-être une base de données différente. -Manage - Fail, Unexpected Exception || §eErreur : ${0}. -Manage - List Importers || Importateurs : -Manage - Notify External Url || §eAdresse non locale, vérifiez que le port soit ouvert. -Manage - Remind HotSwap || §eN'oubliez pas de passer à la nouvelle base de données (/plan m hotswap ${0}) & de recharger Plan. -Manage - Start || > §2Traitement des données... -Manage - Success || > §aSuccès ! -Negative || Non -Positive || Oui -Unknown || Inconnu -Version - DEV || Ceci est une version de développement. -Version - Latest || Vous utilisez la dernière version. -Version - New || Une nouvelle version (${0}) est disponible ${1} -Version - New (old) || Une nouvelle version est disponible depuis ${0} -Version FAIL - Read info (old) || Impossible de vérifier le dernier numéro de la version -Version FAIL - Read versions.txt || Les informations de la version n'ont pas pu être chargées depuis Github/versions.txt -Web User Listing || §2${0} §7: §f${1} -WebServer - Notify HTTP || Serveur Web : Aucun certificat -> Utilisation du serveur HTTP pour la visualisation. -WebServer - Notify HTTP User Auth || Serveur Web : Authentification utilisateur désactivée ! (Non sécurisée avec HTTP) -WebServer - Notify no Cert file || Serveur Web : Fichier KeyStore du certificat introuvable : ${0} -WebServer FAIL - Port Bind || Le Serveur Web n'a pas été initialisé avec succès. Le port (${0}) est-il actuellement utilisé ? -WebServer FAIL - SSL Context || Serveur Web : Échec d'initialisation du contexte SSL. -WebServer FAIL - Store Load || Serveur Web : Échec du chargement du certificat SSL. -Yesterday || 'Hier' -Today || 'Aujourd''hui' -Health - Active Playtime Comparison Decrease || Les joueurs actifs risquent de manquer de choses à faire (Joué ${0} contre ${1}, les deux dernières semaines par rapport aux semaines 2 à 4). -Health - Active Playtime Comparison Increase || Les joueurs actifs semblent avoir des choses à faire (Joué ${0} contre ${1}, les deux dernières semaines par rapport aux semaines 2 à 4). -Health - Downtime || Le temps total d'arrêt du serveur (absence de données) était de ${0}. -Health - New Player Join Players, No || Les nouveaux joueurs peuvent ne pas avoir de joueurs avec lesquels jouer (${0} en moyenne). -Health - New Player Join Players, Yes || Les nouveaux joueurs ont des joueurs avec lesquels jouer (${0} en moyenne). -Health - New Player Stickiness || ${0} des nouveaux joueurs sont restés (${1}/${2}). -Health - No Servers Inaccuracy || Aucun serveur Bukkit/Sponge pour collecter des données de session - Ces mesures sont inexactes. -Health - Player Play on Network || joueurs jouent sur le réseau : -Health - Player Register Server || joueurs s'enregistrent surle serveur par jour/serveur en moyenne. -Health - Player Visit Server || joueurs visitent le serveur par jour/serveur en moyenne. -Health - Regular Activity Change || Le nombre de joueurs réguliers a -Health - Regular Activity Change Decrease || diminué (${0}). -Health - Regular Activity Change Increase || augmenté (+${0}). -Health - Regular Activity Change Zero || stagné (+/-${0}). -Health - Regular Activity Remain || ${0} des joueurs réguliers sont restés actifs (${1}/${2}). -Health - Single Servers Inaccuracy || Un seul serveur Bukkit/Sponge pour collecter les données de session. -Health - TPS Above Low Threshold || Les TPS moyens étaient supérieurs au seuil bas ${0} du temps. -Health - TPS Low Dips || Les TPS moyens sont descendus sous le seuil bas (${0}) ${1} fois. -HTML - FREE_DISK_SPACE || Espace disque disponible -HTML - DISK_SPACE || ESPACE DISQUE diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_FR_old.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_FR_old.txt deleted file mode 100644 index 6cdfddc45..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_FR_old.txt +++ /dev/null @@ -1,118 +0,0 @@ -Analysis - Third Party || Analyse | Analyse des sources de données supplémentaires (tierce partie). -Analysis FAIL - Fetch Exception || Analyse | Échec de l’extraction des données pour l’analyse, une exception s'est produite. -Analysis FAIL - No Data || Analyse | L'analyse a échoué, aucune donnée dans la base de données. -Analysis FAIL - No Players || Analyse | L'analyse a échoué, aucun joueur connu. -Analysis - Fetch Phase || Analyse | Récupération des données.. -Analysis - Fetch Phase Start || Analyse | Vérification des joueurs disponibles.. -Analysis - Complete || Analyse | Analyse terminée. (En ${0}ms) ${1} -Analysis - Begin Analysis || Analyse | Données récupérées (${0} utilisateurs, en ${1}ms), début Analyse des données.. -Analysis - Start || Analyse | Début de l'analyse des données utilisateur.. ->Constant - CMD Footer || §f» ->Constant - List Ball || §7 •§2 -Cmd FAIL - No Data View || §e[Plan] Aucun moyen de voir les données disponibles. -Cmd FAIL - No Permission || §c[Plan] Vous n'avez pas la permission requise. -Cmd FAIL - Requires Arguments || §c[Plan] La commande nécessite des arguments. ${0} -Cmd FAIL - Require only one Argument || §c[Plan] La commande nécessite un argument. -Cmd FAIL - Timeout || §c[Plan] ${0} La commande a expiré ! Vérifiez avec '/plan status' et la console. -Cmd FAIL - Unknown Username || §c[Plan] Joueur introuvable dans la base de données. -Cmd FAIL - Unseen Username || §c[Plan] Ce joueur n'a pas joué sur ce serveur. -Cmd FAIL - Invalid Username || §c[Plan] Ce joueur n'existe pas. -Cmd Header - Analysis || §f»§2 Player Analytics - Résultats de l’analyse -Cmd Header - Info || §f»§2 Player Analytics - Info -Cmd Header - Inspect || §f»§2 Player Analytics - Résultats de l’inspection -Cmd Header - Search || §f»§2 Player Analytics - Résultats de la recherche: -In Depth Help - /plan analyze ? || §2Commande d’analyse\§f Utilisé pour actualiser le cache d'analyse et accéder à la page de résultats\§7 /plan status peut être utilisé pour vérifier le statut de l'analyse pendant son exécution.\§7 Alias: analyze, analyse, analysis, a -In Depth Help - /plan inspect ? || §2Commande d’inspection\§f Utilisé pour obtenir un lien vers la page d'inspection d’un utilisateur.\§7 Votre propre page d'inspection peut être consultée avec /plan inspect\§7 Alias: /plan -In Depth Help - /plan list ? || §2Commande de listing\§f Utilisé pour obtenir un lien vers la page des joueurs.\§7 La page des joueurs contient des liens vers toutes les pages d'inspection mises en cache.\§7 Alias: /plan pl -In Depth Help - /plan manage ? || §2Commande de gestion\§f Utilisé pour gérer la base de données du plugin.\§7 Alias: /plan m\§7 /plan m - Liste des sous-commandes\§7 /plan m ? - aide approfondie -In Depth Help - /plan manage clear ? || §2Gestion: Commande d’effacement.\§f Utilisé pour supprimer TOUTES les données dans la base de données active.\§7 Le plugin doit être rechargé après l’effacement terminé.\§7 Alias: /plan pl -In Depth Help - /plan manage dump ? || §2Gestion: Commande de listage\§f Utilisé pour lister des données importantes pour le rapport de bug à hastebin. -In Depth Help - /plan manage hotswap ? || §2Gestion: Commande de Hotswap\§f Utilisé pour modifier la base de données en cours d'utilisation.\§7 Ne change pas la base de données si la connexion échoue. -In Depth Help - /plan manage import ? || §2Gestion: Commande d'importation\§f Utilisé pour importer des données d'autres sources\§7 L'analyse sera désactivée pendant l'importation. -In Depth Help - /plan manage remove ? || §2Gestion: Commande de suppression\§f Utilisé pour supprimer les données de l'utilisateur de la base de données active. -In Depth Help - /plan ? || §2/plan - Commande principale\§f Utilisé pour accéder à toutes les sous-commandes et aide\§7 /plan - Liste des sous-commandes\§7 /plan ? - aide approfondie -In Depth Help - /plan qanalyze ? || §2Commande d'analyse rapide\§f Utilisé pour obtenir des informations en jeu sur l'analyse.\§7 A moins d'informations que la page Web d'analyse complète.\§7 Alias: qanalyze, ganalyse, qanalysis, qa -In Depth Help - /plan qinspect ? || §2Commande d'inspection rapide\§f Utilisé pour obtenir des informations d'inspection en jeu.\§7 A moins d'informations que la page Web d'inspection complète.\§7 Alias: /plan qi -In Depth Help - /plan search ? || §2Commande de recherche\§f Utilisé pour obtenir une liste des noms de joueurs qui correspondent à l'argument donné.\§7 Exemple: /plan search 123 - Trouve tous les utilisateurs avec 123 dans leur nom. -In Depth Help - /plan webuser ? || §2Commande de gestion des utilisateurs Web\§f Utilisé pour gérer les utilisateurs Web du plugin\§7 Les utilisateurs ont un niveau de permission:\§f 0 - Accès à toutes les pages\§f 1 - Accès à /players et toutes les pages d'inspection\§f 2 - Accès à sa propre page d'inspection\§7 Alias: /plan web -In Depth Help - /plan webuser register ? || §2Commande Web Register\§f Utilisé pour enregistrer un nouvel utilisateur pour le serveur Web.\§7 L'inscription d'un utilisateur pour un autre joueur nécessite la permission plan.webmanage.\§7 Les mots de passe sont hachés avec PBKDF2 (64,000 itérations de SHA1) en utilisant un sel cryptographiquement aléatoire. -Analysis NOTIFY - Temporary Disable || §eL'analyse a été temporairement désactivée en raison d’un charge trop importante, faites /plan status pour plus d'informations. -Cmd - Click Me || Cliquez ici -Cmd - Fetch Data || §f»§2 Récupération des données dans le cache.. -Cmd - Link || §7 • §2Lien: §f -Cmd - No Results || §7 • §2Aucun résultat pour §7${0}§2. -Cmd - Reload Success || §a[Plan] Recharge terminée. -Cmd - Results || §7 Joueurs correspondants: §f -Cmd - Searching || §f»§2Recherche.. -Cmd - Usage /plan analyze || Voir l'analyse du serveur -Cmd - Usage /plan help || Afficher la liste des commandes. -Cmd - Usage /plan info || Vérifier la version de of Plan -Cmd - Usage /plan inspect || Inspecter les données du joueur -Cmd - Usage /plan list || Liste à tous les joueurs mis en cache -Cmd - Usage /plan manage || Commande de gestion de base de données -Cmd - Usage /plan manage backup || Sauvegarder une base de données dans un fichier .db -Cmd - Usage /plan manage clean || Effacer les anciennes données de la base de données -Cmd - Usage /plan manage clear || Effacer TOUTES les données de la base de données -Cmd - Usage /plan manage dump || Créez un journal Hastebin pour les développeurs pour faciliter le rapport de bug -Cmd - Usage /plan manage hotswap || Hot Swap à une autre base de données et redémarrer le plugin -Cmd - Usage /plan manage import || Importer des données depuis les plugins pris en charge vers la base de données active. -Cmd - Usage /plan manage move || Copier les données d'une base de données à une autre et remplacer les valeurs -Cmd - Usage /plan manage remove || Supprimer les données des joueurs de la base de données active. -Cmd - Usage /plan manage restore || Restaurer une base de données à partir d'un fichier de sauvegarde -Cmd - Usage /plan qanalyze || Voir l'analyse du serveur sous forme de texte -Cmd - Usage /plan qinspect || Inspecter les données du joueur sous forme de texte -Cmd - Usage /plan reload || Redémarrer le plugin (Recharge la configuration) -Cmd - Usage /plan search || Rechercher un joueur -Cmd - Usage /plan webuser || Gérer les utilisateurs Web -Cmd - Usage /plan webuser check || Vérifiez un utilisateur Web et son niveau de permission. -Cmd - Usage /plan webuser delete || Supprimer un utilisateur Web -Cmd - Usage /plan webuser level || Informations sur les niveaux de permission. -Cmd - Usage /plan webuser register || Enregistrer un utilisateur pour le serveur Web -Disable || Player Analytics Désactivé. -Disable - Save || Sauvegarde des données mises en cache.. -Disable - WebServer || Arrêt du serveur Web.. -Enable || Player Analytics Activé. -Enable - Boot Analysis 30s Notify || Analyse | Analyse de démarrage dans 30 secondes.. -Enable - Boot Analysis Notify || Analyse | Démarrage l'analyse de démarrage.. -Enable Db FAIL - Disable Info || L'initialisation de la base de données a échoué, désactivation de Plan. -Enable - Db Info || ${0}-connexion à la base de données établie. -Enable - Db || Initialisation de la base de données.. -Enable FAIL-Db || ${0}-Connexion à la base de données échouée: ${1} -Enable FAIL - Wrong Db Type || Ce type de base de données n'existe pas. -Enable Notify - ChatListener || §eÉcouteur de chat désactivé, information de pseudo inexacte. -Enable Notify - Disabled CommandListener || §eÉcouteur d'utilisation des commandes désactivé. -Enable Notify - Disabled DeathListener || §eÉcouteur de morts désactivé, morts de joueur et de mob non enregistrées.. -Enable Notify-Empty IP || §eL’IP dans server.properties est vide et AlternativeServerIP n'est pas utilisé, des liens incorrects seront donnés ! -Enable Notify - No data view || §eServeur Web désactivé mais AlternativeIP non utilisé, aucun moyen d'afficher les données ! -Enable - WebServer || Initialisation du serveur Web.. -Enable - WebServer Info || Serveur Web en cours d'exécution sur le PORT ${0} -Html - Active || Le joueur est actif -Html - Banned || | Banni -Html - Inactive || Le joueur est inactif -Html - No Extra Plugins ||

    Aucun plugin supplémentaire enregistré.

    -Html - Offline || | Hors ligne -Html - Online || | En ligne -Html - OP || , Opérateur (Op) -Html - Table No Kills || Pas de kills -Manage FAIL - Confirm Action || §c[Plan] Ajoutez -a pour confirmer l'exécution ! ${0} -Manage FAIL - Faulty DB Connection || §c[Plan] Une des bases de données n'a pas été initialisée correctement. -Manage FAIL - Backup File Not Found || §c[Plan] Le fichier de sauvegarde n'existe pas ! -Manage FAIL - Incorrect DB || §c[Plan] Base de données incorrecte ! (sqlite/mysql accepté): -Manage FAIL - Incorrect Plugin || §c[Plan] Plugin non supporté: -Manage FAIL - Empty DB || §c[Plan] La base de données n'a pas de données de joueur ! -Manage FAIL - Unenabled Plugin || §c[Plan] Le plugin n'est pas activé: -Manage FAIL - Same DB || §c[Plan] Impossible de passer à la même base de données ! -Manage - Clear Success || §a[Plan] Toutes les données ont été effacées avec succès! -Manage - Remind Config Change || §e[Plan] N'oubliez pas de basculer vers la nouvelle base de données et de recharger le plugin -Manage - Copy Success || §a[Plan] Toutes les données ont été copiées avec succès ! -Manage - Process Fail || §c[Plan] Quelque chose s'est mal passé pendant le traitement des données ! -Manage - Import || §f» §2 Importation de données.. -Manage - Move Success || §a[Plan] Toutes les données ont été déplacées avec succès ! -Manage - Remove Success || §f» §2Les données de §f${0}§2 ont été supprimées de la base de données §f${1}§2. -Manage - Start || »§7 Traitement des données.. -Manage - Success || §f» §2 Succès ! -Manage NOTIFY - Overwrite || Les données dans la base de données ${0} seront écrasées ! -Manage NOTIFY - Partial Overwrite || Quelques données dans la base de données ${0} seront écrasées ! -Manage NOTIFY - Remove || Les données dans la base de données ${0} seront supprimées ! -Manage NOTIFY - Rewrite || Les données dans la base de données ${0} seront réécrites ! -WARN - Too Small Queue Size || La taille de la file d'attente est trop petite ! (${0}), changez le réglage à un nombre plus élevé ! (Actuellement ${1}) diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_IT_old.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_IT_old.txt deleted file mode 100644 index ed11648d9..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_IT_old.txt +++ /dev/null @@ -1,118 +0,0 @@ -Analysis - Third Party || Analisi | Sto analizzando ulteriori dati (terze parti) -Analysis FAIL - Fetch Exception || Analisi | Errore durante la raccolta dati per l'analisi. -Analysis FAIL - No Data || Analisi | Analisi fallita, nessun dato nel database. -Analysis FAIL - No Players || Analisi | Analisi fallita, nessun player presente. -Analysis - Fetch Phase || Analisi | Raccolta dati.. -Analysis - Fetch Phase Start || Analisi | Verifica players disponibili.. -Analysis - Complete || Analisi | Analisi completa. (ho impiegato ${0}ms) ${1} -Analysis - Begin Analysis || Analisi | Dati raccolti (${0} utenti, ho impiegato ${1}ms), Inizio l'analisi dei dati.. -Analysis - Start || Analisi | Inizio analisi dei dati utente.. ->Constant - CMD Footer || §f» ->Constant - List Ball || §7 •§2 -Cmd FAIL - No Data View || §e[Plan] Nessun modo per visualizzare i dati disponibili. -Cmd FAIL - No Permission || §c[Plan] Non hai il permesso richiesto. -Cmd FAIL - Requires Arguments || §c[Plan] Il comando richiede argomenti. ${0} -Cmd FAIL - Require only one Argument || §c[Plan] Il comando richiede un argomento. -Cmd FAIL - Timeout || §c[Plan] ${0} Time out del comando! Esegui '/plan status' & console. -Cmd FAIL - Unknown Username || §c[Plan] Player non trovato nel database. -Cmd FAIL - Unseen Username || §c[Plan] Questo player non ha mai giocato nel server. -Cmd FAIL - Invalid Username || §c[Plan] Questo player non esiste. -Cmd Header - Analysis || §f»§2 Player Analytics - Analisi risultati -Cmd Header - Info || §f»§2 Player Analytics - Informazioni -Cmd Header - Inspect || §f»§2 Player Analytics - Risultato ispezione -Cmd Header - Search || §f»§2 Player Analytics - Risultati ricerca: -In Depth Help - /plan analyze ? || §2Comando Analyze\§f Usato per aggiornare la cache di analisi & Accedere alla pagina dei risultati\§7 /plan status pue' essere usato per verificare lo stato dell'analisi in corso.\§7 Alias: analyze, analyse, analysis, a -In Depth Help - /plan inspect ? || §2Comando Inspect\§f Usato per ottenere un link alla Pagina Ispezione Utente.\§7 E' possibile accedere alla propria pagina con /plan inspect\§7 Alias: /plan -In Depth Help - /plan list ? || §2Comando List\§f Usato per ottenere un link alla pagina che elenca i players.\§7 La pagina dei players contiene i links a tutte le pagine di ispezione generate.\§7 Alias: /plan pl -In Depth Help - /plan manage ? || §2Comando Manage\§f USato per gestire il database del plugin.\§7 Alias: /plan m\§7 /plan m - Lista sottocomandi\§7 /plan m ? - Help avanzato -In Depth Help - /plan manage clear ? || §2Comando Manage Clear\§f Usato per cancellare TUTTI i dati del database attivo.\§7 Il plugin deve essere reloadato dopo questo comando.\§7 Alias: /plan pl -In Depth Help - /plan manage dump ? || §2Comando Manage Dump\§f Usato per raccogliere dati e caricarli su hastebin per riportare bug. -In Depth Help - /plan manage hotswap ? || §2Comando Manage Hotswap\§f Usato per cambiare database in uso al volo.\§7 L'operazione non viene effettuata se la connessione al database non viene stabilita correttamente. -In Depth Help - /plan manage import ? || §2Comando Manage Import\§f Usato per importare i dati da altre sorgenti\§7 Durante l'importazione non sara' possibile effettuare analisi. -In Depth Help - /plan manage remove ? || §2Comando Manage Remove\§f Usato per rimuovere dati utente dal database in uso. -In Depth Help - /plan ? || §2/plan - Comando Principale\§f Usato per accedere a tutti i sottocomandi & help\§7 /plan - elenca i sottocomandi\§7 /plan ? - Help avanzato -In Depth Help - /plan qanalyze ? || §2Comando Quick Analysis\§f Usato per avere informazioni sull'analisi in game.\§7 Contiene meno informazioni dell'analisi su pagina web.\§7 Alias: qanalyze, ganalyse, qanalysis, qa -In Depth Help - /plan qinspect ? || §2Comando Quick Inspect\§f Usato per avere alcune informazioni in game.\§7 ontiene meno informazioni dell'inspect su pagina web.\§7 Alias: /plan qi -In Depth Help - /plan search ? || §2Comando Search\§f Visualizza una lista dei nami che includono la stringa cercata.\§7 Esempio: /plan search 123 - Trova tutti gli utenti con "123" nel loro nome. -In Depth Help - /plan webuser ? || §2Comando Web User Manage\§f Usato per gestire gli utenti web del plugin\§7 Livello dei permessi:\§f 0 - Accesso a tutte le pagine\§f 1 - Accesso a /players e tutte le pagine inspect\§f 2 - Accesso alla propria pagina inspect\§7 Alias: /plan web -In Depth Help - /plan webuser register ? || §2Comando Web Register\§f Usato per registrare un nuovo utente nel webserver.\§7 La registrazione di un altro utente richiede il permesso plan.webmanage.\§7 Password criptate con PBKDF2 (64,000 iterazioni di SHA1). -Analysis NOTIFY - Temporary Disable || §eAnalisi temporaneamente disabilitata per sovraccarico, usa /plan status per informazioni. -Cmd - Click Me || Cliccami -Cmd - Fetch Data || §f»§2 Raccolta dati nella cache.. -Cmd - Link || §7 • §2Link: §f -Cmd - No Results || §7 • §2Nessun risultato per §7${0}§2. -Cmd - Reload Success || §a[Plan] Reload completo. -Cmd - Results || §7 Matching players: §f -Cmd - Searching || §f»§2Ricerca.. -Cmd - Usage /plan analyze || Visualizza Analisi Server -Cmd - Usage /plan help || Visualizza elenco comandi. -Cmd - Usage /plan info || Controlla la versione di Plan -Cmd - Usage /plan inspect || Ispeziona i dati dei players -Cmd - Usage /plan list || Lista a tutti i players -Cmd - Usage /plan manage || Comando gestione database -Cmd - Usage /plan manage backup || Backup del database in un file .db -Cmd - Usage /plan manage clean || Cancella i vecchi dati dal database -Cmd - Usage /plan manage clear || Cancella TUTTI i dati dal database -Cmd - Usage /plan manage dump || Crea un log su Hastebin log utile per il Developer per la segnalazione bug. -Cmd - Usage /plan manage hotswap || Cambio rapido del database & restart plugin -Cmd - Usage /plan manage import || Importa data da plugin supportati nel database attivo. -Cmd - Usage /plan manage move || Copia dati da un database all'altro e sovrascrive i valori -Cmd - Usage /plan manage remove || Rimuove i dati dei player dal database attivo. -Cmd - Usage /plan manage restore || Ripristina il database da un file di backup -Cmd - Usage /plan qanalyze || Mostra l'analisi del server come testo in game -Cmd - Usage /plan qinspect || Mostra l'inspect di un player come testo in game -Cmd - Usage /plan reload || Ricarica il plugin (Ricarica i config) -Cmd - Usage /plan search || Ricerca player -Cmd - Usage /plan webuser || Gestisci utenti Web -Cmd - Usage /plan webuser check || Controlla un utente Web e il suo livello di permesso. -Cmd - Usage /plan webuser delete || Cancella un utente Web -Cmd - Usage /plan webuser level || Informazioni sui livelli di permesso degli utenti Web. -Cmd - Usage /plan webuser register || Reegistra un utente Web -Disable || Player Analytics Disabilitato. -Disable - Save || Salvo i dati dalla cache.. -Disable - WebServer || Spegnimento Webserver.. -Enable || Player Analytics Abilitato. -Enable - Boot Analysis 30s Notify || Analisi | Analisi all'avvio in 30 secondi.. -Enable - Boot Analysis Notify || Analisi | Inizio analisi all'avvio.. -Enable Db FAIL - Disable Info || Inizializzazione database fallita, disattivazione Plan. -Enable - Db Info || ${0}-connessione al database stabilita. -Enable - Db || Inizializzazione database.. -Enable FAIL-Db || ${0}-Connessione al database fallita: ${1} -Enable FAIL - Wrong Db Type || Questo tipo di database non esiste. -Enable Notify - ChatListener || §eChatListener disabilitato, informazioni sul nickname non accurate. -Enable Notify - Disabled CommandListener || §eCommandListener disabilitato. -Enable Notify - Disabled DeathListener || §eDeathListener disabilitato, morti e uccisioni mob non disponibili. -Enable Notify-Empty IP || §eL'IP nel server.properties e' vuoto & AlternativeServerIP non e' usato, riceverai link errati! -Enable Notify - No data view || §eWebserver disabilitato e Alternative IP non usato, non potrai vedere i dati! -Enable - WebServer || Inizializzazione Webserver.. -Enable - WebServer Info || Webserver attivo sulla PORTA ${0} -Html - Active || Player Attivo -Html - Banned || | Bannati -Html - Inactive || Player non attivo -Html - No Extra Plugins ||

    NEssun altro plugin registrato.

    -Html - Offline || | Offline -Html - Online || | Online -Html - OP || , Operatore (Op) -Html - Table No Kills || No Kills -Manage FAIL - Confirm Action || §c[Plan] Aggiungi "-a" per confermare esecuzione! ${0} -Manage FAIL - Faulty DB Connection || §c[Plan] Uno dei database non e' stato inizializzato correttamente. -Manage FAIL - Backup File Not Found || §c[Plan] BFile di backup inesistente! -Manage FAIL - Incorrect DB || §c[Plan] Database errato! (accettati sqlite o mysql): -Manage FAIL - Incorrect Plugin || §c[Plan] Plugin non supportato: -Manage FAIL - Empty DB || §c[Plan] Il database non ha dati sui player! -Manage FAIL - Unenabled Plugin || §c[Plan] Plugin non abilitato: -Manage FAIL - Same DB || §c[Plan] Non posso spostare i dati sullo stesso database! -Manage - Clear Success || §a[Plan] Tutti i dati cancellati correttamente! -Manage - Remind Config Change || §e[Plan] Ricardati di selezionare il nuovo database e ricaricare il plugin -Manage - Copy Success || §a[Plan] Tutti i dati copiati correttamente! -Manage - Process Fail || §c[Plan] Qualcosa e' andato storto processando i dati! -Manage - Import || §f» §2 Imporazione dei dati.. -Manage - Move Success || §a[Plan] Tutti i dati spostati correttamente! -Manage - Remove Success || §f» §2Dati di §f${0}§2 rimossi dal database §f${1}§2. -Manage - Start || »§7 Processo dei dati in corso.. -Manage - Success || §f» §2 Completato! -Manage NOTIFY - Overwrite || I dati del database ${0} verranno sovrascritti! -Manage NOTIFY - Partial Overwrite || Alcuni dati del database ${0} verranno sovrascritti! -Manage NOTIFY - Remove || I dati del database ${0} verranno rimossi! -Manage NOTIFY - Rewrite || I dati del database ${0} verranno riscritti! -WARN - Too Small Queue Size || Dimensione della coda troppo piccola! (${0}), cambia le impostazioni in un numero maggiore! (Attualmente ${1}) diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_JA.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_JA.txt deleted file mode 100644 index 4c48d83f6..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_JA.txt +++ /dev/null @@ -1,340 +0,0 @@ -Cmd - Click Me || ここをクリック -Cmd - Link || §2リンク: §f -Cmd Disable - Disabled || §a「Plan」は無効になりました。「/planbungee reload」コマンドを使ってプラグインを再起動できます -Cmd FAIL - Database not open || §cデータベースは${0}です - しばらくしてからもう一度お試し下さい -Cmd FAIL - Invalid Username || §cこのユーザーはUUIDを所持していません -Cmd FAIL - No Feature || §eこの機能は現在使用されていません! (現在、「${0}」をサポートしています) -Cmd FAIL - No Permission || §cあなたには実行する権限がありません -Cmd FAIL - Require only one Argument || §c一つの引数「${1}」が必要です -Cmd FAIL - Requires Arguments || §c引数「(${0}) ${1}」が必要です -Cmd FAIL - Unknown Username || §c入力されたユーザーはBukkit/Spigotサーバー上にいません -Cmd FAIL - WebUser does not exists || §c入力されたユーザーは存在しません! -Cmd FAIL - WebUser exists || §c入力されたユーザー名は既に使われています! -Cmd Header - Analysis || > §2分析結果 -Cmd Header - Info || > §2プレイヤーの分析結果 -Cmd Header - Inspect || > §2プレイヤー: §f${0} -Cmd Header - Network || > §2ネットワークページ -Cmd Header - Players || > §2プレイヤー -Cmd Header - Search || > §2${0} §f${1}§2 の結果: -Cmd Header - Servers || > §2サーバー -Cmd Header - Web Users || > §2${0} ウェブユーザー -Cmd Info - Bungee Connection || §2BungeeCordに接続済み: §f${0} -Cmd Info - Database || §2動作中のデータベース: §f${0} -Cmd Info - Reload Complete || §aリロードが完了しました -Cmd Info - Reload Failed || §cプラグインのリロード中に何らかの問題が発生しました、Bukkit/SpigotサーバーかBungeeCordの再起動をお勧めします -Cmd Info - Update || §2利用可能なアップデート: §f${0} -Cmd Info - Version || §2バージョン: §f${0} -Cmd Notify - No WebUser || ウェブユーザーの情報がない可能性があります、「/plan register 」を使用して登録して下さい -Cmd Notify - WebUser register || 登録が完了しました: '${0}' 権限レベル: ${1} -Cmd Qinspect - Activity Index || §2活動指数: §f${0} | ${1} -Cmd Qinspect - Deaths || §2死亡回数: §f${0} -Cmd Qinspect - Geolocation || §2出身: §f${0} -Cmd Qinspect - Last Seen || §2最終ログイン日: §f${0} -Cmd Qinspect - Longest Session || §2最長ログイン時間: §f${0} -Cmd Qinspect - Mob Kills || §2キルカウント(モブ): §f${0} -Cmd Qinspect - Player Kills || §2キルカウント(プレイヤー): §f${0} -Cmd Qinspect - Playtime || §2プレイ時間: §f${0} -Cmd Qinspect - Registered || §2登録日: §f${0} -Cmd Qinspect - Times Kicked || §2キックされた時間: §f${0} -Cmd Setup - Allowed || §aセットアップモードが有効になりました -Cmd Setup - Bad Request || §e接続は成功しましたが、受信サーバーはBungeeCordのサーバーではありませんでした。代わりにBungeeCordのアドレスを使用して下さい -Cmd Setup - Disallowed || §cセットアップモードが無効になりました -Cmd Setup - Forbidden || §e接続は成功しましたが、BungeeCordの「Plan」のセットアップモードが無効になっています。「/planbungee setup」コマンドを使用して有効にして下さい -Cmd Setup - Gateway Error || §e接続は成功しましたが、BungeeCordの「Plan」のウェブサーバーに接続できませんでした。(ウェブサーバーが再起動中かもしれません)。「/plan m con 」と「/planbungee con」でデバック情報を表示できます -Cmd Setup - Generic Fail || §e以下の理由で接続に失敗しました: ${0} -Cmd Setup - Internal Error || §e接続は成功しました。 ${0}、受信サーバーのデバッグページでエラーログを確認できるようになりました -Cmd Setup - Success || §a接続は成功しました。「Plan」は数秒以内に再起動します。 -Cmd Setup - Unauthorized || §e接続は成功しましたが、このBukkit/Spigotサーバーを受信サーバーが拒否しました。Discordのサポートに連絡して下さい -Cmd Setup - Url mistake || §cウェブアドレスの入力を確かめて下さい(「http://」もしくは「https://」で始まります )。アドレスについてはBungeeCordの「Plan」を有効化した時のログを確認して下さい。 -Cmd Setup - WebServer not Enabled || §cこのBukkit/Spigotサーバーでウェブサーバーは有効になっていません。Bukkit/Spigotサーバー起動時にウェブサーバーが有効になっていることを確認して下さい! -Cmd SUCCESS - Feature disabled || §a次にプラグインがリロードされるまで一時的に「${0}」を無効にしました。 -Cmd SUCCESS - WebUser register || §a新規ユーザー「(${0})」の登録に成功しました!次のリンクでWebパネルを見ることができます。 -Cmd WARN - Database not open || §eデータベースは${0}です - 予想以上に時間がかかるかもしれません -Cmd Web - Permission Levels || >\§70: 全てのページにアクセスできます\§71:「/players」と全てのプレイヤーページにアクセスできます\§72: ウェブユーザーと同じユーザー名でプレイヤーページにアクセスできます\§73+:権限を保持していません -Command Help - /plan analyze || サーバーページのURLを表示します -Command Help - /plan dev || 開発モードコマンド -Command Help - /plan help || コマンドリストを表示します -Command Help - /plan info || 「Plan」のバージョンを表示します -Command Help - /plan inspect || 「プレイヤー」のURLを表示します -Command Help - /plan manage || 「Plan」のデータベースを管理します -Command Help - /plan manage backup || データベースをバックアップします -Command Help - /plan manage clear || データベースを消去します -Command Help - /plan manage con || BungeeCordとBukkit/Spigotサーバーとの接続をデバックします -Command Help - /plan manage disable || 機能を一時的に無効にします -Command Help - /plan manage export || 手動でデータのエクスポートを行います -Command Help - /plan manage hotswap || データベースを高速で変更します -Command Help - /plan manage import || 他の場所からデータをインポートします -Command Help - /plan manage move || データベース間でデータを移動します -Command Help - /plan manage raw || プレイヤーデータのJSONファイルを直接表示ます -Command Help - /plan manage remove || プレイヤーのデータを削除します -Command Help - /plan manage restore || 以前のバックアップから復元します -Command Help - /plan manage setup || BungeeCordとBukkit/Spigotサーバーとの接続をセットアップします -Command Help - /plan manage uninstalled || 指定されたサーバーをデータベースからアンインストールします -Command Help - /plan network || 「ネットワーク」のページのURLを表示します -Command Help - /plan players || 「プレイヤー」のページのURLを表示します -Command Help - /plan qinspect || プレイヤー情報をゲーム内で表示します -Command Help - /plan register || ウェブユーザーを登録します -Command Help - /plan reload || 「Plan」を再起動します -Command Help - /plan search || プレイヤー名を検索します -Command Help - /plan servers || データベース内のBukkit/Spigotサーバー一覧を表示します -Command Help - /plan web check || ウェブユーザーの点検を行います -Command Help - /plan web delete || ウェブユーザーの削除を行います -Command Help - /plan web level || 権限レベルに関する情報を表示します -Command Help - /plan web list || ウェブユーザーの一覧を表示します -Command Help - /plan webuser || ウェブユーザーを管理します -Command Help - /planbungee con || BungeeとBukkit/Spigotサーバーとの接続をデバックします -Command Help - /planbungee disable || プラグインを一時的に無効にします -Command Help - /planbungee setup || セットアップモードを切り替えます -Database - Apply Patch || 次のパッチを適用しています: ${0}.. -Database - Patches Applied || 全てのパッチは正常にデータベースに適用されました -Database - Patches Applied Already || 全てのパッチは既にデータベースへ適用されています -Database MySQL - Launch Options Error || 起動オプションに問題があります,デフォルトのオプションを使用して下さい (${0}) -Database Notify - Clean || ${0} のプレイヤーデータを削除しています -Database Notify - SQLite No WAL || SQLiteのWALモードはこのサーバのバージョンではサポートされていないため、デフォルトを使用します。これはサーバーのパフォーマンスに影響を与える可能性があります -Disable || プレイヤー分析が無効になりました -Disable - Processing || 未実行の重要な処理があります (${0}) -Disable - Processing Complete || 処理が完了しました -Disable - Unsaved Session Save || 未保存のセッションを保存しています・・ -Disable - WebServer || ウェブサーバーが無効になりました -Enable || プレイヤー分析が有効になりました -Enable - Database || ${0}のデータベースの接続が確立しました -Enable - Notify Address Confirmation || 次に表示されるアドレスがこのサーバーをである事を確認して下さい: ${0} -Enable - Notify Empty IP || server.propertiesの設定で、IPの項目が設定されておらずAlternative IPが使用されていません。そのため誤ったリンクが表示されます! -Enable - Notify Geolocations disabled || 位置情報サービスが有効ではありません。 (Data.Geolocations: false) -Enable - Notify Geolocations Internet Required || 「Plan」は初回起動時、「GeoLite2」の位置情報データベースをダウンロードするためインターネットアクセスが必要です -Enable - Notify Webserver disabled || ウェブサーバーの初期化に失敗しました (WebServer.DisableWebServer: true) -Enable - WebServer || ウェブサーバーは次のポートで実行されています: ${0} (${1}) -Enable FAIL - Database || ${0}のデータベースの接続に失敗しました: ${1} -Enable FAIL - Database Patch || データベースのパッチ適用に失敗しました、プラグインを無効にする必要があります。バグ報告をお願いします -Enable FAIL - GeoDB Write || ダウンロードした「GeoLite2」の位置情報データベースを保存中に何らかのエラーが発生しました -Enable FAIL - WebServer (Bungee) || ウェブサーバーの初期化に失敗しました! -Enable FAIL - Wrong Database Type || ${0}はサポートされていないデータベースです -Health - Active Playtime Comparison Decrease || よくログインしているプレイヤーのやることが少なくなっている可能性があります (直近2週間のアクティブ時間が${0}に対し、1ヶ月~2週間のアクティブ時間が${1}です) -Health - Active Playtime Comparison Increase || よくログインしているプレイヤーのやるべきことがある可能性があります (直近2週間のアクティブ時間が${0}に対し、1ヶ月~2週間のアクティブ時間が${1}です) -Health - Downtime || サーバーの合計停止時間(データが存在しない)が${0}です -Health - New Player Join Players, No || 新規プレイヤーが参加時、一緒にプレイするプレイヤーがいないかもしれません。(平均${0}人のプレイヤーがオンラインです) -Health - New Player Join Players, Yes || 新規プレイヤーが参加時、一緒にプレイするプレイヤーがいます。(平均${0}人のプレイヤーがオンラインです) -Health - New Player Stickiness || ${0}人の新規プレイヤーが行き詰詰まっています。(${1}/${2}) -Health - No Servers Inaccuracy || セッションデータを収集するBukkit/Spongeサーバーが接続されていません - 不正確なデータが表示されます -Health - Player Play on Network || 人のプレイヤーがネットワーク上でプレイしています: -Health - Player Register Server || 人のプレイヤーが1日あたり登録されています。以下サーバーごとの1日の登録数: -Health - Player Visit Server || 人のプレイヤーが1日あたりこのサーバーに接続しています。以下サーバーごとの1日の接続数: -Health - Regular Activity Change || しばしばログインしているプレイヤー数は -Health - Regular Activity Change Decrease || ${0}人減少しました (-${0}人) -Health - Regular Activity Change Increase || ${0}人増加しました (+${0}人) -Health - Regular Activity Change Zero || 変化していません (+${0}人) -Health - Regular Activity Remain || ${0}人のしばしばログインしているプレイヤーはよくログインするようになりました(${1}/${2}) -Health - Single Servers Inaccuracy || セッションデータを収集するためのBukkit/Spongeサーバーが1つしか存在しません -Health - TPS Above Low Threshold || 平均TPSの${0}が平均TPSの下限しきい値より高い値を示しています -Health - TPS Low Dips || 平均TPSの下限しきい値を下回った回数:${1}回(以前の値:${0}回) -HTML - ACTIVITY_INDEX || 活動指数 -HTML - ALL || 全て -HTML - ALL_TIME_PEAK || 全体のピークタイム -HTML - AVERAGE_PING || 平均応答時間 -HTML - AVG || 平均 -HTML - BANNED || BAN履歴 -HTML - BEST_PING || 最低応答時間 -HTML - CALENDAR || カレンダー -HTML - CALENDAR_TEXT || カレンダー -HTML - CHUNKS || チャンク -HTML - COMMAND || コマンド -HTML - COMMNAND_USAGE || コマンド使用履歴 -HTML - CONNECTION_INFORMATION || 接続情報 -HTML - COUNTRY || 国/地域 -HTML - CURRENT_PLAYERBASE || ログインプレイヤー -HTML - DATABASE_NOT_OPEN || データベースを開くことができませんでした。「/plan info」コマンドを実行して状況を確認して下さい -HTML - DEATHS || 死亡回数 -HTML - DISK_SPACE || ドライブの容量 -HTML - ENTITIES || エンティティ数 -HTML - ERROR || エラーが発生したため認証に失敗しました -HTML - FAVORITE_SERVER || お気に入りのサーバー -HTML - FREE_DISK_SPACE || ドライブの空き容量 -HTML - GEOLOCATION || 地域 -HTML - GEOLOCATION_TEXT || 地域 -HTML - HEALTH_ESTIMATE || ネットワークの健康状態 -HTML - INDEX_ACTIVE || よくログインしている -HTML - INDEX_INACTIVE || 休止中 -HTML - INDEX_IRREGULAR || たまにログインしている -HTML - INDEX_REGULAR || しばしばログインしている -HTML - INDEX_VERY_ACTIVE || とてもログインしている -HTML - IP_ADDRESS || IPアドレス -HTML - KILLED || 殺した人 -HTML - KILLED_BY || 殺された人 -HTML - LAST_24_HOURS || 直近24時間以内 -HTML - LAST_30_DAYS || 直近30日以内 -HTML - LAST_30_DAYS_TEXT || 直近30日以内の出来事 -HTML - LAST_7_DAYS || 一週間以内 -HTML - LAST_CONNECTED || 直近の接続 -HTML - LAST_PEAK || 直近のピークタイム -HTML - LAST_SEEN || 直近のオンライン -HTML - LAST_SEEN_TEXT || 直近のオンライン -HTML - LOADED_CHUNKS || ロードされたチャンク数 -HTML - LOADED_ENTITIES || ロードされたエンティ数 -HTML - LOCAL_MACHINE || ローカルマシン -HTML - LONGEST || 最長 -HTML - LOW_TPS_SPIKES || 最低TPS値 -HTML - MOB_CAUSED_DEATHS || Mobによって殺された回数 -HTML - MOB_KDR || Mobに対してのKDR -HTML - MOB_KILLS || Mobを殺した回数 -HTML - MOST_RECENT_SESSIONS || 最近のログイン -HTML - NAME || 名前 -HTML - NAV_COMMAND_USAGE || コマンド使用履歴 -HTML - NAV_GEOLOCATIONS || 地域 -HTML - NAV_INFORMATION || 概要 -HTML - NAV_NETWORK_PLAYERS || ネットワーク内のプレイヤー数 -HTML - NAV_ONLINE_ACTIVITY || 活動履歴 -HTML - NAV_OVERVIEW || 概要 -HTML - NAV_PERFORMANCE || パフォーマンス -HTML - NAV_PLAYERS || プレイヤー -HTML - NAV_PLUGINS || プラグイン -HTML - NAV_SESSIONS || 接続履歴 -HTML - NAV_SEVER_HEALTH || サーバーの健康状態 -HTML - NETWORK || ネットワーク -HTML - NETWORK_INFORMATION || ネットワーク内の情報 -HTML - NEW || 新規 -HTML - NEW_CALENDAR || New: -HTML - NEW_PLAYERS_TEXT || 新規プレイヤー -HTML - NEW_RETENTION || 新規プレイヤーの継続率 -HTML - NEW_TEXT || 新規 -HTML - NICKNAME || ニックネーム -HTML - NO_KILLS || プレイヤーキルなし -HTML - NO_PLAYER_CAUSED_DEATHS || プレイヤーによるキルなし -HTML - OFFLINE || オフライン -HTML - ONLINE || オンライン -HTML - ONLINE_ACTIVITY || 活動指数 -HTML - OPERATOR || 管理者 -HTML - OVERVIEW || 概要 -HTML - PER_DAY || /日 -HTML - PLAYER_CAUSED_DEATHS || プレイヤーによるキル -HTML - PLAYER_KILLS || プレイヤーキル -HTML - PLAYER_LIST || プレイヤー一覧 -HTML - PLAYERBASE_DEVELOPMENT || 登録されているプレイヤーの推移 -HTML - PLAYERS || プレイヤー -HTML - PLAYERS_ONLINE || オンラインのプレイヤー -HTML - PLAYERS_ONLINE_TEXT || オンラインのプレイヤー -HTML - PLAYERS_TEXT || プレイヤー -HTML - PLAYTIME || プレイ時間 -HTML - PLEASE_WAIT || 少々お待ち下さい・・・ -HTML - PREDICETED_RETENTION || 推定される継続率 -HTML - PUNCH_CARD || パンチボード -HTML - PUNCHCARD || パンチボード -HTML - RECENT_LOGINS || 最近のログイン -HTML - REGISTERED || 登録日 -HTML - REGISTERED_TEXT || 登録 -HTML - REGULAR || よくいる -HTML - SEEN_NICKNAMES || ニックネーム一覧 -HTML - SERVER || サーバー -HTML - SERVER_ANALYSIS || サーバーの分析結果 -HTML - SERVER_HEALTH_ESTIMATE || サーバーの健康状態 -HTML - SERVER_INFORMATION || サーバーの情報 -HTML - SERVER_PREFERENCE || サーバー毎のプレイ時間 -HTML - SERVERS || 接続されているサーバー -HTML - SESSION || オンライン -HTML - SESSION_ENDED || ログアウト時刻 -HTML - SESSION_LENGTH || 最長オンライン -HTML - SESSION_MEDIAN || 平均オンライン -HTML - SESSIONS || 接続履歴 -HTML - TIME || 時刻 -HTML - TIMES_KICKED || キック回数 -HTML - TIMES_USED || 使用回数 -HTML - TOTAL_ACTIVE_TEXT || 累計活動時間 -HTML - TOTAL_AFK || 累計離席時間 -HTML - TOTAL_PLAYERS || 全プレイヤー数 -HTML - TOTAL_PLAYTIME || 全プレイ時間 -HTML - UNIQUE || ユニーク -HTML - UNIQUE_CALENDAR || ユニーク: -HTML - UNIQUE_PLAYERS || ユニークプレイヤー -HTML - UNIQUE_PLAYERS_TEXT || ユニークプレイヤー -HTML - UNIQUE_TEXT || ユニーク -HTML - USAGE || 使用履歴 -HTML - USED_COMMANDS || 使用したコマンド -HTML - USER_AND_PASS_NOT_SPECIFIED || ユーザーとパスワードが入力されてません -HTML - USER_DOES_NOT_EXIST || 入力されたユーザーは存在しません -HTML - USER_INFORMATION || ユーザー情報 -HTML - USER_PASS_MISMATCH || 入力されたユーザー名とパスワードが間違っています -HTML - WITH ||
    死亡原因 -HTML - WORLD || ワールド -HTML - WORLD_LOAD || ワールドロード数 -HTML - WORLD_PLAYTIME || ワールドごとのプレイ時間 -HTML - WORST_PING || 最高応答時間 -HTML ERRORS - ACCESS_DENIED_403 || アクセスが拒否されました -HTML ERRORS - ANALYSIS_REFRESH || 分析結果に基づいてデータを更新中です・・・ -HTML ERRORS - ANALYSIS_REFRESH_LONG || サーバーを分析中です・・・・
    数秒後にページが更新されない場合、ページを更新して下さい -HTML ERRORS - AUTH_FAIL_TIPS_401 || - 登録したユーザーを「/plan register 」で確認できます。
    - 入力したユーザー名とパスワードが正しいことを確認して下さい
    - ユーザー名とパスワードは大文字と小文字が区別されています

    パスワードを忘れた場合は、管理者に古いユーザーを削除して新しくユーザーを再登録するよう依頼して下さい -HTML ERRORS - AUTHENTICATION_FAILED_401 || 認証に失敗しました -HTML ERRORS - FORBIDDEN_403 || 閲覧禁止 -HTML ERRORS - INSPECT_REFRESH || プレーヤページのリクエスト処理が実行中です・・ -HTML ERRORS - INSPECT_REFRESH_LONG || ページは自動的に更新されます・・ -HTML ERRORS - NO_SERVERS_404 || リクエストを処理するサーバーがオンラインではありません -HTML ERRORS - NOT_FOUND_404 || ページが見つかりませんでした -HTML ERRORS - NOT_PLAYED_404 || プレイヤーはこのサーバーでプレイしていません -HTML ERRORS - PAGE_NOT_FOUND_404 || ページは存在しません -HTML ERRORS - PLUGIN_TAB_REFRESH || 計算中です・・・ -HTML ERRORS - UNAUTHORIZED_401 || 未認証状態です -HTML ERRORS - UNKNOWN_PAGE_404 || リンクが間違っています、コマンドを使用してURLを確認して下さい。 URL例:

    /player/PlayerName
    /server/ServerName

    -HTML ERRORS - UUID_404 || データベース内にプレヤーのUUIDが存在しません -In Depth Help - /plan ? || > §2主要なコマンド\ 補助コマンドの表示とヘルプ\ §2/plan §f補助コマンドの一覧を表示します\ §2/plan ? §f詳細なヘルプを表示します -In Depth Help - /plan analyze ? || > §2分析コマンド\ サーバーページを更新して、ウェブページへのリンクを表示します -In Depth Help - /plan inspect ? || > §2検査コマンド\ プレイヤーページを更新して、ウェブページへのリンクを表示します -In Depth Help - /plan manage ? || > §2管理コマンド\ MySQLまたはSQLiteの「Plan」のデータベースを管理します\ §2/plan m §f補助コマンドの一覧を表示します\ §2/plan m ? §f詳細なヘルプを表示します -In Depth Help - /plan manage backup ? || > §2バックアップコマンド\ 現在アクティブになっているデータベースの内容を含むSQLiteの新しいデータベースを「Plan」のプラグインフォルダ内に作成します(拡張子は「.db」です) -In Depth Help - /plan manage clear ? || > §2クリア補助コマンド\ アクティブになっているデータベースの全てを削除します。使用には注意が必要です -In Depth Help - /plan manage con ? || > §2接続デバッグ補助コマンド\ ネットワーク内の接続をデバッグするために使用します\ データベース内の各サーバーにリクエストを送信します。 -In Depth Help - /plan manage disable ? || > §2無効補助コマンド\ 次回のリロードまでプラグインの一部を無効にすることができます\ 使用できる引数:\ §2キックカウント §fシャットダウンマクロで「/kickball」が使用されている場合の無効化されたキックカウント。 -In Depth Help - /plan manage export ? || > §2エクスポート補助コマンド\ 分析結果を特定のフォルダーへのエクスポートを有効化します\ 使用できる引数:\ §2list §fList possible arguments.\ §2players §fExport /players, /player pages + /player/raw json depending on config values.\ §2server_json §fExport /server/raw JSON if enabled in config. -In Depth Help - /plan manage import ? || > §2インポート補助コマンド\ 別のソースからデータをインポートします\ 使用できる引数:\ §2オフライン §fBukkitのプレイヤーデータ、登録日と名前のみを登録できます -In Depth Help - /plan manage move ? || > §2移動補助コマンド\ SQLiteからMySQLもしくは他の形式にデータを移行させます\ ターゲットとなるデータベースは移行前に空である必要があります -In Depth Help - /plan manage raw ? || > §2生のデータ補助コマンド\ 生のJSONデータページへのリンクを表示します\ 「Plan」の内部ウェブサーバーが有効になっていない場合は利用できません -In Depth Help - /plan manage remove ? || > §2削除補助コマンド\ プレイヤーのデータをアクティブになっているデータベースから削除します -In Depth Help - /plan manage restore ? || > §2復元補助コマンド\ データベースを以前にバックアップしたSQLiteデータベース(拡張子が「.db」のファイル)に復元します\ 他のサーバーの拡張子が「.db」のデータベースをMySQLに復元することもできます\ ターゲットとなるデータベースは移行前に空である必要があります -In Depth Help - /plan manage setup ? || > §2セットアップ補助コマンド\ 「ネットワーク」のページを機能させるために、BungeeCordとこのBukkit/Spigotサーバーの間の接続を設定します.\ BungeeCordのアドレスはBungeeCordで「Plan」が有効化された時のログで見つけることができます。 -In Depth Help - /plan manage uninstalled ? || > §2サーバーアンインストール補助コマンド\ 指定されたサーバーをデータベースからアンインストールします\ コマンドが実行されているサーバーをアンインストールするサーバーとしてマークすることはできません\ サーバーの接続システムに影響します -In Depth Help - /plan network ? || > §2ネットワークコマンド\ 「ネットワーク」のページのURLを表示します\ BungeeCordのネットワーク上にない場合は、このページにサーバーページが表示されます。 -In Depth Help - /plan players ? || > §2プレイヤーコマンド\ 「プレイヤー」のページのURLを表示します -In Depth Help - /plan qinspect ? || > §2クイック検査コマンド\ ゲーム内にいるプレイヤーに関する情報を表示します。 -In Depth Help - /plan reload ? || > §2リロードコマンド\ 「onDisable」と「onEnable」を使ってプラグインを再起動します。\ §bその状態で「Swapping jar」は対応していません -In Depth Help - /plan search ? || > §2検索コマンド\ 与えられた引数に一致するプレイヤー名のリストを取得します\§7 例: /plan search 123 - 名前に「123」を含むすべてのユーザーを検索します -In Depth Help - /plan servers ? || > §2サーバーコマンド\ データベース内の「Plan」サーバーのリストを表示します\ BungeeCordネットワークのデータベースにサーバーを登録する際の問題をデバッグするために使用できます -In Depth Help - /plan web ? || < §2ウェブユーザー管理コマンド\ §2/plan web §f補助コマンドの一覧を表示します\ §2/plan web ? §f詳細なヘルプを表示します -In Depth Help - /plan web register ? || > §2登録コマンド\ 新しいウェブユーザーを登録します。\ プレイヤーが他のプレイヤーをユーザー登録するには「plan.webmanage」権限が必要です\ パスワードはPBKDF2(64,000回のSHA1の繰り返し)でソルト(暗号論)をかけてハッシュされます。 -In Depth Help - /planbungee disable ? || > §2無効化コマンド\ BungeeCordの「Plan」で「onDisable」を実行します\ あとで「/planbungee reload」を使ってプラグインを有効にすることができます\ §bその状態で「Swapping jar」は対応していません -In Depth Help - /planbungee setup ? || > §2セットアップ切り替えコマンド\ BungeeCordでセットアップモードを切り替えます\ 許可されていない他のサーバーがMySQLを詮索するのを防ぎます。 -Manage - Confirm Overwrite || ${0}のデータは上書きされます! -Manage - Confirm Removal || ${0}のデータは削除されます! -Manage - Fail || > §c何かがうまくいきませんでした: ${0} -Manage - Fail File not found || > §c「${0}」にファイルが見つかりませんでした -Manage - Fail Incorrect Database || > §c「${0}」はサポートされていないデータベースです -Manage - Fail No Exporter || §eエクスポーター 「${0}」が存在しません -Manage - Fail No Importer || §eインポーター 「${0}」が存在しません -Manage - Fail No Server || 指定されたパラメーターを持つサーバーが存在しませんでした -Manage - Fail Same Database || > §c同じデータベースを操作することはできません! -Manage - Fail Same server || このサーバーをアンインストールするサーバーとして指定することはできません(あなたがこのサーバーにログインしているため) -Manage - Fail, Confirmation || > §c実行を確認するために引数「-a」を追加します: ${0} -Manage - Fail, Connection Exception || §e失敗した理由: -Manage - Fail, No Servers || §cデータベース内にサーバーが存在しませんでした -Manage - Fail, Old version || §e失敗した理由:受信サーバーで実行されている「Plan」のバージョンが古いです -Manage - Fail, Unauthorized || §e失敗した理由:権限制限があります。サーバーが別のデータベースを使用している可能性があります -Manage - Fail, Unexpected Exception || §e不明な例外: ${0} -Manage - List Importers || インポーター: -Manage - Notify External Url || §e非ローカルアドレスです、接続先のポートが開放されていることを確認して下さい -Manage - Remind HotSwap || §e新しいデータベースに交換することを忘れないで下さい(/plan m hotswap ${0})。そして、プラグインをリロードして下さい -Manage - Start || > §2データを処理中です.. -Manage - Success || > §a成功しました! -Negative || ない -Positive || ある -Today || '今日' -Yesterday || '昨日' -Unknown || 不明 -Version - DEV || このバージョンは開発版です -Version - Latest || 最新版の「Plan」を使用しています -Version - New || 新しいバージョンの${0}が次のURLで入手可能です ${1} -Version - New (old) || 新しいバージョンは次のURLで入手可能です${0} -Version FAIL - Read info (old) || 新しいバージョンのチェックに失敗しました -Version FAIL - Read versions.txt || Github/versions.txtに存在するバージョン情報のロードに失敗しました -Web User Listing || §2${0} §7: §f${1} -WebServer - Notify HTTP || Webサーバー: 証明書が存在ません -> HTTPサーバーを使用します -WebServer - Notify HTTP User Auth || Webサーバー: ユーザー認証が無効になりました! (HTTP経由だと安全ではないためです) -WebServer - Notify no Cert file || Webサーバー: 以下のパスに保存された認証キーファイルが存在しません: ${0} -WebServer FAIL - Port Bind || Webサーバーの初期化が正常に終了しませんでした。ポート番号(${0})は使用されていませんか? -WebServer FAIL - SSL Context || Webサーバー: SSLコンテキストの初期化に失敗しました。 -WebServer FAIL - Store Load || Webサーバー: SSL証明書のロードに失敗しました diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_PT-BR.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_PT-BR.txt deleted file mode 100644 index 449b072c5..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_PT-BR.txt +++ /dev/null @@ -1,336 +0,0 @@ -Cmd - Click Me || Clique aqui -Cmd - Link || §2Link: §f -Cmd Disable - Disabled || §aO sistema do Plan agora está desativado. Você pode usar /planbungee reload para reiniciar o plugin. -Cmd FAIL - Invalid Username || §cEsse usuário não tem uma UUID. -Cmd FAIL - No Feature || §eDefina um recurso para desativar! (atualmente suporta ${0}) -Cmd FAIL - No Permission || §cVocê não tem a permissão necessária. -Cmd FAIL - Require only one Argument || §cÚnico argumento necessário ${1} -Cmd FAIL - Requires Arguments || §cArgumentos necessários (${0}) ${1} -Cmd FAIL - Unknown Username || §cEsse usuário não foi encontrado nesse servidor -Cmd FAIL - WebUser does not exists || §cEsse usuário não existe! -Cmd FAIL - WebUser exists || §cEsse usuário já existe! -Cmd Header - Analysis || > §2Resultados da Análise -Cmd Header - Info || > §2Análise do Jogador -Cmd Header - Inspect || > §2Jogador: §f${0} -Cmd Header - Network || > §2Página da Network -Cmd Header - Players || > §2Jogadores -Cmd Header - Search || > §2${0} Resultados para §f${1}§2: -Cmd Header - Servers || > §2Servidores -Cmd Header - Web Users || > §2${0} Usuários da Web -Cmd Info - Bungee Connection || §2Conectados ao Bungee: §f${0} -Cmd Info - Database || §2Banco de dados ativo: §f${0} -Cmd Info - Reload Complete || §aReload Realizado -Cmd Info - Reload Failed || §cAlguma coisa ocorreu ao recarregar o plugin, um restart é recomendável. -Cmd Info - Update || §2Atualização Disponível: §f${0} -Cmd Info - Version || §2Versão: §f${0} -Cmd Notify - No WebUser || Você não tem um usuário para web, utilize /plan register -Cmd Notify - WebUser register || Novo usuário registrado: '${0}' Nível de permissão: ${1} -Cmd Qinspect - Activity Index || §2Índice de Atividade: §f${0} | ${1} -Cmd Qinspect - Deaths || §2Mortes: §f${0} -Cmd Qinspect - Geolocation || §2Conectado de: §f${0} -Cmd Qinspect - Last Seen || §2Última vez visto: §f${0} -Cmd Qinspect - Longest Session || §2Sessão mais longa: §f${0} -Cmd Qinspect - Mob Kills || §2Assassinato de Mobs: §f${0} -Cmd Qinspect - Player Kills || §2Assassinato de Jogadores: §f${0} -Cmd Qinspect - Playtime || §2Tempo de Jogo: §f${0} -Cmd Qinspect - Registered || §2Registered: §f${0} -Cmd Qinspect - Times Kicked || §2Vezes Kickado: §f${0} -Cmd Setup - Allowed || §aA configuração agora é permitida -Cmd Setup - Bad Request || §eA conexão foi bem sucedida, mas o servidor de recebimento não era um servidor Bungee. Utilize o endereço de IP do Bungee. -Cmd Setup - Disallowed || §cA configuração de instalação agora foi bloqueada -Cmd Setup - Forbidden || §eA conexão foi bem sucedida, mas o Bungee desativou o modo de configuração - utilize '/planbungee setup' para ativá-lo. -Cmd Setup - Gateway Error || §eA conexão foi bem sucedida, mas o Bungee não conseguiu se conectar a esse servidor (O servidor web atual foi reiniciado?). Utilize /plan m con & /planbungee con para depurar. -Cmd Setup - Generic Fail || §eConexão falhou: ${0} -Cmd Setup - Internal Error || §eConexão bem sucedida. ${0}, verifique se possível o ErrorLog que está recebendo nos servidores na página de depuração. -Cmd Setup - Success || §aConexão bem sucedida, o Plan pode reiniciar em alguns segundos.. -Cmd Setup - Unauthorized || §eA conexão foi bem sucedida, mas o servidor de recebimento não autorizou esse servidor. Entre em contato por Discord para receber suporte. -Cmd Setup - Url mistake || §cVerifique se você está usando o endereço completo (que começa com http:// ou https://) - verifique no console do Bungee se está recebendo o endereço corretamente. -Cmd Setup - WebServer not Enabled || §cO servidor web não está habilitado nesse servidor! Certifique-se que essa opção esteja habilitada no arquivo de configuração do Plan! -Cmd SUCCESS - Feature disabled || §aDesativado '${0}' temporariamente até o próximo reload do plugin. -Cmd SUCCESS - WebUser register || §aFoi adicionado um novo usuário (${0})! Você pode ver o painel da web no link a seguir. -Cmd Update - Cancel Success || §aCancelar operação realizada. -Cmd Update - Cancelled || §cAtualização cancelada. -Cmd Update - Change log || Change Log v${0}: -Cmd Update - Fail Cacnel || §cA atualização falhou em um dos servidores, cancelando a atualização em todos os servidores.. -Cmd Update - Fail Force Notify || §e${0} falhou ao atualizar, utilize -force, para continuar com a atualização. -Cmd Update - Fail Not Online || §cNem todos os servidores estavam online ou acessíveis, você ainda pode atualizar os servidores disponíveis usando /plan update -u -force -Cmd Update - Notify Cancel || §aVocê pode cancelar a atualização dos servidores que não foram reiniciados ainda com /plan update cancel. -Cmd Update - Online Check || Verificando se todos os servidores estão online.. -Cmd Update - Scheduled || §a${0} agendado para atualização. -Cmd Update - Url mismatch || §cO url de download não começou com ${0} e pode ser que não seja confiável. Você pode baixar essa versão manualmente aqui (Download Direto): -Cmd Web - Permission Levels || >\§70: Acesse todas as páginas\§71: Acesse '/players' e todas as páginas de jogadores\§72: Acesse a página de jogado com o mesmo usuário do login\§73+: Sem permissões -Command Help - /plan analyze || Visualizar a página do servidor -Command Help - /plan dev || Comando do modo de desenvolvimento -Command Help - /plan help || Mostrar a lista de comandos -Command Help - /plan info || Verificar a versão do Plan -Command Help - /plan inspect || Visualizar a página do jogador -Command Help - /plan manage || Gerenciar o banco de dados do Plan -Command Help - /plan manage backup || Fazer backup do banco de dados -Command Help - /plan manage clear || Limpar o banco de dados -Command Help - /plan manage con || Depurar as conexões Servidor-Bungee -Command Help - /plan manage disable || Desativar um recurso temporariamente -Command Help - /plan manage hotswap || Alterar o banco de dados rapidamente -Command Help - /plan manage import || Importar dados de outro lugar -Command Help - /plan manage move || Mover dados entre banco de dados -Command Help - /plan manage remove || Remvoer dados de jogadores -Command Help - /plan manage restore || Restaurar último backup realizado -Command Help - /plan manage setup || Configurar uma conexão Servidor-Bungee -Command Help - /plan network || Visualizar a página da Network -Command Help - /plan players || Visualizar a página de Jogadores -Command Help - /plan qinspect || Visualziar informações do Jogador in-game -Command Help - /plan register || Registrar um usuário web -Command Help - /plan reload || Reiniciar Plan -Command Help - /plan search || Buscar por um nome de jogador -Command Help - /plan servers || Listar servidores do banco de dados -Command Help - /plan update || Pegar o link de Changelog ou atualização do plugin -Command Help - /plan web check || Inspecionar um usuário web -Command Help - /plan web delete || Excluir um usuário web -Command Help - /plan web level || Informações sobre os níveis de permissão -Command Help - /plan web list || Listar usuários web -Command Help - /plan webuser || Gerenciar usuários web -Command Help - /planbungee con || Depurar conexões Bungee-Servidor -Command Help - /planbungee disable || Desativar o plugin temporariamente -Command Help - /planbungee setup || Alternar o modo de configuração -Database - Apply Patch || Aplicando o Patch: ${0}.. -Database - Patches Applied || Todos os patchs de bancos de dados foram aplicados. -Database - Patches Applied Already || Todos os patchs de bancos de dados já foram aplicados. -Database MySQL - Launch Options Error || Opções de execução estavam com problemas, usando configuração padrão (${0}) -Database Notify - Clean || Removido dados de ${0} jogadores. -Database Notify - SQLite No WAL || O modo WAL do SQLite não é suportado nessa versão do servidor, então será usado a configuração padrão. Isso pode ou não afetar o desempenho. -Disable || Análise de Jogadores Desativado. -Disable - Processing || Processando tarefas críticas não processadas anteriormente. (${0}) -Disable - Processing Complete || Processamento completo. -Disable - WebServer || O servidor web foi desativado. -Enable || Análise de Jogadores Ativado. -Enable - Database || ${0}-conexão com o banco de dados estabilizada. -Enable - Notify Address Confirmation || Tenha certeza que esse endereço está apontando para ESSE servidor: ${0} -Enable - Notify Empty IP || O IP no server.properties está vazio & o IP alternativo não está sendo usado. Os dados informados estão incorretos! -Enable - Notify Geolocations disabled || A coleta de geolocalização está desativada. (Data.Geolocations: false) -Enable - Notify Geolocations Internet Required || O Plan requer acesso à internet na primeira execução para baixar o banco de dados de geolocalização do GeoLite2. -Enable - Notify Webserver disabled || O servidor web não foi inicializado. (WebServer.DisableWebServer: true) -Enable - WebServer || O servidor web está rodando na PORTA ${0} (${1}) -Enable FAIL - Database || ${0}-Falha na Conexão do Banco de Dados: ${1} -Enable FAIL - Database Patch || O patch do banco de dados falhou, o plugin teve que ser desativado. Reporte esse problema no GitHub ou Discord para suporte. -Enable FAIL - GeoDB Write || Algo deu errado ao salvar o banco de dados de geolocalização do GeoLite2 -Enable FAIL - WebServer (Bungee) || O servidor web não pode ser inicializado! -Enable FAIL - Wrong Database Type || ${0} não é um banco de dados suportado -HTML - ACTIVITY_INDEX || Índice de Atividade -HTML - ALL || TODOS -HTML - ALL_TIME_PEAK || Pico Máximo -HTML - AVERAGE_PING || Ping Médio -HTML - AVG || AVG -HTML - BANNED || Banido -HTML - BEST_PING || Melhor Ping -HTML - CALENDAR || CALENDÁRIO -HTML - CALENDAR_TEXT || Calendário -HTML - CHUNKS || Chunks -HTML - COMMAND || Comandos -HTML - COMMNAND_USAGE || Comandos Utilizados -HTML - CONNECTION_INFORMATION || Informações de Conexão -HTML - COUNTRY || País -HTML - CURRENT_PLAYERBASE || Base de Jogadores Atual -HTML - DEATHS || Mortes -HTML - ENTITIES || Entidades -HTML - ERROR || Falha ao autenticar -HTML - FAVORITE_SERVER || Servidor Favorito -HTML - GEOLOCATION || Geolocalização -HTML - GEOLOCATION_TEXT || Geolocalização -HTML - HEALTH_ESTIMATE || Vida Estimada -HTML - INDEX_ACTIVE || Ativo -HTML - INDEX_INACTIVE || Inativo -HTML - INDEX_IRREGULAR || Irregular -HTML - INDEX_REGULAR || Regular -HTML - INDEX_VERY_ACTIVE || Muito Ativo -HTML - IP_ADDRESS || Endereço IP -HTML - KILLED || Assassinou -HTML - KILLED_BY || Morto por -HTML - LAST_24_HOURS || ÚLTIMAS 24 HORAS -HTML - LAST_30_DAYS || ÚLTIMOS 30 DIAS -HTML - LAST_30_DAYS_TEXT || Últimos 30 Dias -HTML - LAST_7_DAYS || ÚLTIMOS 7 DIAS -HTML - LAST_CONNECTED || Última Conexão -HTML - LAST_PEAK || Último Pico -HTML - LAST_SEEN || ÚLTIMA VEZ VISTO -HTML - LAST_SEEN_TEXT || Última Vez Visto -HTML - LOADED_CHUNKS || Chunks Carregados -HTML - LOADED_ENTITIES || Entidades Carregadas -HTML - LOCAL_MACHINE || Máquina Local -HTML - LONGEST || Maior Tempo -HTML - LOW_TPS_SPIKES || Picos Baixos do TPS -HTML - MOB_CAUSED_DEATHS || Mortes causadas por Mobs -HTML - MOB_KDR || KDR por Mob -HTML - MOB_KILLS || Assassinato de Mobs -HTML - MOST_RECENT_SESSIONS || Sessões Mais Recentes -HTML - NAME || Nome -HTML - NAV_COMMAND_USAGE || Comandos Utilizados -HTML - NAV_GEOLOCATIONS || Geolocalizações -HTML - NAV_INFORMATION || Informações -HTML - NAV_NETWORK_PLAYERS || Jogadores da Network -HTML - NAV_ONLINE_ACTIVITY || Atividade Online -HTML - NAV_OVERVIEW || Visão Global -HTML - NAV_PERFORMANCE || Desempenho -HTML - NAV_PLAYERS || Jogadores -HTML - NAV_PLUGINS || Plugins -HTML - NAV_SESSIONS || Sessões -HTML - NAV_SEVER_HEALTH || Vida do Servidor -HTML - NETWORK || Network -HTML - NETWORK_INFORMATION || INFORMAÇÕES DA NETWORK -HTML - NEW || NOVO -HTML - NEW_CALENDAR || Novo: -HTML - NEW_PLAYERS_TEXT || Novos Jogadores -HTML - NEW_RETENTION || Retenção de Novos Jogadores -HTML - NEW_TEXT || Novo -HTML - NICKNAME || Nick -HTML - NO_KILLS || Sem Kills -HTML - NO_PLAYER_CAUSED_DEATHS || Nenhum jogador lhe matou -HTML - OFFLINE || Offline -HTML - ONLINE || Online -HTML - ONLINE_ACTIVITY || ATIVIDADE ONLINE -HTML - OPERATOR || Operador -HTML - OVERVIEW || VISÃO GLOBAL -HTML - PER_DAY || / Dia -HTML - PLAYER_CAUSED_DEATHS || Mortes causadas por Jogadores -HTML - PLAYER_KILLS || Assassinato -HTML - PLAYER_LIST || Lista de Jogadores -HTML - PLAYERBASE_DEVELOPMENT || Desenvolvimento da base de Jogadores -HTML - PLAYERS || JOGADORES -HTML - PLAYERS_ONLINE || JOGADORES ONLINE -HTML - PLAYERS_ONLINE_TEXT || Jogadores Online -HTML - PLAYERS_TEXT || Jogadores -HTML - PLAYTIME || Tempo de Jogo -HTML - PLEASE_WAIT || Por favor, aguarde... -HTML - PREDICETED_RETENTION || Retenção Prevista -HTML - PUNCH_CARD || Cartão Perfurado -HTML - PUNCHCARD || CARTÃO PERFURADO -HTML - RECENT_LOGINS || LOGINS RECENTES -HTML - REGISTERED || REGISTRADOS -HTML - REGISTERED_TEXT || Registrados -HTML - REGULAR || REGULARES -HTML - SEEN_NICKNAMES || Nicks Vistos -HTML - SERVER || Servidor -HTML - SERVER_ANALYSIS || Análise do Servidor -HTML - SERVER_HEALTH_ESTIMATE || Estimativa de Integridade do Servidor -HTML - SERVER_INFORMATION || INFORMAÇÕES DO SERVIDOR -HTML - SERVER_PREFERENCE || Preferência de servidor -HTML - SERVERS || Servidores -HTML - SESSION || Sessão -HTML - SESSION_ENDED || Sessões Finalizadas -HTML - SESSION_LENGTH || Tempo de Sessões -HTML - SESSION_MEDIAN || Média de Sessões -HTML - SESSIONS || Sessões -HTML - TIME || Tempo -HTML - TIMES_KICKED || Vezes Kickado -HTML - TIMES_USED || Vezes Usados -HTML - TOTAL_ACTIVE_TEXT || Tempo Total Ativo -HTML - TOTAL_AFK || Tempo Total AFK -HTML - TOTAL_PLAYERS || Total de Jogadores -HTML - TOTAL_PLAYTIME || Tempo Total Jogado -HTML - UNIQUE || ÚNICOS -HTML - UNIQUE_CALENDAR || Únicos: -HTML - UNIQUE_PLAYERS || JOGADORES ÚNICOS -HTML - UNIQUE_PLAYERS_TEXT || Jogadores Únicos -HTML - UNIQUE_TEXT || Único -HTML - USAGE || Uso -HTML - USED_COMMANDS || Comandos Usados -HTML - USER_AND_PASS_NOT_SPECIFIED || Usuário e Senha não específicado -HTML - USER_DOES_NOT_EXIST || Usuário não existe -HTML - USER_INFORMATION || INFORMAÇÕES DO USUÁRIO -HTML - USER_PASS_MISMATCH || Usuário e Senha não coincidem -HTML - WITH ||
    Com -HTML - WORLD || Mundo -HTML - WORLD_LOAD || MUNDOS CARREGADOS -HTML - WORLD_PLAYTIME || Tempo de Jogo por Mundo -HTML - WORST_PING || Pior Ping -HTML ERRORS - ACCESS_DENIED_403 || Acesso Negado -HTML ERRORS - ANALYSIS_REFRESH || A análise está sendo atualizada.. -HTML ERRORS - ANALYSIS_REFRESH_LONG || A análise está sendo executada, atualize a página após alguns segundos.. -HTML ERRORS - AUTH_FAIL_TIPS_401 || - Certifique-se de ter registrado um usuário com /plan register
    - Verifique se o nome de usuário e a senha estão corretos
    - O nome de usuário e senha fazem distinção entre maiúsculas e minúsculas, verifique se escreveu corretamente

    Se você esqueceu sua senha, peça para um staff que exclua seu antigo usuário e registre um novo. -HTML ERRORS - AUTHENTICATION_FAILED_401 || Falha na Autenticação. -HTML ERRORS - FORBIDDEN_403 || Proibido -HTML ERRORS - NO_SERVERS_404 || Nenhum servidor online para executar a solicitação. -HTML ERRORS - NOT_FOUND_404 || Não Encontrado -HTML ERRORS - NOT_PLAYED_404 || Esse jogador não jogou nesse servidor. -HTML ERRORS - PAGE_NOT_FOUND_404 || Página não existe. -HTML ERRORS - UNAUTHORIZED_401 || Acesso não autorizado -HTML ERRORS - UNKNOWN_PAGE_404 || Certifique-se de que você está acessando um link fornecido por comando, exemplos:

    /player/NomeDoJogador
    /server/NomeDoServidor

    -HTML ERRORS - UUID_404 || UUID de jogador não encontrado no banco de dados. -In Depth Help - /plan ? || > §2Comando Principal\ Acesso aos subcomandos e ajuda\ §2/plan §fLista os subcomandos\ §2/plan ? §fConsulta mais detalhada -In Depth Help - /plan analyze ? || > §2Comando Analyze\ Atualiza a página do servidor e mostra um link para a página web. -In Depth Help - /plan inspect ? || > §2Comando Inspect\ Atualizar a página do jogador e mostra um link para a página web. -In Depth Help - /plan manage ? || > §2Comando Manage\ Gerencia o banco de dados MySQL e SQLite do Plan.\ §2/plan m §fListar subcomandos\ §2/plan m ? §fConsulta mais detalhada -In Depth Help - /plan manage backup ? || > §2Subcomando Backup\ Cria um novo banco de dados SQLite (arquivo .db) com o conteúdo atual do banco de dados na pasta plugin do Plan. -In Depth Help - /plan manage clear ? || > §2Subcomando Clear\ Remove qualquer coisa ativa no banco de dados. Utilize com cuidado. -In Depth Help - /plan manage con ? || > §2Subcomando Connection Debug\ Usado para depurar conexões na network.\ Envia uma requisição para cada servidor do banco de dados. -In Depth Help - /plan manage disable ? || > §2Subcomando Disable\ Pode desativar recursos do plugin até o próximo reload.\ Argumentos válidos:\ §2kickcount §fDesativa as contagens de kick em caso de /kickall. -In Depth Help - /plan manage import ? || > §2Subcomando Import\ Importa dados de outras fontes.\ Argumentos válidos:\ §2offline §fDados de jogadores do Bukkit, somente datas de registro e nomes. -In Depth Help - /plan manage move ? || > §2Subcomando Move\ Move dados do SQLite para o MySQL ou outro meio.\ O banco de dados de destino é limpo antes da transferência de dados. -In Depth Help - /plan manage remove ? || > §2Subcomando Remove\ Remover dados de jogadores do banco de dados ativo. -In Depth Help - /plan manage restore ? || > §2Restore Subcommand\ Restore a previous backup SQLite database (.db file)\ You can also restore database.db from another server to MySQL.\ Target database is cleared before transfer. -In Depth Help - /plan manage setup ? || > §2Subcomando Setup\ Configura uma conexão entre Bungee e um servidor para a funcionalidade da rede.\ O endereço Bungee pode ser encontrado no log de ativação no console quando o Plan é habilitado no Bungee. -In Depth Help - /plan network ? || > §2Comando Network\ Mostra o link para a página da network.\ Se não for uma network, essa página mostra a página do servidor. -In Depth Help - /plan players ? || > §2Comando Players\ Mostra o link para a página de jogadores. -In Depth Help - /plan qinspect ? || > §2Comando Quick Inspect\ Mostra algumas informações sobre o jogador in-game. -In Depth Help - /plan reload ? || > §2Comando Reload\ Reinicia o plugin usando onDisable e onEnable.\ §bIsso não suporta a troca de JAR (caso seja isso, precisa reiniciar o servidor) -In Depth Help - /plan search ? || > §2Comando Search\ Pega uma lista de jogadores em que o nome coincida com o argumento dado.\§7 Exemplo: /plan search 123 - Encontra todos os jogadores com 123 no nome. -In Depth Help - /plan servers ? || > §2Comando Servers\ Mostra uma lista de servidores do banco de dados.\ Podem ser usados para depurar problemas com registros no banco de dados da network. -In Depth Help - /plan update ? || > §2Comando Update\ Usado para atualizar o plugin na próxima parada\ /plan update - Changelog link\ /plan update -u - Agenda uma atualização para acontecer com todos os servidores da network que esteja online, na próxima vez em que eles sejam reiniciados.\ /plan update cancel - Cancela uma atualização agendad no servidor em que não foi reiniciado ainda. -In Depth Help - /plan web ? || > §2Comando de Gerenciado do Usuário Web.\ §2/plan web §fLista subcomandos\ §2/plan web ? §fConsulta mais detalhada -In Depth Help - /plan web register ? || > §2Subcomando Register\ Registra um novo usuário web.\ Registrando um usuário web para outro jogador precisa da permissão plan.webmanage.\ Senhas são criptografadas com PBKDF2 (64,000 iterações de SHA1) sendo totalmente aleatórias. -In Depth Help - /planbungee disable ? || > §2Comando Disable\ Executa onDisable no PlanBungee.\ O plugin pode ser ativado com /planbungee reload.\ §bNão suporta a troca de JAR (caso seja isso, precisa reiniciar o servidor) -In Depth Help - /planbungee setup ? || > §2Comando Set-up\ Alterna o modo de configuração no Bungee.\ É um método de segurança para que não haja invasão MySQL a partir de servidores fake. -Manage - Confirm Overwrite || Dados em ${0} serão sobrescritos! -Manage - Confirm Removal || Dados em ${0} serão removidos! -Manage - Fail || > §cAlguma coisa deu errado: ${0} -Manage - Fail File not found || > §cNão foi encontrado um arquivo em ${0} -Manage - Fail Incorrect Database || > §c'${0}' não é um banco de dados suportado. -Manage - Fail No Importer || §eImportador '${0}' não existe -Manage - Fail Same Database || > §cNão é possível operar do mesmo banco de dados! -Manage - Fail, Confirmation || > §cAdicione o argumento '-a' para confirmar a execução: ${0} -Manage - Fail, Connection Exception || §eMotivo de falha: -Manage - Fail, No Servers || §cNenhum servidor encontrado no banco de dados. -Manage - Fail, Old version || §eMotivo de falha: Versão do Plan muito antiga no servidor de recebimento -Manage - Fail, Unauthorized || §eMotivo de falha: Não autorizado. O servidor pode estar usando um banco de dados diferente. -Manage - Fail, Unexpected Exception || §eExceção ímpar: ${0} -Manage - List Importers || Importadores: -Manage - Notify External Url || §eEndereço é remoto, verifique se a porta está aberta -Manage - Remind HotSwap || §eLembre-se de trocar para o novo banco de dados (/plan m hotswap ${0}) & reinicie o plugin. -Manage - Start || > §2Processando dados.. -Manage - Success || > §aSucesso! -Negative || Não -Positive || Sim -Unknown || Desconhecido -Version - DEV || Essa é uma versão em desenvolvimento. -Version - Latest || Você está usando a última versão. -Version - New || Nova Versão (${0}) está disponível ${1} -Version - New (old) || Nova Versão está disponível em ${0} -Version FAIL - Read info (old) || Falha ao verificar disponibilidade de atualização -Version FAIL - Read versions.txt || Informação da versão não pode ser carregada de Github/versions.txt -Web User Listing || §2${0} §7: §f${1} -WebServer - Notify HTTP || Servidor Web: Sem Certificado -> Usando protocolo HTTP para visualização. -WebServer - Notify HTTP User Auth || Servidor Web: Autenticação de usuário desativada! (Não seguro por HTTP) -WebServer - Notify no Cert file || Servidor Web: Arquivo KeyStore não encontrado: ${0} -WebServer FAIL - Port Bind || O servidor web não foi inicializado. A porta (${0}) já está em uso? -WebServer FAIL - SSL Context || Servidor Web: Falha ao inicializar certificado SSL. -WebServer FAIL - Store Load || Servidor Web: Falha ao carregar certificado SSL. -Yesterday || 'Ontem' -Today || 'Hoje' -Health - Active Playtime Comparison Decrease || Jogadores ativos podem estar ficando sem coisas para fazer (Jogaram ${0} vs ${1}, últimas duas semanas vs últimas quatro semanas) -Health - Active Playtime Comparison Increase || Jogadores ativos parecem ter coisas para fazer (Jogaram ${0} vs ${1}, últimas duas semanas vs últimas quatro semanas) -Health - Downtime || O tempo de indisponibilidade total do servidor (sem dados) foi de ${0} -Health - New Player Join Players, No || Novos jogadores podem estar descontentes por verem o servidor com poucos jogadores ao entrar (${0} em média) -Health - New Player Join Players, Yes || Novos jogadores devem estar felizes ao entrar no servidores com muitos jogadores (${0} em média) -Health - New Player Stickiness || ${0} de novos jogadores ficaram no servidor pra jogar um pouco (${1}/${2}) -Health - No Servers Inaccuracy || Nenhum servidor Bukkit/Sponge para pegar dados de sessões - Essas medidas são imprecisas. -Health - Player Play on Network || jogadores que jogaram na network: -Health - Player Register Server || registros de jogadores no servidor por dia / servidor em média. -Health - Player Visit Server || visitas de jogadores no servidor por dia / servidor em médio. -Health - Regular Activity Change || Número de jogadores regulares é de -Health - Regular Activity Change Decrease || diminuiu (${0}) -Health - Regular Activity Change Increase || aumentou (+${0}) -Health - Regular Activity Change Zero || permaneceu o mesmo (+${0}) -Health - Regular Activity Remain || ${0} de jogadores regulares permaneceram ativos (${1}/${2}) -Health - Single Servers Inaccuracy || Único servidor Bukkit/Sponge para pegar dados de sessões. -Health - TPS Above Low Threshold || O TPS médio esteve acima do limite de segurança ${0} do tempo -Health - TPS Low Dips || O TPS médio esteve abaixo do limite de segurança (${0}) ${1} vezes -HTML - FREE_DISK_SPACE || Espaço de Disco Livre -HTML - DISK_SPACE || ESPAÇO DE DISCO \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/locale/locale_TR.txt b/Plan/common/src/main/resources/assets/plan/locale/locale_TR.txt deleted file mode 100644 index 1128fe006..000000000 --- a/Plan/common/src/main/resources/assets/plan/locale/locale_TR.txt +++ /dev/null @@ -1,315 +0,0 @@ -Cmd - Click Me || Tıkla bana -Cmd - Link || §2Link: §f -Cmd Disable - Disabled || §aPlan sistemi şuanda kapandı. Plugini yeniden başlatmak için /planbungee komutunu kullanabilirsin. -Cmd FAIL - Invalid Username || §cKullanıcının Bir UUID si yok. -Cmd FAIL - No Feature || §eDevre dışı bırakılacak özelliği seçin! (Şuanda desteklenen ${0}) -Cmd FAIL - No Permission || §cBunu gerekli izne sahip değilsin. -Cmd FAIL - Require only one Argument || §cTek Argüman gerekli ${1} -Cmd FAIL - Requires Arguments || §cArguments required (${0}) ${1} -Cmd FAIL - Unknown Username || §cKullanıcı bu sunucuda hiç görülmemiş -Cmd FAIL - WebUser does not exists || §cBöyle bir kullanıcı yok! -Cmd FAIL - WebUser exists || §cBöyle bir kullanıcı zaten var! -Cmd Header - Analysis || > §2Analiz sonuçları -Cmd Header - Info || > §2Oyuncu Analizi -Cmd Header - Inspect || > §2Oyuncu: §f${0} -Cmd Header - Network || > §2Network Sayfası -Cmd Header - Players || > §2Oyuncular -Cmd Header - Search || > §2${0} Results for §f${1}§2: -Cmd Header - Servers || > §2Sunucular -Cmd Header - Web Users || > §2${0} Web kullanıcıları -Cmd Info - Bungee Connection || §2Bungee ye bağlan: §f${0} -Cmd Info - Database || §2Aktif Veritabanı: §f${0} -Cmd Info - Reload Complete || §aYeniden başlatma tamamlandı -Cmd Info - Reload Failed || §cPlugini yeniden başlatırken bir şeyler ters gitti,yeniden başlatmanız tavsiye edilir. -Cmd Info - Update || §2Güncelleme mevcut: §f${0} -Cmd Info - Version || §2Versiyon: §f${0} -Cmd Notify - No WebUser || Beliki Web kullanıcısı değilsinizdir, Kayıt olmak için /plan register -Cmd Notify - WebUser register || Yeni bir kullanıcı kayıt oldu: '${0}' Yetki seviyesi: ${1} -Cmd Qinspect - Activity Index || §2Aktivite göstergesi: §f${0} | ${1} -Cmd Qinspect - Deaths || §2Ölümler: §f${0} -Cmd Qinspect - Geolocation || §2Bölgesinden giriş yapıldı: §f${0} -Cmd Qinspect - Last Seen || §2En son görülme: §f${0} -Cmd Qinspect - Longest Session || §2En uzun giriş: §f${0} -Cmd Qinspect - Mob Kills || §2Öldürülen canlılar: §f${0} -Cmd Qinspect - Player Kills || §2Oyuncu öldürme: §f${0} -Cmd Qinspect - Playtime || §2Oynama süresi: §f${0} -Cmd Qinspect - Registered || §2Kayıtlı: §f${0} -Cmd Qinspect - Times Kicked || §2Atılma sayısı: §f${0} -Cmd Setup - Allowed || §aŞuanda kuruluma izin verildi. -Cmd Setup - Bad Request || §eBağlantı başarılı, fakat yönlendirilmiş sunucu bir Bungee sunucusu değil. Bunun yerine Bungee adresini kullanın. -Cmd Setup - Disallowed || §cŞuanda kurulum yasaklandı -Cmd Setup - Forbidden || §eBağlantı başarılı, fakat Bungee kurulum modu kapalı - açmak için '/planbungee setup' komudunu kullanın. -Cmd Setup - Gateway Error || §eBağlantı başarılı, fakat Bungee bu sunucuya bağlanırken hata verdi (Geçerli web sunucusu yeniden başlatıldı mı?). Düzeltmek için /plan m con & /planbungee con komutlarını deneyin. -Cmd Setup - Generic Fail || §eBağlantı başarısız: ${0} -Cmd Setup - Internal Error || §eBağlantı başarılı. ${0}, sunucu ayıklama sayfasındayken hata loglarını incele. -Cmd Setup - Success || §aBağantı başarılı, Plan birkaç saniye içinde yeniden başlatılabilir.. -Cmd Setup - Unauthorized || §eBağlantı başarılı, ancak alıcı sunucu bu sunucuyu onaylamadı. Destek için Discord'a başvurun -Cmd Setup - Url mistake || §cAdrsesi tam olarak girdiğine emin ol (http:// ya da https:// ile başlamalı) - Tam adres için Bungee loglarını kontrol et. -Cmd Setup - WebServer not Enabled || §cWebServer bu sunucuda aktif değil! Açılışta etkinleştirildiğinden emin ol! -Cmd SUCCESS - Feature disabled || §aKapatıldı '${0}' Plugin yeniden başlatılana kadar. -Cmd SUCCESS - WebUser register || §aYeni kullanıcı (${0}) başarıyla eklendi! Web panelini aşağıdaki linkte görebilirsiniz. -Cmd Update - Cancel Success || §aİşlem iptal edildi. -Cmd Update - Cancelled || §cGüncelleme iptal edildi. -Cmd Update - Change log || Değişim kaydı v${0}: -Cmd Update - Fail Cacnel || §cGüncelleme sunucuda başarısız oldu, Tüm sunucularda güncellemeyi iptal edin.. -Cmd Update - Fail Force Notify || §e${0} failed to update, -force specified, continuing update. -Cmd Update - Fail Not Online || §cTüm sunucular çevrimiçi değil ya da erişilebilir değil, /plan update -u -force komudunu kullanarak plugini tüm sunucularda güncelleye bilrsin. -Cmd Update - Notify Cancel || §aTüm sunucularda plugin güncellenmeden önce /plan update cancel komuduyla iptal edebilirsin. -Cmd Update - Online Check || Tüm sunucular çevrimiçi mi diye kontrol ediliyor.. -Cmd Update - Scheduled || §a${0} Zamanlanış günceleme. -Cmd Update - Url mismatch || §cVersion download url did not start with ${0} and might not be trusted. You can download this version manually here (Direct download): -Cmd Web - Permission Levels || >\§70: Access all pages\§71: Access '/players' and all player pages\§72: Access player page with the same username as the webuser\§73+: No permissions -Command Help - /plan analyze || Sunucu Sayfasını gösterir -Command Help - /plan dev || Geliştirme modu komutu -Command Help - /plan help || Komut listesini gösterir -Command Help - /plan info || Pluginin sürümünü gösterir -Command Help - /plan inspect || Oyunucunun sayfasını gösterir -Command Help - /plan manage || Plan Veritabanını Yönet -Command Help - /plan manage backup || Veritabanını yedekler -Command Help - /plan manage clear || Veritabanını temizler -Command Help - /plan manage con || Server-Bungee bağlantı sorunlarını çözer -Command Help - /plan manage disable || Bir özelliği geçici olarak devre dışı bırakır -Command Help - /plan manage hotswap || Veritabının hızlıca değiştirir -Command Help - /plan manage import || Başka bir yerden veri alır -Command Help - /plan manage move || Veriyi Veritabanları arasında taşır -Command Help - /plan manage remove || Oyuncu bilgilerini siler -Command Help - /plan manage restore || Önceki bir Yedeği geri yükler -Command Help - /plan manage setup || Sunucu-Bungee kurulumunu yapar -Command Help - /plan network || Network sayfasını görüntüler -Command Help - /plan players || Oyuncu sayfasını görüntüler -Command Help - /plan qinspect || Oyuncu bilgilerini oyun içi gösterir -Command Help - /plan register || Web kullanıcısna kayıt yapar -Command Help - /plan reload || Plugini yeniden başlatır -Command Help - /plan search || Bir oyuncu adı arar -Command Help - /plan servers || Sunucun tüm veritabanını listeler -Command Help - /plan update || Sunucu kaydı veya plugini güncellemek için link verir -Command Help - /plan web check || Web kullanıcısını inceler -Command Help - /plan web delete || Web kullanıcısın siler -Command Help - /plan web level || Yetki seviyeleri hakkında bilgi verir -Command Help - /plan web list || Web kullanıcılarını listeler -Command Help - /plan webuser || Web kullanıcılarını listeler -Command Help - /planbungee con || Bungee-Server bağlantı sorunlarını çözer -Command Help - /planbungee disable || Eklentiyi geçici olarak devre dışı bırakır -Command Help - /planbungee setup || Kurulum modunu değiştirir -Database - Apply Patch || Yama uygulanıyor: ${0}.. -Database - Patches Applied || Yama tüm veritabanlarına başarıyla uygulandı. -Database - Patches Applied Already || Veritabanlarına yama zaten uygulanmış. -Database MySQL - Launch Options Error || Başlatma seçenekleri hatalı, varsayılan olarak kullanın (${0}) -Database Notify - Clean || ${0} oyuncunun verileri kaldırıldı. -Database Notify - SQLite No WAL || SQLite WAL modu bu sunucu versiyonunda desteklenmiyor, varsayılanı kullanın. Bu performansınızı etkiliye bilir veya etkilemezde. -Disable || Oyuncu analizi kapatıldı. -Disable - Processing || Önceden işlenmemiş kritik görevler işleniyor. (${0}) -Disable - Processing Complete || İşlenme tamamlandı. -Disable - WebServer || Websunucusu kapatıldı. -Enable || Oyuncu analizi aktif edildi. -Enable - Database || ${0}- Veritabanı bağlantısı kurulmuş. -Enable - Notify Address Confirmation || Bu sunucu adresini doğru girdiğine emin ol: ${0} -Enable - Notify Empty IP || server.properties IP adresi kısmı boş & AlternatifIP kullanılmıyor. Bu yüzden yanlış linkler verilecektir! -Enable - Notify Geolocations disabled || Coğrafi konum toplama etkin değil. (Data.Geolocations: false) -Enable - Notify Geolocations Internet Required || Plan GeoLite2 Geolocation veritabanını indirmek için ilk çalıştırmada internet erişimi gerektir. -Enable - Notify Webserver disabled || WebServer başlatılmadı. (WebServer.DisableWebServer: true) -Enable - WebServer || Webserver Bu port üzerinden çalışıyor ${0} (${1}) -Enable FAIL - Database || ${0}-Veritabanı bağlantısı başarısız: ${1} -Enable FAIL - Database Patch || VeriTabanı yaması başarısız, plugin devre dışı bırakılmış olmalı. Lütfen bu sorunu bildirin. -Enable FAIL - GeoDB Write || İndirilen GeoLite2 Geolocation veritabanını kaydederken bir şeyler ters gitti. -Enable FAIL - WebServer (Bungee) || WebServer başlatılmadı! -Enable FAIL - Wrong Database Type || ${0} Desteklenmeyen bir veritabanı -HTML - ACTIVITY_INDEX || Aktivite göstergesi -HTML - ALL || Tamamı -HTML - ALL_TIME_PEAK || Tüm Zamanların Zirvesi -HTML - AVERAGE_PING || Ortalama Ping -HTML - AVG || Ortalama -HTML - BANNED || Yasaklanmış -HTML - BEST_PING || En iyi Ping -HTML - CALENDAR || Takvim -HTML - CALENDAR_TEXT || Takvim -HTML - CHUNKS || Chunks -HTML - COMMAND || Komut -HTML - COMMNAND_USAGE || Komut Kullanımı -HTML - CONNECTION_INFORMATION || Bağlantı Bilgileri -HTML - COUNTRY || Ülke -HTML - CURRENT_PLAYERBASE || Current Playerbase -HTML - DEATHS || Ölümler -HTML - ENTITIES || Varlıklar -HTML - ERROR || Kimlik doğrulama hata nedeniyle başarısız oldu -HTML - FAVORITE_SERVER || Favori Sunucu -HTML - GEOLOCATION || Coğrafi Konum -HTML - GEOLOCATION_TEXT || Coğrafi Konum -HTML - HEALTH_ESTIMATE || Sağlık Tahmini -HTML - INDEX_ACTIVE || Aktivite -HTML - INDEX_INACTIVE || Etkisiz -HTML - INDEX_IRREGULAR || Düzensiz -HTML - INDEX_REGULAR || Düzenli -HTML - INDEX_VERY_ACTIVE || Çok Aktif -HTML - IP_ADDRESS || IP-address -HTML - KILLED || Öldürülen -HTML - KILLED_BY || Tarafından Öldürülen -HTML - LAST_24_HOURS || SON 24 SAAT -HTML - LAST_30_DAYS || SON 30 GÜN -HTML - LAST_30_DAYS_TEXT || SON 30 GÜN -HTML - LAST_7_DAYS || SON 7 GÜN -HTML - LAST_CONNECTED || Son bağlantı -HTML - LAST_PEAK || Son Zirve -HTML - LAST_SEEN || Son Görülme -HTML - LAST_SEEN_TEXT || Son Görülme -HTML - LOADED_CHUNKS || Yüklenmiş Chunks lar -HTML - LOADED_ENTITIES || Yüklenmiş Varlıklar -HTML - LOCAL_MACHINE || Yerel makine -HTML - LONGEST || En uzun -HTML - LOW_TPS_SPIKES || Düşük TPS Artışı -HTML - MOB_CAUSED_DEATHS || Yaratık Yüzünden ölümler -HTML - MOB_KDR || Mob İstatistiği -HTML - MOB_KILLS || Öldürülen Mob -HTML - MOST_RECENT_SESSIONS || En Son Oturumlar -HTML - NAME || İsim -HTML - NAV_COMMAND_USAGE || Komut kullanımı -HTML - NAV_GEOLOCATIONS || Coğrafi Konumlar -HTML - NAV_INFORMATION || Bilgi -HTML - NAV_NETWORK_PLAYERS || Network Oyuncuları -HTML - NAV_ONLINE_ACTIVITY || Çevrimiçi Etkinlik -HTML - NAV_OVERVIEW || Genel Bakış -HTML - NAV_PERFORMANCE || Performans -HTML - NAV_PLAYERS || Oyuncular -HTML - NAV_PLUGINS || Pluginler -HTML - NAV_SESSIONS || Oturumlar -HTML - NAV_SEVER_HEALTH || Sunucu Sağlığı -HTML - NETWORK || Network -HTML - NETWORK_INFORMATION || NETWORK Bilgisi -HTML - NEW || YENİ -HTML - NEW_CALENDAR || Yeni: -HTML - NEW_PLAYERS_TEXT || Yeni Oyuncular -HTML - NEW_RETENTION || New Player Retention -HTML - NEW_TEXT || Yeni -HTML - NICKNAME || Takma ad -HTML - NO_KILLS || Öldürmesi yok -HTML - NO_PLAYER_CAUSED_DEATHS || Hiçbir Oyuncu Ölüme Sebep Olmadı -HTML - OFFLINE || Çevrimdışı -HTML - ONLINE || Çevrimiçi -HTML - ONLINE_ACTIVITY || ÇEVRİMİÇİ AKTİVİTE -HTML - OPERATOR || Operator -HTML - OVERVIEW || GENEL BAKIŞ -HTML - PER_DAY || / Gün -HTML - PLAYER_CAUSED_DEATHS || Oyuncu ölüme sebep oldu -HTML - PLAYER_KILLS || Oyuncu Öldürüldü -HTML - PLAYER_LIST || Oyuncu Listesi -HTML - PLAYERBASE_DEVELOPMENT || Oyuncu Etkinlik Grafiği -HTML - PLAYERS || OYUNCULAR -HTML - PLAYERS_ONLINE || OYUNCU AKTİF -HTML - PLAYERS_ONLINE_TEXT || Oyuncu Çevrimiçi -HTML - PLAYERS_TEXT || Oyuncular -HTML - PLAYTIME || Oyun Süresi -HTML - PLEASE_WAIT || Lütfen Bekleyin... -HTML - PREDICETED_RETENTION || Tahmin Edilen Tutma -HTML - PUNCH_CARD || Punchcard -HTML - PUNCHCARD || PUNCHCARD -HTML - RECENT_LOGINS || SON GİRİŞLER -HTML - REGISTERED || KAYITLI -HTML - REGISTERED_TEXT || Kayıtlı -HTML - REGULAR || DÜZENLİ -HTML - SEEN_NICKNAMES || Görülen takma adlar -HTML - SERVER || Sunucu -HTML - SERVER_ANALYSIS || Sunucu analizi -HTML - SERVER_HEALTH_ESTIMATE || Sunucu Sağlığı Tahmini -HTML - SERVER_INFORMATION || SUNUCU BİLGİSİ -HTML - SERVER_PREFERENCE || Sunucu Tercihi -HTML - SERVERS || Sunucular -HTML - SESSION || Oturum -HTML - SESSION_ENDED || Oturum Sona Erdi -HTML - SESSION_LENGTH || Oturum Giriş Süresi -HTML - SESSION_MEDIAN || Session Median -HTML - SESSIONS || Oturumlar -HTML - TIME || Süre -HTML - TIMES_KICKED || Kere Atılmış -HTML - TIMES_USED || Kere Kullanışmış -HTML - TOTAL_ACTIVE_TEXT || Toplam Aktiflik -HTML - TOTAL_AFK || Toplam AFKlık -HTML - TOTAL_PLAYERS || Toplam Oyuncular -HTML - TOTAL_PLAYTIME || Toplam Oyunda oynanan süre -HTML - UNIQUE || İLK DEFA GİRENLER -HTML - UNIQUE_CALENDAR || Benzersiz: -HTML - UNIQUE_PLAYERS || SUNUCUYA İLK DEFA GİRENLER -HTML - UNIQUE_PLAYERS_TEXT || Sunucuya İlk Defa Girenler -HTML - UNIQUE_TEXT || İlk Defa Girenler -HTML - USAGE || Kullanım -HTML - USED_COMMANDS || Kullanılan Komutlar -HTML - USER_AND_PASS_NOT_SPECIFIED || Kullanıcı ve Şifre belirtilmedi -HTML - USER_DOES_NOT_EXIST || Böyle Bir Kullanıcı Yok -HTML - USER_INFORMATION || KULLANICI BİLGİSİ -HTML - USER_PASS_MISMATCH || Kullanıcı adı ve şifre uyuşmuyor -HTML - WITH ||
    Birlikte -HTML - WORLD || Dünya -HTML - WORLD_LOAD || WORLD LOAD -HTML - WORLD_PLAYTIME || Dünya OyunSüresi -HTML - WORST_PING || Kötü Ping -HTML ERRORS - ACCESS_DENIED_403 || Giriş reddedildi -HTML ERRORS - ANALYSIS_REFRESH || Analiz yenileniyor.. -HTML ERRORS - ANALYSIS_REFRESH_LONG || Analiz çalıştırılıyor, birkaç saniye sonra sayfayı yenileyin.. -HTML ERRORS - AUTH_FAIL_TIPS_401 || - Bir kullanıcıyı /plan register
    - ile kayıt ettiğinize emin olun ismin ve şifrenin doğru olup olmadığını kontol edin
    - Kullanıcı adı ve şifre büyük / küçük harf duyarlıdır

    Eğer şifreni unuttuysan, Yetkiliden sizi tekrar kayıt etmesini isteyin. -HTML ERRORS - AUTHENTICATION_FAIlED_401 || Kimlik doğrulama başarısız oldu. -HTML ERRORS - FORBIDDEN_403 || Yasaklanmış. -HTML ERRORS - NO_SERVERS_404 || İsteği gerçekleştirecek çevrimiçi sunucu yok. -HTML ERRORS - NOT_FOUND_404 || Bulunamadı -HTML ERRORS - NOT_PLAYED_404 || Oyuncu bu sunucuda hiç oynamadı. -HTML ERRORS - PAGE_NOT_FOUND_404 || Böyle bir sayfa mevcut değil. -HTML ERRORS - UNAUTHORIZED_401 || Yetkisiz -HTML ERRORS - UNKNOWN_PAGE_404 || Make sure you're accessing a link given by a command, Examples:

    /player/PlayerName
    /server/ServerName

    -HTML ERRORS - UUID_404 || Oyuncunun UUID si veritabanında bulunamadı. -In Depth Help - /plan ? || > §2Ana Komutlar\ Alt komutlara erişim ve yardım\ §2/plan §fList subcommands\ §2/plan ? §fdaha fazla yardım -In Depth Help - /plan analyze ? || > §2Analiz Komutu\ Sunucu sayfasını yenile ve web sayfasının bağlantısına tekrar gir. -In Depth Help - /plan inspect ? || > §2Denetleme Komutu\ Oyuncu sayfasını yenile ve web sayfasının bağlantısına tekrar gir. -In Depth Help - /plan manage ? || > §2Yönetme Komutu\ MySQL ve SQLite Plan veritabanını yönetin.\ §2/plan m §fList subcommands\ §2/plan m ? §fDaha fazla yardım -In Depth Help - /plan manage backup ? || > §2Yedekleme Alt Komutu\ Yeni bir SQLite Veritabanı (.db dosyası) Plan eklentisi klasöründeki etkin veritabanı içeriğiyle birlikte. -In Depth Help - /plan manage clear ? || > §2Temizleme Alt Komutu\ Aktf Veritabanlarındaki tüm bilgileri siler. Silmeden önce yedek alın ve herkesi uyarın. -In Depth Help - /plan manage con ? || > §2Bağlantı sorunlarını çözme alt komutu\ Networka bağlanma sorunlarını çözmek için kullanılır.\ Veritabanındaki her sunucuya bir istek gönderir. -In Depth Help - /plan manage disable ? || > §2Devre Dışı Alt Komutu\ Eklentinin parçalarını bir sonraki yeniden yüklemeye kadar devre dışı bırakır.\ Kabul edilen argümanlar:\ §2Atılma sayısı §fKapatma makrosunda / kickall kullanılıyorsa kick sayımlarını devre dışı bırakır. -In Depth Help - /plan manage import ? || > §2Import Subcommand\ Import data from other sources.\ Accepted Arguments:\ §2Çevrimdışı §fBukkit oyuncu verileri, sadece kayıt tarihi ve ismi. -In Depth Help - /plan manage move ? || > §2Veri konumu değiştirme alt Komutu\ Verileri SQLite'den MySQL'e veya başka bir yere taşıyın.\ Dosyaların gönderileceği Veritabanı aktarımdan önce temizlendi. -In Depth Help - /plan manage remove ? || > §2Silme alt Komutu\ Aktif Veritabanından oyuncu bilgilerini siler. -In Depth Help - /plan manage restore ? || > §2Onarım Alt Komutu\ Önceki bir yedek SQLite veritabanını geri yükler (.db dosyası)\ Ayrıca database.db dosyasını başka bir sunucudan MySQL'e geri yükleyebilirsiniz.\ Veriler gönderilmeden önce Veritabanı temizlenir. -In Depth Help - /plan manage setup ? || > §2Kurulum alt Komutu\ Bungeecord ile server Arasında bağlantı kurmalısın.\ Bungeeaddress planını aktif ettiğinde bungee konsolunda görünür. -In Depth Help - /plan network ? || > §2Network Komutu\ Ağ sayfasının bağlantısını görüntüler.\ Networkte değilse, bu sayfa sunucu sayfasını görüntüler. -In Depth Help - /plan players ? || > §2Oyuncu Komutu\ Oyuncular sayfasına olan bağlantıyı verir. -In Depth Help - /plan qinspect ? || > §2Hızlı Denetim Komutu\ Oyun içindeyken oyuncu hakkında bilgi verir. -In Depth Help - /plan reload ? || > §2Yeniden Başlatma Komutu\ Restarts the plugin using onDisable and onEnable.\ §bDoes not support swapping jar on the fly -In Depth Help - /plan search ? || > §2Arama Komutu\ Verilen argümanla eşleşen Oyuncu isimlerinin bir listesini alın.\§7 Örnek: /plan search 123 - 123 adındaki tüm kullanıcıları adında bulur. -In Depth Help - /plan servers ? || > §2Sunucu Komutu\ Veritabanındaki Plan sunucularının listesini görüntüler.\ Networkteki veritabanı kaydıyla ilgili sorunları çözmek için kullanılabilir. -In Depth Help - /plan update ? || > §2Güncelleme Komutu\ Bir sonraki kapanışta eklentiyi güncellemek için kullanılır\ /plan update - Değişim linki\ /plan update -u - Güncelleştirmeyi, çevrimiçi olan tüm Netwok sunucularında, bir sonraki açılışında güncellenecek şekilde ayarlayın.\ /plan update cancel - Henüz yeniden başlatılmamış sunucularda zamanlanmış güncellemeyi iptal et. -In Depth Help - /plan web ? || < §2Web Kullanıcısı Yönetim Paneli Komutu.\ §2/plan web §fList subcommands\ §2/plan web ? §fIn Depth help -In Depth Help - /plan web register ? || > §2Kayıt Alt Komutu\ Yeni bir Web Kullanıcısı kaydeder.\ Bir kullanıcıyı başka bir oyuncuya kaydetmek plan.webmanage izni gerektirir.\ Şifreler, kriptografik olarak rasgele bir sıra kullanılarak PBKDF2 (64.000 iterasyon SHA1) ile karıştırıldı. -In Depth Help - /planbungee disable ? || > §2Devre Dışı Komutu\ Runs onDisable on PlanBungee.\ Plugin can be enabled with /planbungee reload afterwards.\ §bDoes not support swapping jar on the fly -In Depth Help - /planbungee setup ? || > §2Set-up toggle Command\ Bungee'deki kurulum modunu değiştirir.\ Başka bir sunucudan yetkisiz MySQL girişine karşı korunma. -Manage - Confirm Overwrite || ${0} içindeki verilen üzerinden yazılacak! -Manage - Confirm Removal || ${0} İçindeki Veri Silinecek! -Manage - Fail || > §cBirşey yanlış gidiyor: ${0} -Manage - Fail File not found || > §cBurada bir dosya bulunamadı ${0} -Manage - Fail Incorrect Database || > §c'${0}' Desteklenmeyen bir VeriTabanı. -Manage - Fail No Importer || §eAlıcı '${0}' yok -Manage - Fail Same Database || > §cAynı veritabanında veya benzerinde çalışamaz! -Manage - Fail, Confirmation || > §cKomutu onaylamak için '-a' komuta ekle: ${0} -Manage - Fail, Connection Exception || §eHata Sebebi: -Manage - Fail, No Servers || §cVeritabanında sunucu verileri bulunamadı. -Manage - Fail, Old version || §eHata Sebebi: Şuanda sunucuzda eski Plan versiyonu çalışıyor. -Manage - Fail, Unauthorized || §eHata Sebebi: Yetkisiz. Sunucu farklı veritabanı kullanıyor olabilir. -Manage - Fail, Unexpected Exception || §eOdd Exception: ${0} -Manage - List Importers || Importers: -Manage - Notify External Url || §eBöyle bir adres yok, lütfen portların açık olduğunu kontrol edin. -Manage - Remind HotSwap || §eRemember to swap to the new database (/plan m hotswap ${0}) & reload the plugin. -Manage - Start || > §2Veri işleniyor.. -Manage - Success || > §aBaşarılı! -Negative || Hayır -Positive || Evet -Unknown || Bilinmeyen -Version - DEV || Bu bir GELİŞTİRİCİ sürümüdür. -Version - Latest || En son sürümü kullanıyorsunuz. -Version - New || Yeni sürüm (${0}) mevcut ${1} -Version - New (old) || Yeni sürüm ${0} -Version FAIL - Read info (old) || En yeni sürüm numarası kontrol edilemedi -Version FAIL - Read versions.txt || Sürüm bilgileri Github/versions.txt kısmından indirilemedi -Web User Listing || §2${0} §7: §f${1} -WebServer - Notify HTTP || WebServer: Sertifika yok -> Görüntülemek için HTTP-server kullanılıyor. -WebServer - Notify HTTP User Auth || WebServer: Kullanıcı Yetkisi Devre Dışı! (HTTP Güvenli değil) -WebServer - Notify no Cert file || WebServer: Setrifikası Dosyası Bulunamadı: ${0} -WebServer FAIL - Port Bind || Web Sunucusu başarıyla başlatılmadı. Bu (${0}) port mu kullanılıyor ? -WebServer FAIL - SSL Context || WebServer: SSL İçeriği Başlatma Başarısız Oldu. -WebServer FAIL - Store Load || WebServer: SSL Sertifikası yüklenirken sorun oluştu. -Yesterday || 'Dün' \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/themes/greyscale.yml b/Plan/common/src/main/resources/assets/plan/themes/greyscale.yml deleted file mode 100644 index 462032da4..000000000 --- a/Plan/common/src/main/resources/assets/plan/themes/greyscale.yml +++ /dev/null @@ -1,63 +0,0 @@ -# Default Theme bar color when user has not chosen a color -DefaultColor: "teal" - -Font: - # Location of the FontStyleSheet, eg. https://fonts.googleapis.com/css?family=Quicksand:300,400 - FontStyleSheet: https://fonts.googleapis.com/css?family=Roboto:400,700&subset=latin,cyrillic-ext - # Name of the Font for CSS eg "'Quicksand', sans-serif" - FontFamily: '"Roboto", sans-serif' - -# Color codes for each theme element color -# These affect icons & backgrounds of all elements of this color. -Colors: - red: "#767676" - pink: "#626262" - purple: "#595959" - deep-purple: "#555555" - indigo: "#575757" - blue: "#7D7D7D" - light-blue: "#7F7F7F" - cyan: "#868686" - teal: "#676767" - green: "#868686" - light-green: "#A4A4A4" - lime: "#C4C4C4" - yellow: "#DCDCDC" - amber: "#BEBEBE" - orange: "#A5A5A5" - deep-orange: "#838383" - brown: "#5E5E5E" - grey: "#9E9E9E" - blue-grey: "#757575" - black: "#000000" - Extra: - White: "#fff" - -# Useful tool for html colors -# https://www.w3schools.com/colors/colors_picker.asp -GraphColors: - PunchCard: "#222" - PlayersOnline: "#7A7A7A" - TPS: - High: "#555555" - Medium: "#BEBEBE" - Low: "#656565" - CPU: "#C9C9C9" - RAM: "#A1A1A1" - Chunks: "#848484" - Entities: "#8C8C8C" - WorldPie: '"#707070", "#828282", "#595959", "#676767", "#7F7F7F", "#989898", "#535353", "#888888", "#6F6F6F", "#707070"' - GMDrilldown: '"#535353", "#888888", "#6F6F6F", "#707070"' - ActivityPie: '"#8C8C8C", "#A4A4A4", "#C4C4C4", "#BEBEBE", "#757575"' - ServerPreferencePie: '"#707070", "#828282", "#595959", "#676767", "#7F7F7F", "#989898", "#535353", "#888888", "#6F6F6F", "#707070"' - WorldMap_High: "#555555" - WorldMap_Low: "#DDDDDD" - Ping: - Max: '#707070' - Avg: '#828282' - Min: '#595959' - -# Leave blank "" for white -ParsedElements: - SessionAccordion: "teal" - ServerAccordion: "light-green" diff --git a/Plan/common/src/main/resources/assets/plan/themes/mute.yml b/Plan/common/src/main/resources/assets/plan/themes/mute.yml deleted file mode 100644 index d6992cf20..000000000 --- a/Plan/common/src/main/resources/assets/plan/themes/mute.yml +++ /dev/null @@ -1,63 +0,0 @@ -# Default Theme bar color when user has not chosen a color -DefaultColor: "green" - -Font: - # Location of the FontStyleSheet, eg. https://fonts.googleapis.com/css?family=Quicksand:300,400 - FontStyleSheet: https://fonts.googleapis.com/css?family=Roboto:400,700&subset=latin,cyrillic-ext - # Name of the Font for CSS eg "'Quicksand', sans-serif" - FontFamily: '"Roboto", sans-serif' - -# Color codes for each theme element color -# These affect icons & backgrounds of all elements of this color. -Colors: - red: "#C4564E" - pink: "#B63863" - purple: "#833A8F" - deep-purple: "#604492" - indigo: "#485391" - blue: "#448DC6" - light-blue: "#3399C8" - cyan: "#33A8B6" - teal: "#27847C" - green: "#629F65" - light-green: "#94B76C" - lime: "#CAD36E" - yellow: "#F2E679" - amber: "#E6C04C" - orange: "#DD9D3F" - deep-orange: "#D06747" - brown: "#6F5850" - grey: "#9E9E9E" - blue-grey: "#687A83" - black: "#000000" - Extra: - White: "#fff" - -# Useful tool for html colors -# https://www.w3schools.com/colors/colors_picker.asp -GraphColors: - PunchCard: "#222" - PlayersOnline: "#4188CD" - TPS: - High: "#386F21" - Medium: "#D6C653" - Low: "#985050" - CPU: "#D7CF8B" - RAM: "#8ABB53" - Chunks: "#A3843C" - Entities: "#A076C9" - WorldPie: '"#2A89A5", "#709B31", "#0075FE", "#865186", "#459A8F", "#A3A344", "#5F3F9E", "#C27B33", "#4A8567", "#5F7291"' - GMDrilldown: '"#865186", "#459A8F", "#A3A344", "#5F3F9E"' - ActivityPie: '"#629F65", "#94B76C", "#CAD36E", "#E6C04C", "#687A83"' - ServerPreferencePie: '"#2A89A5", "#709B31", "#0075FE", "#865186", "#459A8F", "#A3A344", "#5F3F9E", "#C27B33", "#4A8567", "#5F7291"' - WorldMap_High: "#386F21" - WorldMap_Low: "#EEFFEE" - Ping: - Max: '#ffa000' - Avg: '#ffc107' - Min: '#ffd54f' - -# Leave blank "" for white -ParsedElements: - SessionAccordion: "teal" - ServerAccordion: "light-green" diff --git a/Plan/common/src/main/resources/assets/plan/themes/pastel.yml b/Plan/common/src/main/resources/assets/plan/themes/pastel.yml deleted file mode 100644 index 01c4c79aa..000000000 --- a/Plan/common/src/main/resources/assets/plan/themes/pastel.yml +++ /dev/null @@ -1,63 +0,0 @@ -# Default Theme bar color when user has not chosen a color -DefaultColor: "indigo" - -Font: - # Location of the FontStyleSheet, eg. https://fonts.googleapis.com/css?family=Quicksand:300,400 - FontStyleSheet: https://fonts.googleapis.com/css?family=Roboto:400,700&subset=latin,cyrillic-ext - # Name of the Font for CSS eg "'Quicksand', sans-serif" - FontFamily: '"Roboto", sans-serif' - -# Color codes for each theme element color -# These affect icons & backgrounds of all elements of this color. -Colors: - red: "#FF0000" - pink: "#FF0065" - purple: "#FF00FF" - deep-purple: "#870BFF" - indigo: "#1546FF" - blue: "#00C2FF" - light-blue: "#00F2FF" - cyan: "#00FFFF" - teal: "#00E8C1" - green: "#00F600" - light-green: "#5FF900" - lime: "#DDFF00" - yellow: "#FFFF00" - amber: "#FFC600" - orange: "#FF8100" - deep-orange: "#FF0A00" - brown: "#A84522" - grey: "#9E9E9E" - blue-grey: "#3C8BB2" - black: "#000000" - Extra: - White: "#fff" - -# Useful tool for html colors -# https://www.w3schools.com/colors/colors_picker.asp -GraphColors: - PunchCard: "#222" - PlayersOnline: "#00B6FF" - TPS: - High: "#00C800" - Medium: "#FFE400" - Low: "#FF0808" - CPU: "#FFE200" - RAM: "#3EFF00" - Chunks: "#FF8200" - Entities: "#E32CFF" - WorldPie: '"#00E0FF", "#35EF00", "#0075FE", "#F007F0", "#00F5C6", "#C9C900", "#8700FF", "#FF4E00", "#00CF4C", "#267BFF"' - GMDrilldown: '"#C9C900", "#8700FF", "#FF4E00", "#00CF4C"' - ActivityPie: '"#00F600", "#5FF900", "#DDFF00", "#FFC600", "#3C8BB2"' - ServerPreferencePie: '"#00E0FF", "#35EF00", "#0075FE", "#F007F0", "#00F5C6", "#C9C900", "#8700FF", "#FF4E00", "#00CF4C", "#267BFF"' - WorldMap_High: "#00C800" - WorldMap_Low: "#EEFFEE" - Ping: - Max: '#ffa000' - Avg: '#ffc107' - Min: '#ffd54f' - -# Leave blank "" for white -ParsedElements: - SessionAccordion: "teal" - ServerAccordion: "light-green" diff --git a/Plan/common/src/main/resources/assets/plan/themes/sepia.yml b/Plan/common/src/main/resources/assets/plan/themes/sepia.yml deleted file mode 100644 index e151334a8..000000000 --- a/Plan/common/src/main/resources/assets/plan/themes/sepia.yml +++ /dev/null @@ -1,63 +0,0 @@ -# Default Theme bar color when user has not chosen a color -DefaultColor: "brown" - -Font: - # Location of the FontStyleSheet, eg. https://fonts.googleapis.com/css?family=Quicksand:300,400 - FontStyleSheet: https://fonts.googleapis.com/css?family=Roboto:400,700&subset=latin,cyrillic-ext - # Name of the Font for CSS eg "'Quicksand', sans-serif" - FontFamily: '"Roboto", sans-serif' - -# Color codes for each theme element color -# These affect icons & backgrounds of all elements of this color. -Colors: - red: "#897665" - pink: "#766250" - purple: "#6D5948" - deep-purple: "#695544" - indigo: "#6B5746" - blue: "#907D6C" - light-blue: "#917F6E" - cyan: "#988675" - teal: "#7B6755" - green: "#988675" - light-green: "#B3A496" - lime: "#CEC4B9" - yellow: "#E2DCD5" - amber: "#C9BEB3" - orange: "#B4A597" - deep-orange: "#958372" - brown: "#725E4C" - grey: "#AD9E8F" - blue-grey: "#887564" - black: "#000000" - Extra: - White: "#fff" - -# Useful tool for html colors -# https://www.w3schools.com/colors/colors_picker.asp -GraphColors: - PunchCard: "#322216" - PlayersOnline: "#8D7A69" - TPS: - High: "#695544" - Medium: "#C9BEB3" - Low: "#796553" - CPU: "#D2C9BF" - RAM: "#B0A192" - Chunks: "#968473" - Entities: "#9D8C7C" - WorldPie: '"#84705F", "#948271", "#6D5948", "#7B6755", "#917F6E", "#A89889", "#675342", "#9A8877", "#836F5D", "#84705F"' - GMDrilldown: '"#917F6E", "#A89889", "#675342", "#9A8877"' - ActivityPie: '"#988675", "#B3A496", "#CEC4B9", "#C9BEB3", "#887564"' - ServerPreferencePie: '"#84705F", "#948271", "#6D5948", "#7B6755", "#917F6E", "#A89889", "#675342", "#9A8877", "#836F5D", "#84705F"' - WorldMap_High: "#695544" - WorldMap_Low: "#FFFFFF" - Ping: - Max: '#ffa000' - Avg: '#ffc107' - Min: '#ffd54f' - -# Leave blank "" for white -ParsedElements: - SessionAccordion: "teal" - ServerAccordion: "light-green" diff --git a/Plan/common/src/main/resources/assets/plan/themes/soft.yml b/Plan/common/src/main/resources/assets/plan/themes/soft.yml deleted file mode 100644 index ad3602520..000000000 --- a/Plan/common/src/main/resources/assets/plan/themes/soft.yml +++ /dev/null @@ -1,63 +0,0 @@ -# Default Theme bar color when user has not chosen a color -DefaultColor: "light-green" - -Font: - # Location of the FontStyleSheet, eg. https://fonts.googleapis.com/css?family=Quicksand:300,400 - FontStyleSheet: https://fonts.googleapis.com/css?family=Roboto:400,700&subset=latin,cyrillic-ext - # Name of the Font for CSS eg "'Quicksand', sans-serif" - FontFamily: '"Roboto", sans-serif' - -# Color codes for each theme element color -# These affect icons & backgrounds of all elements of this color. -Colors: - red: "#F43D2C" - pink: "#C41744" - purple: "#791C70" - deep-purple: "#4C286F" - indigo: "#2F376F" - blue: "#3293D5" - light-blue: "#1CA9DD" - cyan: "#27BFC8" - teal: "#007B63" - green: "#69B54C" - light-green: "#BAD364" - lime: "#EFEF84" - yellow: "#FFFAA8" - amber: "#FFDF5C" - orange: "#FFB527" - deep-orange: "#FE5A1F" - brown: "#623F2F" - grey: "#C1B5A9" - blue-grey: "#617372" - black: "#000000" - Extra: - White: "#fff" - -# Useful tool for html colors -# https://www.w3schools.com/colors/colors_picker.asp -GraphColors: - PunchCard: "#0A0908" - PlayersOnline: "#298ADA" - TPS: - High: "#1C5601" - Medium: "#F5E461" - Low: "#9F352F" - CPU: "#F7ECA4" - RAM: "#AFD93F" - Chunks: "#BF870F" - Entities: "#BC76EA" - WorldPie: '"#00869B", "#79AC00", "#25455D", "#8D3472", "#33A887", "#C5BC24", "#492176", "#EA7C00", "#307F4C", "#516681"' - GMDrilldown: '"#8D3472", "#33A887", "#C5BC24", "#492176"' - ActivityPie: '"#69B54C", "#BAD364", "#EFEF84", "#FFDF5C", "#617372"' - ServerPreferencePie: '"#00869B", "#79AC00", "#25455D", "#8D3472", "#33A887", "#C5BC24", "#492176", "#EA7C00", "#307F4C", "#516681"' - WorldMap_High: "#267f00" - WorldMap_Low: "#EEFFEE" - Ping: - Max: '#ffa000' - Avg: '#ffc107' - Min: '#ffd54f' - -# Leave blank "" for white -ParsedElements: - SessionAccordion: "teal" - ServerAccordion: "light-green" diff --git a/Plan/common/src/main/resources/assets/plan/themes/theme.yml b/Plan/common/src/main/resources/assets/plan/themes/theme.yml deleted file mode 100644 index c7a5df825..000000000 --- a/Plan/common/src/main/resources/assets/plan/themes/theme.yml +++ /dev/null @@ -1,63 +0,0 @@ -# Default Theme bar color when user has not chosen a color -DefaultColor: "light-green" - -Font: - # Location of the FontStyleSheet, eg. https://fonts.googleapis.com/css?family=Quicksand:300,400 - FontStyleSheet: https://fonts.googleapis.com/css?family=Roboto:400,700&subset=latin,cyrillic-ext - # Name of the Font for CSS eg "'Quicksand', sans-serif" - FontFamily: '"Roboto", sans-serif' - -# Color codes for each theme element color -# These affect icons & backgrounds of all elements of this color. -Colors: - red: "#F44336" - pink: "#E91E63" - purple: "#9C27B0" - deep-purple: "#673AB7" - indigo: "#3F51B5" - blue: "#2196F3" - light-blue: "#03A9F4" - cyan: "#00BCD4" - teal: "#009688" - green: "#4CAF50" - light-green: "#8BC34A" - lime: "#CDDC39" - yellow: "#ffe821" - amber: "#FFC107" - orange: "#FF9800" - deep-orange: "#FF5722" - brown: "#795548" - grey: "#9E9E9E" - blue-grey: "#607D8B" - black: "#000000" - Extra: - White: "#fff" - -# Useful tool for html colors -# https://www.w3schools.com/colors/colors_picker.asp -GraphColors: - PunchCard: "#222" - PlayersOnline: "#1E90FF" - TPS: - High: "#267F00" - Medium: "#e5cc12" - Low: "#b74343" - CPU: "#e0d264" - RAM: "#7dcc24" - Chunks: "#b58310" - Entities: "#ac69ef" - WorldPie: '"#0099C6", "#66AA00", "#316395", "#994499", "#22AA99", "#AAAA11", "#6633CC", "#E67300", "#329262", "#5574A6"' - GMDrilldown: '"#438c99", "#639A67", "#D8EBB5", "#D9BF77"' - ActivityPie: '"#4CAF50", "#8BC34A", "#CDDC39", "#FFC107", "#607D8B"' - ServerPreferencePie: '"#0099C6", "#66AA00", "#316395", "#994499", "#22AA99", "#AAAA11", "#6633CC", "#E67300", "#329262", "#5574A6"' - WorldMap_High: "#267f00" - WorldMap_Low: "#EEFFEE" - Ping: - Max: '#ffa000' - Avg: '#ffc107' - Min: '#ffd54f' - -# Leave blank "" for white -ParsedElements: - SessionAccordion: "teal" - ServerAccordion: "light-green" diff --git a/Plan/common/src/main/resources/assets/plan/web/css/main.css b/Plan/common/src/main/resources/assets/plan/web/css/main.css deleted file mode 100644 index 19ddc2f88..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/css/main.css +++ /dev/null @@ -1,168 +0,0 @@ -.black { - color: #000000; -} -.darkblue { - color: #0000AA; -} -.darkgreen { - color: #00AA00; -} -.darkaqua { - color: #00AAAA; -} -.darkred { - color: #AA0000; -} -.darkpurple { - color: #AA00AA; -} -.gold { - color: #FFAA00; -} -.gray { - color: #AAAAAA; -} -.darkgray { - color: #555555; -} -.blue { - color: #5555FF; -} -.green { - color: #55FF55; -} -.aqua { - color: #55FFFF; -} -.red { - color: #FF5555; -} -.pink { - color: #FF55FF; -} -.yellow { - color: #FFFF55; - text-shadow: 0 0 6px #000; -} -.white { - color: #FFFFFF; - text-shadow: 0 0 8px #000; -} - -.g { - color: #008000; -} -.o { - color: #FFA500; -} -.r { - color: #FF4500; -} - -.nav-button { -} - -.sidenav-button:hover { - background: #89c471; -} - -.right { - float: right; -} -.left { - float: left; -} - -.plugin { - max-height: 300px; - overflow-y: auto; - height: 100%; -} - -.main-limiter { - width: 100%; - overflow-x: hidden; - margin: 0; - padding: 0; -} - -.tab { - width: 0; - float: left; -} - -.scrollbar { - max-height: 650px; - overflow-y: auto; -} - -.session-header h3 { - margin: 0; -} -.session-header p { - margin: 0; -} -.session { - -} - -.session-header { - background: #ddd; - color: #000; - margin: 1px 3px; - display: flex; - flex-direction: row; - padding: 0; -} - -.session-col { - width: 100%; - background: #fff; - color: #000; - margin: 0 2px; - display: flex; - flex-direction: column; - padding: 10px 20px; -} - -.session-content { - display: none; - margin: 2px 10px; - flex-direction: row; -} - -.plugins-content { - display: none; -} -.plugins-header h2 { - margin: 0; -} -.plugins-header p { - margin: 0; -} - -.plugin { - padding: 10px; -} - -.plugin p { - padding: 5px 0; - margin: 0; -} - -.help { - text-decoration: none; -!important; -} - -@media only screen and (max-width: 1680px) { - .nav-button { - font-size: 19px; - } -} -@media only screen and (max-width: 780px) { - .scrollbar { - overflow-x: auto; - width: 100%; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/css/materialize.css b/Plan/common/src/main/resources/assets/plan/web/css/materialize.css deleted file mode 100644 index f1ed98446..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/css/materialize.css +++ /dev/null @@ -1,415 +0,0 @@ -/*! - * Materialize v0.97.7 (http://materializecss.com) - * Copyright 2014-2015 Materialize - * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) - */ - -/* Radio Buttons - ========================================================================== */ -[type="radio"]:not(:checked), -[type="radio"]:checked { - position: absolute; - left: -9999px; - opacity: 0; -} - -[type="radio"]:not(:checked) + label, -[type="radio"]:checked + label { - position: relative; - padding-left: 35px; - cursor: pointer; - display: inline-block; - height: 25px; - line-height: 25px; - font-size: 1rem; - transition: .28s ease; - /* webkit (konqueror) browsers */ - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -[type="radio"] + label:before, -[type="radio"] + label:after { - content: ''; - position: absolute; - left: 0; - top: 0; - margin: 4px; - width: 16px; - height: 16px; - z-index: 0; - transition: .28s ease; -} - -/* Unchecked styles */ -[type="radio"]:not(:checked) + label:before, -[type="radio"]:not(:checked) + label:after, -[type="radio"]:checked + label:before, -[type="radio"]:checked + label:after, -[type="radio"].with-gap:checked + label:before, -[type="radio"].with-gap:checked + label:after { - border-radius: 50%; -} - -[type="radio"]:not(:checked) + label:before, -[type="radio"]:not(:checked) + label:after { - border: 2px solid #5a5a5a; -} - -[type="radio"]:not(:checked) + label:after { - z-index: -1; - -webkit-transform: scale(0); - transform: scale(0); -} - -/* Checked styles */ -[type="radio"]:checked + label:before { - border: 2px solid transparent; -} - -[type="radio"]:checked + label:after, -[type="radio"].with-gap:checked + label:before, -[type="radio"].with-gap:checked + label:after { - border: 2px solid #26a69a; -} - -[type="radio"]:checked + label:after, -[type="radio"].with-gap:checked + label:after { - background-color: #26a69a; - z-index: 0; -} - -[type="radio"]:checked + label:after { - -webkit-transform: scale(1.02); - transform: scale(1.02); -} - -/* Radio With gap */ -[type="radio"].with-gap:checked + label:after { - -webkit-transform: scale(0.5); - transform: scale(0.5); -} - -/* Focused styles */ -[type="radio"].tabbed:focus + label:before { - box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); -} - -/* Disabled Radio With gap */ -[type="radio"].with-gap:disabled:checked + label:before { - border: 2px solid rgba(0, 0, 0, 0.26); -} - -[type="radio"].with-gap:disabled:checked + label:after { - border: none; - background-color: rgba(0, 0, 0, 0.26); -} - -/* Disabled style */ -[type="radio"]:disabled:not(:checked) + label:before, -[type="radio"]:disabled:checked + label:before { - background-color: transparent; - border-color: rgba(0, 0, 0, 0.26); -} - -[type="radio"]:disabled + label { - color: rgba(0, 0, 0, 0.26); -} - -[type="radio"]:disabled:not(:checked) + label:before { - border-color: rgba(0, 0, 0, 0.26); -} - -[type="radio"]:disabled:checked + label:after { - background-color: rgba(0, 0, 0, 0.26); - border-color: #BDBDBD; -} - -/* Checkboxes - ========================================================================== */ -/* CUSTOM CSS CHECKBOXES */ -form p { - margin-bottom: 10px; - text-align: left; -} - -form p:last-child { - margin-bottom: 0; -} - -/* Remove default checkbox */ -[type="checkbox"]:not(:checked), -[type="checkbox"]:checked { - position: absolute; - left: -9999px; - opacity: 0; -} - -[type="checkbox"] { - /* checkbox aspect */ -} - -[type="checkbox"] + label { - position: relative; - padding-left: 35px; - cursor: pointer; - display: inline-block; - height: 25px; - line-height: 25px; - font-size: 1rem; - -webkit-user-select: none; - /* webkit (safari, chrome) browsers */ - -moz-user-select: none; - /* mozilla browsers */ - -khtml-user-select: none; - /* webkit (konqueror) browsers */ - -ms-user-select: none; - /* IE10+ */ -} - -[type="checkbox"] + label:before, -[type="checkbox"]:not(.filled-in) + label:after { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 18px; - height: 18px; - z-index: 0; - border: 2px solid #5a5a5a; - border-radius: 1px; - margin-top: 2px; - transition: .2s; -} - -[type="checkbox"]:not(.filled-in) + label:after { - border: 0; - -webkit-transform: scale(0); - transform: scale(0); -} - -[type="checkbox"]:not(:checked):disabled + label:before { - border: none; - background-color: rgba(0, 0, 0, 0.26); -} - -[type="checkbox"].tabbed:focus + label:after { - -webkit-transform: scale(1); - transform: scale(1); - border: 0; - border-radius: 50%; - box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); - background-color: rgba(0, 0, 0, 0.1); -} - -[type="checkbox"]:checked + label:before { - top: -4px; - left: -5px; - width: 12px; - height: 22px; - border: 2px solid transparent; - border-right-color: #26a69a; - border-bottom-color: #26a69a; - -webkit-transform: rotate(40deg); - transform: rotate(40deg); - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - -webkit-transform-origin: 100% 100%; - transform-origin: 100% 100%; -} - -[type="checkbox"]:checked:disabled + label:before { - border-right: 2px solid rgba(0, 0, 0, 0.26); - border-bottom: 2px solid rgba(0, 0, 0, 0.26); -} - -/* Indeterminate checkbox */ -[type="checkbox"]:indeterminate + label:before { - top: -11px; - left: -12px; - width: 10px; - height: 22px; - border-top: none; - border-left: none; - border-right: 2px solid #26a69a; - border-bottom: none; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - -webkit-transform-origin: 100% 100%; - transform-origin: 100% 100%; -} - -[type="checkbox"]:indeterminate:disabled + label:before { - border-right: 2px solid rgba(0, 0, 0, 0.26); - background-color: transparent; -} - -[type="checkbox"].filled-in + label:after { - border-radius: 2px; -} - -[type="checkbox"].filled-in + label:before, -[type="checkbox"].filled-in + label:after { - content: ''; - left: 0; - position: absolute; - /* .1s delay is for check animation */ - transition: border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s; - z-index: 1; -} - -[type="checkbox"].filled-in:not(:checked) + label:before { - width: 0; - height: 0; - border: 3px solid transparent; - left: 6px; - top: 10px; - -webkit-transform: rotateZ(37deg); - transform: rotateZ(37deg); - -webkit-transform-origin: 20% 40%; - transform-origin: 100% 100%; -} - -[type="checkbox"].filled-in:not(:checked) + label:after { - height: 20px; - width: 20px; - background-color: transparent; - border: 2px solid #5a5a5a; - top: 0; - z-index: 0; -} - -[type="checkbox"].filled-in:checked + label:before { - top: 0; - left: 1px; - width: 8px; - height: 13px; - border-top: 2px solid transparent; - border-left: 2px solid transparent; - border-right: 2px solid #fff; - border-bottom: 2px solid #fff; - -webkit-transform: rotateZ(37deg); - transform: rotateZ(37deg); - -webkit-transform-origin: 100% 100%; - transform-origin: 100% 100%; -} - -[type="checkbox"].filled-in:checked + label:after { - top: 0; - width: 20px; - height: 20px; - border: 2px solid #26a69a; - background-color: #26a69a; - z-index: 0; -} - -[type="checkbox"].filled-in.tabbed:focus + label:after { - border-radius: 2px; - border-color: #5a5a5a; - background-color: rgba(0, 0, 0, 0.1); -} - -[type="checkbox"].filled-in.tabbed:checked:focus + label:after { - border-radius: 2px; - background-color: #26a69a; - border-color: #26a69a; -} - -[type="checkbox"].filled-in:disabled:not(:checked) + label:before { - background-color: transparent; - border: 2px solid transparent; -} - -[type="checkbox"].filled-in:disabled:not(:checked) + label:after { - border-color: transparent; - background-color: #BDBDBD; -} - -[type="checkbox"].filled-in:disabled:checked + label:before { - background-color: transparent; -} - -[type="checkbox"].filled-in:disabled:checked + label:after { - background-color: #BDBDBD; - border-color: #BDBDBD; -} - -/* Switch - ========================================================================== */ -.switch, -.switch * { - -webkit-user-select: none; - -moz-user-select: none; - -khtml-user-select: none; - -ms-user-select: none; -} - -.switch label { - cursor: pointer; -} - -.switch label input[type=checkbox] { - opacity: 0; - width: 0; - height: 0; -} - -.switch label input[type=checkbox]:checked + .lever { - background-color: #84c7c1; -} - -.switch label input[type=checkbox]:checked + .lever:after { - background-color: #26a69a; - left: 24px; -} - -.switch label .lever { - content: ""; - display: inline-block; - position: relative; - width: 40px; - height: 15px; - background-color: #818181; - border-radius: 15px; - margin-right: 10px; - transition: background 0.3s ease; - vertical-align: middle; - margin: 0 16px; -} - -.switch label .lever:after { - content: ""; - position: absolute; - display: inline-block; - width: 21px; - height: 21px; - background-color: #F1F1F1; - border-radius: 21px; - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4); - left: -5px; - top: -3px; - transition: left 0.3s ease, background .3s ease, box-shadow 0.1s ease; -} - -input[type=checkbox]:checked:not(:disabled) ~ .lever:active::after, -input[type=checkbox]:checked:not(:disabled).tabbed:focus ~ .lever::after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(38, 166, 154, 0.1); -} - -input[type=checkbox]:not(:disabled) ~ .lever:active:after, -input[type=checkbox]:not(:disabled).tabbed:focus ~ .lever::after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(0, 0, 0, 0.08); -} - -.switch input[type=checkbox][disabled] + .lever { - cursor: default; -} - -.switch label input[type=checkbox][disabled] + .lever:after, -.switch label input[type=checkbox][disabled]:checked + .lever:after { - background-color: #BDBDBD; -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/css/style.css b/Plan/common/src/main/resources/assets/plan/web/css/style.css deleted file mode 100644 index 6bb4a8702..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/css/style.css +++ /dev/null @@ -1,8042 +0,0 @@ -/* Navbar ====================================== */ -@import url(materialize.css); -.navbar { - font-family: "Roboto", sans-serif; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - -ms-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - border: none; - position: fixed; - top: 0; - left: 0; - z-index: 12; - width: 100%; } - .navbar .navbar-brand { - white-space: nowrap; - -ms-text-overflow: ellipsis; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; - overflow: hidden; } - .navbar .navbar-custom-right-menu { - float: right; } - .navbar .navbar-toggle { - text-decoration: none; - color: #fff; - width: 20px; - height: 20px; - margin-top: -4px; - margin-right: 17px; } - .navbar .navbar-toggle:before { - content: '\E8D5'; - font-family: 'Material Icons'; - font-size: 26px; } - .navbar .navbar-collapse.in { - overflow: visible; } - -.ls-closed .sidebar { - margin-left: -300px; } - -.ls-closed section.content { - margin-left: 15px; } - -.ls-closed .bars:after, .ls-closed .bars:before { - font-family: 'Material Icons'; - font-size: 24px; - position: absolute; - top: 18px; - left: 20px; - margin-right: 10px; - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - -webkit-transform: scale(0); - transform: scale(0); - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - -webkit-transition: all 0.3s; - transition: all 0.3s; } - -.ls-closed .bars:before { - content: '\E5D2'; - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - -webkit-transform: scale(1); - transform: scale(1); } - -.ls-closed .bars:after { - content: '\E5C4'; - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - -webkit-transform: scale(0); - transform: scale(0); } - -.ls-closed .navbar-brand { - margin-left: 30px; } - -.overlay-open .bars:before { - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - -webkit-transform: scale(0); - transform: scale(0); } - -.overlay-open .bars:after { - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - -webkit-transform: scale(1); - transform: scale(1); } - -.navbar-header { - padding: 10px 7px; } - .navbar-header .bars { - float: left; - text-decoration: none; } - -.navbar-nav > li > a { - padding: 7px 7px 2px 7px; - margin-top: 17px; - margin-left: 5px; } - -.navbar-nav .dropdown-menu { - margin-top: -40px !important; } - -.label-count { - position: absolute; - top: 2px; - right: 6px; - font-size: 10px; - line-height: 15px; - background-color: #000; - padding: 0 4px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - border-radius: 3px; } - -.col-red .navbar .navbar-brand, -.col-red .navbar .navbar-brand:hover, -.col-red .navbar .navbar-brand:active, -.col-red .navbar .navbar-brand:focus { - color: #fff; } - -.col-red .navbar .nav > li > a:hover, -.col-red .navbar .nav > li > a:focus, -.col-red .navbar .nav .open > a, -.col-red .navbar .nav .open > a:hover, -.col-red .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-red .navbar .nav > li > a { - color: #fff; } - -.col-red .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-red .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-pink .navbar .navbar-brand, -.col-pink .navbar .navbar-brand:hover, -.col-pink .navbar .navbar-brand:active, -.col-pink .navbar .navbar-brand:focus { - color: #fff; } - -.col-pink .navbar .nav > li > a:hover, -.col-pink .navbar .nav > li > a:focus, -.col-pink .navbar .nav .open > a, -.col-pink .navbar .nav .open > a:hover, -.col-pink .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-pink .navbar .nav > li > a { - color: #fff; } - -.col-pink .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-pink .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-purple .navbar .navbar-brand, -.col-purple .navbar .navbar-brand:hover, -.col-purple .navbar .navbar-brand:active, -.col-purple .navbar .navbar-brand:focus { - color: #fff; } - -.col-purple .navbar .nav > li > a:hover, -.col-purple .navbar .nav > li > a:focus, -.col-purple .navbar .nav .open > a, -.col-purple .navbar .nav .open > a:hover, -.col-purple .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-purple .navbar .nav > li > a { - color: #fff; } - -.col-purple .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-purple .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-deep-purple .navbar .navbar-brand, -.col-deep-purple .navbar .navbar-brand:hover, -.col-deep-purple .navbar .navbar-brand:active, -.col-deep-purple .navbar .navbar-brand:focus { - color: #fff; } - -.col-deep-purple .navbar .nav > li > a:hover, -.col-deep-purple .navbar .nav > li > a:focus, -.col-deep-purple .navbar .nav .open > a, -.col-deep-purple .navbar .nav .open > a:hover, -.col-deep-purple .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-deep-purple .navbar .nav > li > a { - color: #fff; } - -.col-deep-purple .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-deep-purple .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-indigo .navbar .navbar-brand, -.col-indigo .navbar .navbar-brand:hover, -.col-indigo .navbar .navbar-brand:active, -.col-indigo .navbar .navbar-brand:focus { - color: #fff; } - -.col-indigo .navbar .nav > li > a:hover, -.col-indigo .navbar .nav > li > a:focus, -.col-indigo .navbar .nav .open > a, -.col-indigo .navbar .nav .open > a:hover, -.col-indigo .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-indigo .navbar .nav > li > a { - color: #fff; } - -.col-indigo .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-indigo .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-blue .navbar .navbar-brand, -.col-blue .navbar .navbar-brand:hover, -.col-blue .navbar .navbar-brand:active, -.col-blue .navbar .navbar-brand:focus { - color: #fff; } - -.col-blue .navbar .nav > li > a:hover, -.col-blue .navbar .nav > li > a:focus, -.col-blue .navbar .nav .open > a, -.col-blue .navbar .nav .open > a:hover, -.col-blue .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-blue .navbar .nav > li > a { - color: #fff; } - -.col-blue .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-blue .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-light-blue .navbar .navbar-brand, -.col-light-blue .navbar .navbar-brand:hover, -.col-light-blue .navbar .navbar-brand:active, -.col-light-blue .navbar .navbar-brand:focus { - color: #fff; } - -.col-light-blue .navbar .nav > li > a:hover, -.col-light-blue .navbar .nav > li > a:focus, -.col-light-blue .navbar .nav .open > a, -.col-light-blue .navbar .nav .open > a:hover, -.col-light-blue .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-light-blue .navbar .nav > li > a { - color: #fff; } - -.col-light-blue .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-light-blue .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-cyan .navbar .navbar-brand, -.col-cyan .navbar .navbar-brand:hover, -.col-cyan .navbar .navbar-brand:active, -.col-cyan .navbar .navbar-brand:focus { - color: #fff; } - -.col-cyan .navbar .nav > li > a:hover, -.col-cyan .navbar .nav > li > a:focus, -.col-cyan .navbar .nav .open > a, -.col-cyan .navbar .nav .open > a:hover, -.col-cyan .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-cyan .navbar .nav > li > a { - color: #fff; } - -.col-cyan .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-cyan .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-teal .navbar .navbar-brand, -.col-teal .navbar .navbar-brand:hover, -.col-teal .navbar .navbar-brand:active, -.col-teal .navbar .navbar-brand:focus { - color: #fff; } - -.col-teal .navbar .nav > li > a:hover, -.col-teal .navbar .nav > li > a:focus, -.col-teal .navbar .nav .open > a, -.col-teal .navbar .nav .open > a:hover, -.col-teal .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-teal .navbar .nav > li > a { - color: #fff; } - -.col-teal .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-teal .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-green .navbar .navbar-brand, -.col-green .navbar .navbar-brand:hover, -.col-green .navbar .navbar-brand:active, -.col-green .navbar .navbar-brand:focus { - color: #fff; } - -.col-green .navbar .nav > li > a:hover, -.col-green .navbar .nav > li > a:focus, -.col-green .navbar .nav .open > a, -.col-green .navbar .nav .open > a:hover, -.col-green .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-green .navbar .nav > li > a { - color: #fff; } - -.col-green .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-green .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-light-green .navbar .navbar-brand, -.col-light-green .navbar .navbar-brand:hover, -.col-light-green .navbar .navbar-brand:active, -.col-light-green .navbar .navbar-brand:focus { - color: #fff; } - -.col-light-green .navbar .nav > li > a:hover, -.col-light-green .navbar .nav > li > a:focus, -.col-light-green .navbar .nav .open > a, -.col-light-green .navbar .nav .open > a:hover, -.col-light-green .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-light-green .navbar .nav > li > a { - color: #fff; } - -.col-light-green .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-light-green .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-lime .navbar .navbar-brand, -.col-lime .navbar .navbar-brand:hover, -.col-lime .navbar .navbar-brand:active, -.col-lime .navbar .navbar-brand:focus { - color: #fff; } - -.col-lime .navbar .nav > li > a:hover, -.col-lime .navbar .nav > li > a:focus, -.col-lime .navbar .nav .open > a, -.col-lime .navbar .nav .open > a:hover, -.col-lime .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-lime .navbar .nav > li > a { - color: #fff; } - -.col-lime .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-lime .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-yellow .navbar .navbar-brand, -.col-yellow .navbar .navbar-brand:hover, -.col-yellow .navbar .navbar-brand:active, -.col-yellow .navbar .navbar-brand:focus { - color: #fff; } - -.col-yellow .navbar .nav > li > a:hover, -.col-yellow .navbar .nav > li > a:focus, -.col-yellow .navbar .nav .open > a, -.col-yellow .navbar .nav .open > a:hover, -.col-yellow .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-yellow .navbar .nav > li > a { - color: #fff; } - -.col-yellow .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-yellow .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-amber .navbar .navbar-brand, -.col-amber .navbar .navbar-brand:hover, -.col-amber .navbar .navbar-brand:active, -.col-amber .navbar .navbar-brand:focus { - color: #fff; } - -.col-amber .navbar .nav > li > a:hover, -.col-amber .navbar .nav > li > a:focus, -.col-amber .navbar .nav .open > a, -.col-amber .navbar .nav .open > a:hover, -.col-amber .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-amber .navbar .nav > li > a { - color: #fff; } - -.col-amber .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-amber .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-orange .navbar .navbar-brand, -.col-orange .navbar .navbar-brand:hover, -.col-orange .navbar .navbar-brand:active, -.col-orange .navbar .navbar-brand:focus { - color: #fff; } - -.col-orange .navbar .nav > li > a:hover, -.col-orange .navbar .nav > li > a:focus, -.col-orange .navbar .nav .open > a, -.col-orange .navbar .nav .open > a:hover, -.col-orange .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-orange .navbar .nav > li > a { - color: #fff; } - -.col-orange .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-orange .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-deep-orange .navbar .navbar-brand, -.col-deep-orange .navbar .navbar-brand:hover, -.col-deep-orange .navbar .navbar-brand:active, -.col-deep-orange .navbar .navbar-brand:focus { - color: #fff; } - -.col-deep-orange .navbar .nav > li > a:hover, -.col-deep-orange .navbar .nav > li > a:focus, -.col-deep-orange .navbar .nav .open > a, -.col-deep-orange .navbar .nav .open > a:hover, -.col-deep-orange .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-deep-orange .navbar .nav > li > a { - color: #fff; } - -.col-deep-orange .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-deep-orange .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-brown .navbar .navbar-brand, -.col-brown .navbar .navbar-brand:hover, -.col-brown .navbar .navbar-brand:active, -.col-brown .navbar .navbar-brand:focus { - color: #fff; } - -.col-brown .navbar .nav > li > a:hover, -.col-brown .navbar .nav > li > a:focus, -.col-brown .navbar .nav .open > a, -.col-brown .navbar .nav .open > a:hover, -.col-brown .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-brown .navbar .nav > li > a { - color: #fff; } - -.col-brown .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-brown .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-grey .navbar .navbar-brand, -.col-grey .navbar .navbar-brand:hover, -.col-grey .navbar .navbar-brand:active, -.col-grey .navbar .navbar-brand:focus { - color: #fff; } - -.col-grey .navbar .nav > li > a:hover, -.col-grey .navbar .nav > li > a:focus, -.col-grey .navbar .nav .open > a, -.col-grey .navbar .nav .open > a:hover, -.col-grey .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-grey .navbar .nav > li > a { - color: #fff; } - -.col-grey .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-grey .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-blue-grey .navbar .navbar-brand, -.col-blue-grey .navbar .navbar-brand:hover, -.col-blue-grey .navbar .navbar-brand:active, -.col-blue-grey .navbar .navbar-brand:focus { - color: #fff; } - -.col-blue-grey .navbar .nav > li > a:hover, -.col-blue-grey .navbar .nav > li > a:focus, -.col-blue-grey .navbar .nav .open > a, -.col-blue-grey .navbar .nav .open > a:hover, -.col-blue-grey .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-blue-grey .navbar .nav > li > a { - color: #fff; } - -.col-blue-grey .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-blue-grey .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-black .navbar .navbar-brand, -.col-black .navbar .navbar-brand:hover, -.col-black .navbar .navbar-brand:active, -.col-black .navbar .navbar-brand:focus { - color: #fff; } - -.col-black .navbar .nav > li > a:hover, -.col-black .navbar .nav > li > a:focus, -.col-black .navbar .nav .open > a, -.col-black .navbar .nav .open > a:hover, -.col-black .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-black .navbar .nav > li > a { - color: #fff; } - -.col-black .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-black .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-white .navbar .navbar-brand, -.col-white .navbar .navbar-brand:hover, -.col-white .navbar .navbar-brand:active, -.col-white .navbar .navbar-brand:focus { - color: #fff; } - -.col-white .navbar .nav > li > a:hover, -.col-white .navbar .nav > li > a:focus, -.col-white .navbar .nav .open > a, -.col-white .navbar .nav .open > a:hover, -.col-white .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-white .navbar .nav > li > a { - color: #fff; } - -.col-white .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-white .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -/* Material Icons ============================== */ -.material-icons.md-18 { - font-size: 18px; } - -.material-icons.md-24 { - font-size: 24px; } - -.material-icons.md-26 { - font-size: 26px; } - -.material-icons.md-28 { - font-size: 28px; } - -.material-icons.md-30 { - font-size: 30px; } - -.material-icons.md-32 { - font-size: 32px; } - -.material-icons.md-36 { - font-size: 36px; } - -.material-icons.md-48 { - font-size: 48px; } - -/* Helpers ===================================== */ -.m-l--125 { - margin-left: -125px; } - -.m-t--125 { - margin-top: -125px; } - -.m-r--125 { - margin-right: -125px; } - -.m-b--125 { - margin-bottom: -125px; } - -.m-l--120 { - margin-left: -120px; } - -.m-t--120 { - margin-top: -120px; } - -.m-r--120 { - margin-right: -120px; } - -.m-b--120 { - margin-bottom: -120px; } - -.m-l--115 { - margin-left: -115px; } - -.m-t--115 { - margin-top: -115px; } - -.m-r--115 { - margin-right: -115px; } - -.m-b--115 { - margin-bottom: -115px; } - -.m-l--110 { - margin-left: -110px; } - -.m-t--110 { - margin-top: -110px; } - -.m-r--110 { - margin-right: -110px; } - -.m-b--110 { - margin-bottom: -110px; } - -.m-l--105 { - margin-left: -105px; } - -.m-t--105 { - margin-top: -105px; } - -.m-r--105 { - margin-right: -105px; } - -.m-b--105 { - margin-bottom: -105px; } - -.m-l--100 { - margin-left: -100px; } - -.m-t--100 { - margin-top: -100px; } - -.m-r--100 { - margin-right: -100px; } - -.m-b--100 { - margin-bottom: -100px; } - -.m-l--95 { - margin-left: -95px; } - -.m-t--95 { - margin-top: -95px; } - -.m-r--95 { - margin-right: -95px; } - -.m-b--95 { - margin-bottom: -95px; } - -.m-l--90 { - margin-left: -90px; } - -.m-t--90 { - margin-top: -90px; } - -.m-r--90 { - margin-right: -90px; } - -.m-b--90 { - margin-bottom: -90px; } - -.m-l--85 { - margin-left: -85px; } - -.m-t--85 { - margin-top: -85px; } - -.m-r--85 { - margin-right: -85px; } - -.m-b--85 { - margin-bottom: -85px; } - -.m-l--80 { - margin-left: -80px; } - -.m-t--80 { - margin-top: -80px; } - -.m-r--80 { - margin-right: -80px; } - -.m-b--80 { - margin-bottom: -80px; } - -.m-l--75 { - margin-left: -75px; } - -.m-t--75 { - margin-top: -75px; } - -.m-r--75 { - margin-right: -75px; } - -.m-b--75 { - margin-bottom: -75px; } - -.m-l--70 { - margin-left: -70px; } - -.m-t--70 { - margin-top: -70px; } - -.m-r--70 { - margin-right: -70px; } - -.m-b--70 { - margin-bottom: -70px; } - -.m-l--65 { - margin-left: -65px; } - -.m-t--65 { - margin-top: -65px; } - -.m-r--65 { - margin-right: -65px; } - -.m-b--65 { - margin-bottom: -65px; } - -.m-l--60 { - margin-left: -60px; } - -.m-t--60 { - margin-top: -60px; } - -.m-r--60 { - margin-right: -60px; } - -.m-b--60 { - margin-bottom: -60px; } - -.m-l--55 { - margin-left: -55px; } - -.m-t--55 { - margin-top: -55px; } - -.m-r--55 { - margin-right: -55px; } - -.m-b--55 { - margin-bottom: -55px; } - -.m-l--50 { - margin-left: -50px; } - -.m-t--50 { - margin-top: -50px; } - -.m-r--50 { - margin-right: -50px; } - -.m-b--50 { - margin-bottom: -50px; } - -.m-l--45 { - margin-left: -45px; } - -.m-t--45 { - margin-top: -45px; } - -.m-r--45 { - margin-right: -45px; } - -.m-b--45 { - margin-bottom: -45px; } - -.m-l--40 { - margin-left: -40px; } - -.m-t--40 { - margin-top: -40px; } - -.m-r--40 { - margin-right: -40px; } - -.m-b--40 { - margin-bottom: -40px; } - -.m-l--35 { - margin-left: -35px; } - -.m-t--35 { - margin-top: -35px; } - -.m-r--35 { - margin-right: -35px; } - -.m-b--35 { - margin-bottom: -35px; } - -.m-l--30 { - margin-left: -30px; } - -.m-t--30 { - margin-top: -30px; } - -.m-r--30 { - margin-right: -30px; } - -.m-b--30 { - margin-bottom: -30px; } - -.m-l--25 { - margin-left: -25px; } - -.m-t--25 { - margin-top: -25px; } - -.m-r--25 { - margin-right: -25px; } - -.m-b--25 { - margin-bottom: -25px; } - -.m-l--20 { - margin-left: -20px; } - -.m-t--20 { - margin-top: -20px; } - -.m-r--20 { - margin-right: -20px; } - -.m-b--20 { - margin-bottom: -20px; } - -.m-l--15 { - margin-left: -15px; } - -.m-t--15 { - margin-top: -15px; } - -.m-r--15 { - margin-right: -15px; } - -.m-b--15 { - margin-bottom: -15px; } - -.m-l--10 { - margin-left: -10px; } - -.m-t--10 { - margin-top: -10px; } - -.m-r--10 { - margin-right: -10px; } - -.m-b--10 { - margin-bottom: -10px; } - -.m-l--5 { - margin-left: -5px; } - -.m-t--5 { - margin-top: -5px; } - -.m-r--5 { - margin-right: -5px; } - -.m-b--5 { - margin-bottom: -5px; } - -.m-l-0 { - margin-left: 0; } - -.m-t-0 { - margin-top: 0; } - -.m-r-0 { - margin-right: 0; } - -.m-b-0 { - margin-bottom: 0; } - -.m-l-5 { - margin-left: 5px; } - -.m-t-5 { - margin-top: 5px; } - -.m-r-5 { - margin-right: 5px; } - -.m-b-5 { - margin-bottom: 5px; } - -.m-l-10 { - margin-left: 10px; } - -.m-t-10 { - margin-top: 10px; } - -.m-r-10 { - margin-right: 10px; } - -.m-b-10 { - margin-bottom: 10px; } - -.m-l-15 { - margin-left: 15px; } - -.m-t-15 { - margin-top: 15px; } - -.m-r-15 { - margin-right: 15px; } - -.m-b-15 { - margin-bottom: 15px; } - -.m-l-20 { - margin-left: 20px; } - -.m-t-20 { - margin-top: 20px; } - -.m-r-20 { - margin-right: 20px; } - -.m-b-20 { - margin-bottom: 20px; } - -.m-l-25 { - margin-left: 25px; } - -.m-t-25 { - margin-top: 25px; } - -.m-r-25 { - margin-right: 25px; } - -.m-b-25 { - margin-bottom: 25px; } - -.m-l-30 { - margin-left: 30px; } - -.m-t-30 { - margin-top: 30px; } - -.m-r-30 { - margin-right: 30px; } - -.m-b-30 { - margin-bottom: 30px; } - -.m-l-35 { - margin-left: 35px; } - -.m-t-35 { - margin-top: 35px; } - -.m-r-35 { - margin-right: 35px; } - -.m-b-35 { - margin-bottom: 35px; } - -.m-l-40 { - margin-left: 40px; } - -.m-t-40 { - margin-top: 40px; } - -.m-r-40 { - margin-right: 40px; } - -.m-b-40 { - margin-bottom: 40px; } - -.m-l-45 { - margin-left: 45px; } - -.m-t-45 { - margin-top: 45px; } - -.m-r-45 { - margin-right: 45px; } - -.m-b-45 { - margin-bottom: 45px; } - -.m-l-50 { - margin-left: 50px; } - -.m-t-50 { - margin-top: 50px; } - -.m-r-50 { - margin-right: 50px; } - -.m-b-50 { - margin-bottom: 50px; } - -.m-l-55 { - margin-left: 55px; } - -.m-t-55 { - margin-top: 55px; } - -.m-r-55 { - margin-right: 55px; } - -.m-b-55 { - margin-bottom: 55px; } - -.m-l-60 { - margin-left: 60px; } - -.m-t-60 { - margin-top: 60px; } - -.m-r-60 { - margin-right: 60px; } - -.m-b-60 { - margin-bottom: 60px; } - -.m-l-65 { - margin-left: 65px; } - -.m-t-65 { - margin-top: 65px; } - -.m-r-65 { - margin-right: 65px; } - -.m-b-65 { - margin-bottom: 65px; } - -.m-l-70 { - margin-left: 70px; } - -.m-t-70 { - margin-top: 70px; } - -.m-r-70 { - margin-right: 70px; } - -.m-b-70 { - margin-bottom: 70px; } - -.m-l-75 { - margin-left: 75px; } - -.m-t-75 { - margin-top: 75px; } - -.m-r-75 { - margin-right: 75px; } - -.m-b-75 { - margin-bottom: 75px; } - -.m-l-80 { - margin-left: 80px; } - -.m-t-80 { - margin-top: 80px; } - -.m-r-80 { - margin-right: 80px; } - -.m-b-80 { - margin-bottom: 80px; } - -.m-l-85 { - margin-left: 85px; } - -.m-t-85 { - margin-top: 85px; } - -.m-r-85 { - margin-right: 85px; } - -.m-b-85 { - margin-bottom: 85px; } - -.m-l-90 { - margin-left: 90px; } - -.m-t-90 { - margin-top: 90px; } - -.m-r-90 { - margin-right: 90px; } - -.m-b-90 { - margin-bottom: 90px; } - -.m-l-95 { - margin-left: 95px; } - -.m-t-95 { - margin-top: 95px; } - -.m-r-95 { - margin-right: 95px; } - -.m-b-95 { - margin-bottom: 95px; } - -.m-l-100 { - margin-left: 100px; } - -.m-t-100 { - margin-top: 100px; } - -.m-r-100 { - margin-right: 100px; } - -.m-b-100 { - margin-bottom: 100px; } - -.m-l-105 { - margin-left: 105px; } - -.m-t-105 { - margin-top: 105px; } - -.m-r-105 { - margin-right: 105px; } - -.m-b-105 { - margin-bottom: 105px; } - -.m-l-110 { - margin-left: 110px; } - -.m-t-110 { - margin-top: 110px; } - -.m-r-110 { - margin-right: 110px; } - -.m-b-110 { - margin-bottom: 110px; } - -.m-l-115 { - margin-left: 115px; } - -.m-t-115 { - margin-top: 115px; } - -.m-r-115 { - margin-right: 115px; } - -.m-b-115 { - margin-bottom: 115px; } - -.m-l-120 { - margin-left: 120px; } - -.m-t-120 { - margin-top: 120px; } - -.m-r-120 { - margin-right: 120px; } - -.m-b-120 { - margin-bottom: 120px; } - -.m-l-125 { - margin-left: 125px; } - -.m-t-125 { - margin-top: 125px; } - -.m-r-125 { - margin-right: 125px; } - -.m-b-125 { - margin-bottom: 125px; } - -.margin-0 { - margin: 0; } - -.p-l-0 { - padding-left: 0; } - -.p-t-0 { - padding-top: 0; } - -.p-r-0 { - padding-right: 0; } - -.p-b-0 { - padding-bottom: 0; } - -.p-l-5 { - padding-left: 5px; } - -.p-t-5 { - padding-top: 5px; } - -.p-r-5 { - padding-right: 5px; } - -.p-b-5 { - padding-bottom: 5px; } - -.p-l-10 { - padding-left: 10px; } - -.p-t-10 { - padding-top: 10px; } - -.p-r-10 { - padding-right: 10px; } - -.p-b-10 { - padding-bottom: 10px; } - -.p-l-15 { - padding-left: 15px; } - -.p-t-15 { - padding-top: 15px; } - -.p-r-15 { - padding-right: 15px; } - -.p-b-15 { - padding-bottom: 15px; } - -.p-l-20 { - padding-left: 20px; } - -.p-t-20 { - padding-top: 20px; } - -.p-r-20 { - padding-right: 20px; } - -.p-b-20 { - padding-bottom: 20px; } - -.p-l-25 { - padding-left: 25px; } - -.p-t-25 { - padding-top: 25px; } - -.p-r-25 { - padding-right: 25px; } - -.p-b-25 { - padding-bottom: 25px; } - -.p-l-30 { - padding-left: 30px; } - -.p-t-30 { - padding-top: 30px; } - -.p-r-30 { - padding-right: 30px; } - -.p-b-30 { - padding-bottom: 30px; } - -.p-l-35 { - padding-left: 35px; } - -.p-t-35 { - padding-top: 35px; } - -.p-r-35 { - padding-right: 35px; } - -.p-b-35 { - padding-bottom: 35px; } - -.p-l-40 { - padding-left: 40px; } - -.p-t-40 { - padding-top: 40px; } - -.p-r-40 { - padding-right: 40px; } - -.p-b-40 { - padding-bottom: 40px; } - -.p-l-45 { - padding-left: 45px; } - -.p-t-45 { - padding-top: 45px; } - -.p-r-45 { - padding-right: 45px; } - -.p-b-45 { - padding-bottom: 45px; } - -.p-l-50 { - padding-left: 50px; } - -.p-t-50 { - padding-top: 50px; } - -.p-r-50 { - padding-right: 50px; } - -.p-b-50 { - padding-bottom: 50px; } - -.p-l-55 { - padding-left: 55px; } - -.p-t-55 { - padding-top: 55px; } - -.p-r-55 { - padding-right: 55px; } - -.p-b-55 { - padding-bottom: 55px; } - -.p-l-60 { - padding-left: 60px; } - -.p-t-60 { - padding-top: 60px; } - -.p-r-60 { - padding-right: 60px; } - -.p-b-60 { - padding-bottom: 60px; } - -.p-l-65 { - padding-left: 65px; } - -.p-t-65 { - padding-top: 65px; } - -.p-r-65 { - padding-right: 65px; } - -.p-b-65 { - padding-bottom: 65px; } - -.p-l-70 { - padding-left: 70px; } - -.p-t-70 { - padding-top: 70px; } - -.p-r-70 { - padding-right: 70px; } - -.p-b-70 { - padding-bottom: 70px; } - -.p-l-75 { - padding-left: 75px; } - -.p-t-75 { - padding-top: 75px; } - -.p-r-75 { - padding-right: 75px; } - -.p-b-75 { - padding-bottom: 75px; } - -.p-l-80 { - padding-left: 80px; } - -.p-t-80 { - padding-top: 80px; } - -.p-r-80 { - padding-right: 80px; } - -.p-b-80 { - padding-bottom: 80px; } - -.p-l-85 { - padding-left: 85px; } - -.p-t-85 { - padding-top: 85px; } - -.p-r-85 { - padding-right: 85px; } - -.p-b-85 { - padding-bottom: 85px; } - -.p-l-90 { - padding-left: 90px; } - -.p-t-90 { - padding-top: 90px; } - -.p-r-90 { - padding-right: 90px; } - -.p-b-90 { - padding-bottom: 90px; } - -.p-l-95 { - padding-left: 95px; } - -.p-t-95 { - padding-top: 95px; } - -.p-r-95 { - padding-right: 95px; } - -.p-b-95 { - padding-bottom: 95px; } - -.p-l-100 { - padding-left: 100px; } - -.p-t-100 { - padding-top: 100px; } - -.p-r-100 { - padding-right: 100px; } - -.p-b-100 { - padding-bottom: 100px; } - -.p-l-105 { - padding-left: 105px; } - -.p-t-105 { - padding-top: 105px; } - -.p-r-105 { - padding-right: 105px; } - -.p-b-105 { - padding-bottom: 105px; } - -.p-l-110 { - padding-left: 110px; } - -.p-t-110 { - padding-top: 110px; } - -.p-r-110 { - padding-right: 110px; } - -.p-b-110 { - padding-bottom: 110px; } - -.p-l-115 { - padding-left: 115px; } - -.p-t-115 { - padding-top: 115px; } - -.p-r-115 { - padding-right: 115px; } - -.p-b-115 { - padding-bottom: 115px; } - -.p-l-120 { - padding-left: 120px; } - -.p-t-120 { - padding-top: 120px; } - -.p-r-120 { - padding-right: 120px; } - -.p-b-120 { - padding-bottom: 120px; } - -.p-l-125 { - padding-left: 125px; } - -.p-t-125 { - padding-top: 125px; } - -.p-r-125 { - padding-right: 125px; } - -.p-b-125 { - padding-bottom: 125px; } - -.padding-0 { - padding: 0; } - -.font-6 { - font-size: 6px; } - -.font-7 { - font-size: 7px; } - -.font-8 { - font-size: 8px; } - -.font-9 { - font-size: 9px; } - -.font-10 { - font-size: 10px; } - -.font-11 { - font-size: 11px; } - -.font-12 { - font-size: 12px; } - -.font-13 { - font-size: 13px; } - -.font-14 { - font-size: 14px; } - -.font-15 { - font-size: 15px; } - -.font-16 { - font-size: 16px; } - -.font-17 { - font-size: 17px; } - -.font-18 { - font-size: 18px; } - -.font-19 { - font-size: 19px; } - -.font-20 { - font-size: 20px; } - -.font-21 { - font-size: 21px; } - -.font-22 { - font-size: 22px; } - -.font-23 { - font-size: 23px; } - -.font-24 { - font-size: 24px; } - -.font-25 { - font-size: 25px; } - -.font-26 { - font-size: 26px; } - -.font-27 { - font-size: 27px; } - -.font-28 { - font-size: 28px; } - -.font-29 { - font-size: 29px; } - -.font-30 { - font-size: 30px; } - -.font-31 { - font-size: 31px; } - -.font-32 { - font-size: 32px; } - -.font-33 { - font-size: 33px; } - -.font-34 { - font-size: 34px; } - -.font-35 { - font-size: 35px; } - -.font-36 { - font-size: 36px; } - -.font-37 { - font-size: 37px; } - -.font-38 { - font-size: 38px; } - -.font-39 { - font-size: 39px; } - -.font-40 { - font-size: 40px; } - -.font-41 { - font-size: 41px; } - -.font-42 { - font-size: 42px; } - -.font-43 { - font-size: 43px; } - -.font-44 { - font-size: 44px; } - -.font-45 { - font-size: 45px; } - -.font-46 { - font-size: 46px; } - -.font-47 { - font-size: 47px; } - -.font-48 { - font-size: 48px; } - -.font-49 { - font-size: 49px; } - -.font-50 { - font-size: 50px; } - -.align-left { - text-align: left; } - -.align-center { - text-align: center; } - -.align-right { - text-align: right; } - -.align-justify { - text-align: justify; } - -.no-resize { - resize: none; } - -.font-bold { - font-weight: bold; } - -.font-italic { - font-style: italic; } - -.font-underline { - text-decoration: underline; } - -.font-line-through { - text-decoration: line-through; } - -.font-overline { - text-decoration: overline; } - -.block-header { - margin-bottom: 15px; } - .block-header h2 { - margin: 0 !important; - color: #666 !important; - font-weight: normal; - font-size: 16px; } - .block-header h2 small { - display: block; - font-size: 12px; - margin-top: 8px; - color: #888; } - .block-header h2 small a { - font-weight: bold; - color: #777; } - -.bg-red { - background-color: #F44336 !important; - color: #fff; } - .bg-red .content .text, - .bg-red .content .number { - color: #fff !important; } - -.bg-pink { - background-color: #E91E63 !important; - color: #fff; } - .bg-pink .content .text, - .bg-pink .content .number { - color: #fff !important; } - -.bg-purple { - background-color: #9C27B0 !important; - color: #fff; } - .bg-purple .content .text, - .bg-purple .content .number { - color: #fff !important; } - -.bg-deep-purple { - background-color: #673AB7 !important; - color: #fff; } - .bg-deep-purple .content .text, - .bg-deep-purple .content .number { - color: #fff !important; } - -.bg-indigo { - background-color: #3F51B5 !important; - color: #fff; } - .bg-indigo .content .text, - .bg-indigo .content .number { - color: #fff !important; } - -.bg-blue { - background-color: #2196F3 !important; - color: #fff; } - .bg-blue .content .text, - .bg-blue .content .number { - color: #fff !important; } - -.bg-light-blue { - background-color: #03A9F4 !important; - color: #fff; } - .bg-light-blue .content .text, - .bg-light-blue .content .number { - color: #fff !important; } - -.bg-cyan { - background-color: #00BCD4 !important; - color: #fff; } - .bg-cyan .content .text, - .bg-cyan .content .number { - color: #fff !important; } - -.bg-teal { - background-color: #009688 !important; - color: #fff; } - .bg-teal .content .text, - .bg-teal .content .number { - color: #fff !important; } - -.bg-green { - background-color: #4CAF50 !important; - color: #fff; } - .bg-green .content .text, - .bg-green .content .number { - color: #fff !important; } - -.bg-light-green { - background-color: #8BC34A !important; - color: #fff; } - .bg-light-green .content .text, - .bg-light-green .content .number { - color: #fff !important; } - -.bg-lime { - background-color: #CDDC39 !important; - color: #fff; } - .bg-lime .content .text, - .bg-lime .content .number { - color: #fff !important; } - -.bg-yellow { - background-color: #ffe821 !important; - color: #fff; } - .bg-yellow .content .text, - .bg-yellow .content .number { - color: #fff !important; } - -.bg-amber { - background-color: #FFC107 !important; - color: #fff; } - .bg-amber .content .text, - .bg-amber .content .number { - color: #fff !important; } - -.bg-orange { - background-color: #FF9800 !important; - color: #fff; } - .bg-orange .content .text, - .bg-orange .content .number { - color: #fff !important; } - -.bg-deep-orange { - background-color: #FF5722 !important; - color: #fff; } - .bg-deep-orange .content .text, - .bg-deep-orange .content .number { - color: #fff !important; } - -.bg-brown { - background-color: #795548 !important; - color: #fff; } - .bg-brown .content .text, - .bg-brown .content .number { - color: #fff !important; } - -.bg-grey { - background-color: #9E9E9E !important; - color: #fff; } - .bg-grey .content .text, - .bg-grey .content .number { - color: #fff !important; } - -.bg-blue-grey { - background-color: #607D8B !important; - color: #fff; } - .bg-blue-grey .content .text, - .bg-blue-grey .content .number { - color: #fff !important; } - -.bg-black { - background-color: #000000 !important; - color: #fff; } - .bg-black .content .text, - .bg-black .content .number { - color: #fff !important; } - -.bg-white { - background-color: #ffffff !important; - color: #fff; } - .bg-white .content .text, - .bg-white .content .number { - color: #fff !important; } - -.col-red { - color: #F44336 !important; } - -.col-pink { - color: #E91E63 !important; } - -.col-purple { - color: #9C27B0 !important; } - -.col-deep-purple { - color: #673AB7 !important; } - -.col-indigo { - color: #3F51B5 !important; } - -.col-blue { - color: #2196F3 !important; } - -.col-light-blue { - color: #03A9F4 !important; } - -.col-cyan { - color: #00BCD4 !important; } - -.col-teal { - color: #009688 !important; } - -.col-green { - color: #4CAF50 !important; } - -.col-light-green { - color: #8BC34A !important; } - -.col-lime { - color: #CDDC39 !important; } - -.col-yellow { - color: #ffe821 !important; } - -.col-amber { - color: #FFC107 !important; } - -.col-orange { - color: #FF9800 !important; } - -.col-deep-orange { - color: #FF5722 !important; } - -.col-brown { - color: #795548 !important; } - -.col-grey { - color: #9E9E9E !important; } - -.col-blue-grey { - color: #607D8B !important; } - -.col-black { - color: #000000 !important; } - -.col-white { - color: #ffffff !important; } - -/* Custom Animate ============================== */ -@-ms-keyframes spin { - from { - -ms-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); } - to { - -ms-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -o-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - transform: rotate(360deg); } } - -@-moz-keyframes spin { - from { - -moz-transform: rotate(0deg); - -ms-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); } - to { - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - transform: rotate(360deg); } } - -@-webkit-keyframes spin { - from { - -webkit-transform: rotate(0deg); - -moz-transform: rotate(0deg); - -ms-transform: rotate(0deg); - -o-transform: rotate(0deg); - transform: rotate(0deg); } - to { - -webkit-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - transform: rotate(360deg); } } - -@keyframes spin { - from { - -moz-transform: rotate(0deg); - -ms-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); } - to { - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - transform: rotate(360deg); } } - -/* Demo ======================================== */ -.demo-button-sizes .btn { - margin-bottom: 5px; } - -.icon-button-demo button { - margin-right: 5px; - margin-bottom: 12px; } - -.icon-and-text-button-demo button { - margin-right: 5px; - margin-bottom: 12px; - width: 16.66666666666667%; } - -.button-demo ul { - padding-left: 0; } - .button-demo ul li { - list-style: none; - padding-left: 0; - display: inline-block; - margin-right: 7px; } - .button-demo ul li .btn { - display: block; - min-width: 175px; } - -.button-demo .btn { - margin-right: 8px; - margin-bottom: 13px; - min-width: 120px; } - -.demo-button-groups .btn-group { - margin-right: 10px; } - -.demo-button-toolbar .btn-toolbar { - float: left; - margin-right: 25px; } - -.demo-button-nesting > .btn-group { - margin-right: 15px; } - -.demo-single-button-dropdowns > .btn-group { - margin-right: 10px; } - -.demo-splite-button-dropdowns > .btn-group { - margin-right: 10px; } - -.demo-dropup .dropup { - margin-right: 10px; } - -.demo-checkbox label, -.demo-radio-button label { - min-width: 150px; } - -.demo-knob-chart div { - margin-right: 15px; } - -.demo-switch .switch { - display: inline-block; - min-width: 170px; } - -.demo-switch .demo-switch-title { - min-width: 95px; - display: inline-block; } - -.demo-color-box { - padding: 15px 0; - text-align: center; - margin-bottom: 20px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - border-radius: 3px; } - .demo-color-box .color-name { - font-size: 16px; - margin-bottom: 5px; } - .demo-color-box .color-code, - .demo-color-box .color-class-name { - font-size: 13px; } - -.demo-image-copyright { - text-align: right; - font-style: italic; - font-size: 12px; - color: #777; - margin: 5px 0 10px 0; } - .demo-image-copyright a { - font-weight: bold; - color: #555 !important; } - -.demo-tagsinput-area { - margin-bottom: 50px !important; } - -.demo-icon-container .demo-google-material-icon { - margin-bottom: 5px; - text-align: left; } - .demo-icon-container .demo-google-material-icon .icon-name { - position: relative; - top: -8px; - left: 7px; } - .demo-icon-container .demo-google-material-icon .material-icons { - width: 24px; } - -.demo-preloader .preloader { - margin-right: 10px; } - -.irs-demo { - margin-bottom: 40px; } - .irs-demo .irs { - margin-top: 15px; } - -.right-sidebar .nav-tabs + .tab-content { - padding: 0; } - -.right-sidebar p { - margin: 20px 15px 15px 15px; - font-weight: bold; - text-align: center; } - -.right-sidebar #settings .setting-list { - list-style: none; - padding-left: 0; - margin-bottom: 20px; } - .right-sidebar #settings .setting-list li { - padding: 15px; - position: relative; - border-top: 1px solid #eee; } - .right-sidebar #settings .setting-list li .switch { - position: absolute; - top: 15px; - right: 5px; } - -.demo-choose-skin { - list-style: none; - padding-left: 0; - overflow-y: hidden; } - .demo-choose-skin li { - border-bottom: 1px solid #eee; - padding: 10px 10px 4px 10px; - position: relative; - cursor: pointer; } - .demo-choose-skin li.active { - background-color: #eee; } - .demo-choose-skin li.active:after { - font-family: 'Material Icons'; - position: absolute; - top: 10px; - right: 10px; - content: '\E876'; - font-size: 18px; - font-weight: bold; } - .demo-choose-skin li:hover { - background-color: #eee; } - .demo-choose-skin li div { - width: 24px; - height: 24px; - display: inline-block; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - border-radius: 3px; } - .demo-choose-skin li span { - position: relative; - bottom: 7px; - left: 5px; } - .demo-choose-skin .red { - background-color: #F44336; } - .demo-choose-skin .pink { - background-color: #E91E63; } - .demo-choose-skin .purple { - background-color: #9C27B0; } - .demo-choose-skin .deep-purple { - background-color: #673AB7; } - .demo-choose-skin .indigo { - background-color: #3F51B5; } - .demo-choose-skin .blue { - background-color: #2196F3; } - .demo-choose-skin .light-blue { - background-color: #03A9F4; } - .demo-choose-skin .cyan { - background-color: #00BCD4; } - .demo-choose-skin .teal { - background-color: #009688; } - .demo-choose-skin .green { - background-color: #4CAF50; } - .demo-choose-skin .light-green { - background-color: #8BC34A; } - .demo-choose-skin .lime { - background-color: #CDDC39; } - .demo-choose-skin .yellow { - background-color: #ffe821; } - .demo-choose-skin .amber { - background-color: #FFC107; } - .demo-choose-skin .orange { - background-color: #FF9800; } - .demo-choose-skin .deep-orange { - background-color: #FF5722; } - .demo-choose-skin .brown { - background-color: #795548; } - .demo-choose-skin .grey { - background-color: #9E9E9E; } - .demo-choose-skin .blue-grey { - background-color: #607D8B; } - .demo-choose-skin .black { - background-color: #000000; } - .demo-choose-skin .white { - background-color: #ffffff; } - -/* Materialize Css | Taken from www.materializecss.com */ -/* Media ======================================= */ -@media (max-width: 767px) { - .navbar > .container .navbar-brand, - .navbar > .container-fluid .navbar-brand { - margin-left: 35px; - width: 73%; } - .navbar .navbar-header { - display: inline-block; - margin-bottom: -6px; - width: calc(100% + 30px); } - .navbar .nav > li { - display: inline-block; } - .navbar .navbar-nav { - margin-top: -10px; - margin-bottom: 1px; - margin-left: -7px; } - .navbar .navbar-nav .open .dropdown-menu { - background-color: #fff; - position: absolute; } - .navbar .dropdown-menu { - margin-left: -50px; } - .navbar .js-right-sidebar { - margin-top: 15px; } - .dt-buttons { - float: none !important; - text-align: center; - margin-bottom: 15px; } - .panel-switch-btn { - top: 12px; - right: 0 !important; } } - -@media (min-width: 768px) and (max-width: 991px) { - .navbar > .container .navbar-brand, - .navbar > .container-fluid .navbar-brand { - margin-left: 20px; } } - -@media (min-width: 992px) and (max-width: 1169px) { - .navbar > .container .navbar-brand, - .navbar > .container-fluid .navbar-brand { - margin-left: 20px; } } - -/* General ===================================== */ -body { - background-color: #e9e9e9; - -moz-transition: all 0.5s; - -o-transition: all 0.5s; - -webkit-transition: all 0.5s; - transition: all 0.5s; - font-family: 'Roboto', Arial, Tahoma, sans-serif; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-weight: bold; } - -button, -input, -select, -a { - outline: none !important; } - -.no-animate { - -o-transition-property: none !important; - -moz-transition-property: none !important; - -ms-transition-property: none !important; - -webkit-transition-property: none !important; - transition-property: none !important; - -o-transform: none !important; - -moz-transform: none !important; - -ms-transform: none !important; - -webkit-transform: none !important; - transform: none !important; - -webkit-animation: none !important; - -moz-animation: none !important; - -o-animation: none !important; - -ms-animation: none !important; - animation: none !important; } - -section.content { - margin: 100px 15px 0 235px; - -moz-transition: 0.5s; - -o-transition: 0.5s; - -webkit-transition: 0.5s; - transition: 0.5s; } - -/* Dashboard =================================== */ -.dashboard-flot-chart { - height: 400px; } - -.dashboard-donut-chart { - height: 265px; } - -.dashboard-line-chart { - height: 250px; } - -.dashboard-stat-list { - list-style: none; - padding-left: 0; - margin-top: 40px; } - .dashboard-stat-list li { - padding: 16px 0 0 0; } - .dashboard-stat-list li small { - font-size: 8px; } - -.dashboard-task-infos .progress { - height: 10px; - margin-bottom: 0; - position: relative; - top: 6px; } - -/* Buttons ===================================== */ -.btn:focus { - outline: none !important; } - -.btn-circle { - border: none; - outline: none !important; - overflow: hidden; - width: 40px; - height: 40px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - -ms-border-radius: 50%; - border-radius: 50%; } - .btn-circle i { - font-size: 18px; - position: relative; - left: -1px; } - -.btn-link { - font-weight: bold; - color: #333; - -moz-transition: 0.5s; - -o-transition: 0.5s; - -webkit-transition: 0.5s; - transition: 0.5s; } - .btn-link:active, .btn-link:focus { - text-decoration: none; - color: #333; } - .btn-link:hover { - text-decoration: none; - color: #333; - background-color: #ddd; } - -.btn-circle-lg { - border: none; - outline: none !important; - overflow: hidden; - width: 50px; - height: 50px; - -webkit-border-radius: 50% !important; - -moz-border-radius: 50% !important; - -ms-border-radius: 50% !important; - border-radius: 50% !important; } - .btn-circle-lg i { - font-size: 26px !important; - position: relative !important; - left: 0 !important; - top: 6px !important; } - -.btn:not(.btn-link):not(.btn-circle) { - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.16), 0 2px 10px rgba(0, 0, 0, 0.12); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - -ms-border-radius: 2px; - border-radius: 2px; - border: none; - font-size: 13px; - outline: none; } - .btn:not(.btn-link):not(.btn-circle):hover { - outline: none; } - .btn:not(.btn-link):not(.btn-circle) i { - font-size: 20px; - position: relative; - top: 3px; } - .btn:not(.btn-link):not(.btn-circle) span { - position: relative; - top: -2px; - margin-left: 3px; } - -.btn-warning, -.btn-warning:hover, -.btn-warning:active, -.btn-warning:focus { - background-color: #ff9600 !important; } - -.btn-danger, -.btn-danger:hover, -.btn-danger:active, -.btn-danger:focus { - background-color: #fb483a !important; } - -.btn-info, -.btn-info:hover, -.btn-info:active, -.btn-info:focus { - background-color: #00b0e4 !important; } - -.btn-success, -.btn-success:hover, -.btn-success:active, -.btn-success:focus { - background-color: #2b982b !important; } - -.btn-primary, -.btn-primary:hover, -.btn-primary:active, -.btn-primary:focus { - background-color: #1f91f3 !important; } - -.btn-default, -.btn-default:hover, -.btn-default:active, -.btn-default:focus { - background-color: #fff !important; } - -.btn-group, -.btn-group-vertical { - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.16), 0 2px 10px rgba(0, 0, 0, 0.12); } - .btn-group .btn, - .btn-group-vertical .btn { - box-shadow: none !important; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - .btn-group .btn .caret, - .btn-group-vertical .btn .caret { - position: relative; - bottom: 1px; } - .btn-group .btn-group, - .btn-group-vertical .btn-group { - box-shadow: none !important; } - .btn-group .btn + .dropdown-toggle, - .btn-group-vertical .btn + .dropdown-toggle { - border-left: 1px solid rgba(0, 0, 0, 0.08) !important; } - -/* Bootstrap Tags Input ======================== */ -.bootstrap-tagsinput { - -webkit-box-shadow: none !important; - -moz-box-shadow: none !important; - -ms-box-shadow: none !important; - box-shadow: none !important; - border: none !important; } - -/* noUISlider ================================== */ -.noUi-target { - -webkit-touch-callout: none; - -webkit-user-select: none; - -ms-touch-action: none; - touch-action: none; - -ms-user-select: none; - -moz-user-select: none; - user-select: none; - -moz-box-sizing: border-box; - box-sizing: border-box; - position: relative; - direction: ltr; } - .noUi-target * { - -webkit-touch-callout: none; - -webkit-user-select: none; - -ms-touch-action: none; - touch-action: none; - -ms-user-select: none; - -moz-user-select: none; - user-select: none; - -moz-box-sizing: border-box; - box-sizing: border-box; } - -.noUi-base { - width: 100%; - height: 100%; - position: relative; - z-index: 1; } - -.noUi-origin { - position: absolute; - right: 0; - top: 6px; - left: 0; - bottom: 0; } - -.noUi-handle { - position: relative; - z-index: 1; } - -.noUi-stacking .noUi-handle { - z-index: 10; } - -.noUi-state-tap .noUi-origin { - -webkit-transition: left 0.25s, top 0.25s; - transition: left 0.25s, top 0.25s; } - -.noUi-state-drag * { - cursor: inherit !important; } - -.noUi-base { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); } - -.noUi-horizontal { - height: 18px; } - .noUi-horizontal .noUi-handle { - width: 34px; - height: 28px; - left: -17px; - top: -6px; } - -.noUi-vertical { - width: 18px; } - .noUi-vertical .noUi-handle { - width: 28px; - height: 34px; - left: -6px; - top: -17px; } - -.noUi-background { - background: #FAFAFA; - box-shadow: inset 0 1px 1px #f0f0f0; } - -.noUi-connect { - background: #3FB8AF; - box-shadow: inset 0 0 3px rgba(51, 51, 51, 0.45); - -webkit-transition: background 450ms; - transition: background 450ms; } - -.noUi-origin { - border-radius: 2px; } - -.noUi-target { - border-radius: 4px; - border: 1px solid #D3D3D3; - box-shadow: inset 0 1px 1px #F0F0F0, 0 3px 6px -5px #BBB; } - .noUi-target.noUi-connect { - box-shadow: inset 0 0 3px rgba(51, 51, 51, 0.45), 0 3px 6px -5px #BBB; } - -.noUi-dragable { - cursor: w-resize; } - -.noUi-vertical .noUi-dragable { - cursor: n-resize; } - -.noUi-handle { - border: 1px solid #D9D9D9; - border-radius: 3px; - background: #FFF; - cursor: default; - box-shadow: inset 0 0 1px #FFF, inset 0 1px 7px #EBEBEB, 0 3px 6px -3px #BBB; } - -.noUi-active { - box-shadow: inset 0 0 1px #FFF, inset 0 1px 7px #DDD, 0 3px 6px -3px #BBB; } - -.noUi-handle:before { - content: ""; - display: block; - position: absolute; - height: 14px; - width: 1px; - background: #E8E7E6; - left: 14px; - top: 6px; } - -.noUi-handle:after { - content: ""; - display: block; - position: absolute; - height: 14px; - width: 1px; - background: #E8E7E6; - left: 14px; - top: 6px; - left: 17px; } - -.noUi-vertical .noUi-handle:before { - width: 14px; - height: 1px; - left: 6px; - top: 14px; } - -.noUi-vertical .noUi-handle:after { - width: 14px; - height: 1px; - left: 6px; - top: 14px; - top: 17px; } - -[disabled].noUi-connect, [disabled] .noUi-connect { - background: #B8B8B8; } - -[disabled].noUi-origin, [disabled] .noUi-handle { - cursor: not-allowed; } - -.noUi-target { - box-shadow: none; - border: none; } - -.noUi-base { - height: 15px; - top: -6px; } - -.noUi-background { - height: 3px; - top: 6px; - background-color: #bfbfbf; - box-shadow: none; } - -.noUi-horizontal { - height: 3px; } - -.noUi-connect { - height: 3px; - top: 6px; - background-color: #26A69A; - box-shadow: none; } - -.noUi-horizontal .noUi-handle { - width: 15px; - height: 15px; - border-radius: 50%; - box-shadow: none; - background-color: #26A69A; - border: none; - left: -5px; - top: -6px; - transition: width 0.2s cubic-bezier(0.215, 0.61, 0.355, 1), height 0.2s cubic-bezier(0.215, 0.61, 0.355, 1), left 0.2s cubic-bezier(0.215, 0.61, 0.355, 1), top 0.2s cubic-bezier(0.215, 0.61, 0.355, 1); } - -.noUi-handle:before, .noUi-handle:after { - content: none; } - -.noUi-target .noUi-active.noUi-handle { - -webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); - -ms-box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); - box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); } - -.noUi-target .range-label { - position: absolute; - height: 30px; - width: 30px; - top: -17px; - left: -2px; - background-color: #26A69A; - border-radius: 50%; - transition: border-radius 0.25s cubic-bezier(0.215, 0.61, 0.355, 1), transform 0.25s cubic-bezier(0.215, 0.61, 0.355, 1); - transform: scale(0.5) rotate(-45deg); - transform-origin: 50% 100%; } - -.noUi-target .noUi-active .range-label { - border-radius: 15px 15px 15px 0; - transform: rotate(-45deg) translate(23px, -25px); } - -.range-label span { - width: 100%; - text-align: center; - color: #fff; - font-size: 12px; - transform: rotate(45deg); - opacity: 0; - position: absolute; - top: 7px; - left: -1px; - transition: opacity 0.25s cubic-bezier(0.215, 0.61, 0.355, 1); } - -.noUi-active .range-label span { - opacity: 1; } - -/* Multi Select ================================ */ -.ms-container { - width: auto !important; } - .ms-container .ms-list { - -webkit-box-shadow: none !important; - -moz-box-shadow: none !important; - -ms-box-shadow: none !important; - box-shadow: none !important; - -webkit-border-radius: 0 !important; - -moz-border-radius: 0 !important; - -ms-border-radius: 0 !important; - border-radius: 0 !important; } - .ms-container .ms-list.ms-focus { - -webkit-box-shadow: none !important; - -moz-box-shadow: none !important; - -ms-box-shadow: none !important; - box-shadow: none !important; } - .ms-container .ms-selectable, - .ms-container .ms-selection { - min-width: 250px !important; } - .ms-container .ms-selectable li.ms-hover, - .ms-container .ms-selection li.ms-hover { - color: #000000 !important; - background-color: #e6e6e6 !important; } - .ms-container .ms-selectable li.ms-elem-selectable, - .ms-container .ms-selectable li.ms-elem-selection, - .ms-container .ms-selection li.ms-elem-selectable, - .ms-container .ms-selection li.ms-elem-selection { - padding: 9px 15px 6px 15px !important; } - .ms-container .ms-optgroup-label { - padding: 5px 0 0 8px !important; } - -/* Card ======================================== */ -.card { - background: #fff; - min-height: 50px; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - position: relative; - margin-bottom: 30px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - -ms-border-radius: 2px; - border-radius: 2px; } - .card .card-inside-title { - margin-top: 25px; - margin-bottom: 15px; - display: block; - font-size: 15px; - color: #000; } - .card .card-inside-title small { - color: #999; - display: block; - font-size: 11px; - margin-top: 5px; } - .card .card-inside-title small a { - color: #777; - font-weight: bold; } - .card .card-inside-title:first-child { - margin-top: 0; } - .card .bg-red, - .card .bg-pink, - .card .bg-purple, - .card .bg-deep-purple, - .card .bg-indigo, - .card .bg-blue, - .card .bg-light-blue, - .card .bg-cyan, - .card .bg-teal, - .card .bg-green, - .card .bg-light-green, - .card .bg-lime, - .card .bg-yellow, - .card .bg-amber, - .card .bg-orange, - .card .bg-deep-orange, - .card .bg-brown, - .card .bg-grey, - .card .bg-blue-grey, - .card .bg-black { - border-bottom: none !important; - color: #fff !important; } - .card .bg-red h2, .card .bg-red small, .card .bg-red .material-icons, - .card .bg-pink h2, - .card .bg-pink small, - .card .bg-pink .material-icons, - .card .bg-purple h2, - .card .bg-purple small, - .card .bg-purple .material-icons, - .card .bg-deep-purple h2, - .card .bg-deep-purple small, - .card .bg-deep-purple .material-icons, - .card .bg-indigo h2, - .card .bg-indigo small, - .card .bg-indigo .material-icons, - .card .bg-blue h2, - .card .bg-blue small, - .card .bg-blue .material-icons, - .card .bg-light-blue h2, - .card .bg-light-blue small, - .card .bg-light-blue .material-icons, - .card .bg-cyan h2, - .card .bg-cyan small, - .card .bg-cyan .material-icons, - .card .bg-teal h2, - .card .bg-teal small, - .card .bg-teal .material-icons, - .card .bg-green h2, - .card .bg-green small, - .card .bg-green .material-icons, - .card .bg-light-green h2, - .card .bg-light-green small, - .card .bg-light-green .material-icons, - .card .bg-lime h2, - .card .bg-lime small, - .card .bg-lime .material-icons, - .card .bg-yellow h2, - .card .bg-yellow small, - .card .bg-yellow .material-icons, - .card .bg-amber h2, - .card .bg-amber small, - .card .bg-amber .material-icons, - .card .bg-orange h2, - .card .bg-orange small, - .card .bg-orange .material-icons, - .card .bg-deep-orange h2, - .card .bg-deep-orange small, - .card .bg-deep-orange .material-icons, - .card .bg-brown h2, - .card .bg-brown small, - .card .bg-brown .material-icons, - .card .bg-grey h2, - .card .bg-grey small, - .card .bg-grey .material-icons, - .card .bg-blue-grey h2, - .card .bg-blue-grey small, - .card .bg-blue-grey .material-icons, - .card .bg-black h2, - .card .bg-black small, - .card .bg-black .material-icons { - color: #fff !important; } - .card .bg-red .badge, - .card .bg-pink .badge, - .card .bg-purple .badge, - .card .bg-deep-purple .badge, - .card .bg-indigo .badge, - .card .bg-blue .badge, - .card .bg-light-blue .badge, - .card .bg-cyan .badge, - .card .bg-teal .badge, - .card .bg-green .badge, - .card .bg-light-green .badge, - .card .bg-lime .badge, - .card .bg-yellow .badge, - .card .bg-amber .badge, - .card .bg-orange .badge, - .card .bg-deep-orange .badge, - .card .bg-brown .badge, - .card .bg-grey .badge, - .card .bg-blue-grey .badge, - .card .bg-black .badge { - background-color: #fff; - color: #555; } - .card .header { - color: #555; - padding: 20px; - position: relative; - border-bottom: 1px solid rgba(204, 204, 204, 0.35); } - .card .header .header-dropdown { - position: absolute; - top: 20px; - right: 15px; - list-style: none; } - .card .header .header-dropdown .dropdown-menu li { - display: block !important; } - .card .header .header-dropdown li { - display: inline-block; } - .card .header .header-dropdown i { - font-size: 20px; - color: #999; - -moz-transition: all 0.5s; - -o-transition: all 0.5s; - -webkit-transition: all 0.5s; - transition: all 0.5s; } - .card .header .header-dropdown i:hover { - color: #000; } - .card .header h2 { - margin: 0; - font-size: 18px; - font-weight: normal; - color: #111; } - .card .header h2 small { - display: block; - font-size: 12px; - margin-top: 5px; - color: #999; - line-height: 15px; } - .card .header h2 small a { - font-weight: bold; - color: #777; } - .card .header .col-xs-12 h2 { - margin-top: 5px; } - .card .body { - font-size: 14px; - color: #555; - padding: 20px; } - .card .body .col-xs-1, - .card .body .col-sm-1, - .card .body .col-md-1, - .card .body .col-lg-1 { - margin-bottom: 20px; } - .card .body .col-xs-2, - .card .body .col-sm-2, - .card .body .col-md-2, - .card .body .col-lg-2 { - margin-bottom: 20px; } - .card .body .col-xs-3, - .card .body .col-sm-3, - .card .body .col-md-3, - .card .body .col-lg-3 { - margin-bottom: 20px; } - .card .body .col-xs-4, - .card .body .col-sm-4, - .card .body .col-md-4, - .card .body .col-lg-4 { - margin-bottom: 20px; } - .card .body .col-xs-5, - .card .body .col-sm-5, - .card .body .col-md-5, - .card .body .col-lg-5 { - margin-bottom: 20px; } - .card .body .col-xs-6, - .card .body .col-sm-6, - .card .body .col-md-6, - .card .body .col-lg-6 { - margin-bottom: 20px; } - .card .body .col-xs-7, - .card .body .col-sm-7, - .card .body .col-md-7, - .card .body .col-lg-7 { - margin-bottom: 20px; } - .card .body .col-xs-8, - .card .body .col-sm-8, - .card .body .col-md-8, - .card .body .col-lg-8 { - margin-bottom: 20px; } - .card .body .col-xs-9, - .card .body .col-sm-9, - .card .body .col-md-9, - .card .body .col-lg-9 { - margin-bottom: 20px; } - .card .body .col-xs-10, - .card .body .col-sm-10, - .card .body .col-md-10, - .card .body .col-lg-10 { - margin-bottom: 20px; } - .card .body .col-xs-11, - .card .body .col-sm-11, - .card .body .col-md-11, - .card .body .col-lg-11 { - margin-bottom: 20px; } - .card .body .col-xs-12, - .card .body .col-sm-12, - .card .body .col-md-12, - .card .body .col-lg-12 { - margin-bottom: 20px; } - -/* Infobox ===================================== */ -.info-box { - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - height: 80px; - display: flex; - cursor: default; - background-color: #fff; - position: relative; - overflow: hidden; - margin-bottom: 30px; } - .info-box .icon { - display: inline-block; - text-align: center; - background-color: rgba(0, 0, 0, 0.12); - width: 80px; } - .info-box .icon i { - color: #fff; - font-size: 50px; - line-height: 80px; } - .info-box .icon .chart.chart-bar { - height: 100%; - line-height: 100px; } - .info-box .icon .chart.chart-bar canvas { - vertical-align: baseline !important; } - .info-box .icon .chart.chart-pie { - height: 100%; - line-height: 123px; } - .info-box .icon .chart.chart-pie canvas { - vertical-align: baseline !important; } - .info-box .icon .chart.chart-line { - height: 100%; - line-height: 115px; } - .info-box .icon .chart.chart-line canvas { - vertical-align: baseline !important; } - .info-box .content { - display: inline-block; - padding: 7px 10px; } - .info-box .content .text { - font-size: 13px; - margin-top: 11px; - color: #555; } - .info-box .content .number { - font-weight: normal; - font-size: 26px; - margin-top: -4px; - color: #555; } - -.info-box.hover-zoom-effect .icon { - overflow: hidden; } - .info-box.hover-zoom-effect .icon i { - -moz-transition: all 0.3s ease; - -o-transition: all 0.3s ease; - -webkit-transition: all 0.3s ease; - transition: all 0.3s ease; } - -.info-box.hover-zoom-effect:hover .icon i { - opacity: 0.4; - -moz-transform: rotate(-32deg) scale(1.4); - -ms-transform: rotate(-32deg) scale(1.4); - -o-transform: rotate(-32deg) scale(1.4); - -webkit-transform: rotate(-32deg) scale(1.4); - transform: rotate(-32deg) scale(1.4); } - -.info-box.hover-expand-effect:after { - background-color: rgba(0, 0, 0, 0.05); - content: "."; - position: absolute; - left: 80px; - top: 0; - width: 0; - height: 100%; - color: transparent; - -moz-transition: all 0.95s; - -o-transition: all 0.95s; - -webkit-transition: all 0.95s; - transition: all 0.95s; } - -.info-box.hover-expand-effect:hover:after { - width: 100%; } - -.info-box-2 { - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - height: 80px; - display: flex; - cursor: default; - background-color: #fff; - position: relative; - overflow: hidden; - margin-bottom: 30px; } - .info-box-2 .icon { - display: inline-block; - text-align: center; - width: 80px; } - .info-box-2 .icon i { - color: #fff; - font-size: 50px; - line-height: 80px; } - .info-box-2 .chart.chart-bar { - height: 100%; - line-height: 105px; } - .info-box-2 .chart.chart-bar canvas { - vertical-align: baseline !important; } - .info-box-2 .chart.chart-pie { - height: 100%; - line-height: 123px; } - .info-box-2 .chart.chart-pie canvas { - vertical-align: baseline !important; } - .info-box-2 .chart.chart-line { - height: 100%; - line-height: 115px; } - .info-box-2 .chart.chart-line canvas { - vertical-align: baseline !important; } - .info-box-2 .content { - display: inline-block; - padding: 7px 10px; } - .info-box-2 .content .text { - font-size: 13px; - margin-top: 11px; - color: #555; } - .info-box-2 .content .number { - font-weight: normal; - font-size: 26px; - margin-top: -4px; - color: #555; } - -.info-box-2.hover-zoom-effect .icon { - overflow: hidden; } - .info-box-2.hover-zoom-effect .icon i { - -moz-transition: all 0.3s ease; - -o-transition: all 0.3s ease; - -webkit-transition: all 0.3s ease; - transition: all 0.3s ease; } - -.info-box-2.hover-zoom-effect:hover .icon i { - opacity: 0.4; - -moz-transform: rotate(-32deg) scale(1.4); - -ms-transform: rotate(-32deg) scale(1.4); - -o-transform: rotate(-32deg) scale(1.4); - -webkit-transform: rotate(-32deg) scale(1.4); - transform: rotate(-32deg) scale(1.4); } - -.info-box-2.hover-expand-effect:after { - background-color: rgba(0, 0, 0, 0.05); - content: "."; - position: absolute; - left: 0; - top: 0; - width: 0; - height: 100%; - color: transparent; - -moz-transition: all 0.95s; - -o-transition: all 0.95s; - -webkit-transition: all 0.95s; - transition: all 0.95s; } - -.info-box-2.hover-expand-effect:hover:after { - width: 100%; } - -.info-box-3 { - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - height: 80px; - display: flex; - cursor: default; - background-color: #fff; - position: relative; - overflow: hidden; - margin-bottom: 30px; } - .info-box-3 .icon { - position: absolute; - right: 10px; - bottom: 2px; - text-align: center; } - .info-box-3 .icon i { - color: rgba(0, 0, 0, 0.15); - font-size: 60px; } - .info-box-3 .chart { - margin-right: 5px; } - .info-box-3 .chart.chart-bar { - height: 100%; - line-height: 50px; } - .info-box-3 .chart.chart-bar canvas { - vertical-align: baseline !important; } - .info-box-3 .chart.chart-pie { - height: 100%; - line-height: 34px; } - .info-box-3 .chart.chart-pie canvas { - vertical-align: baseline !important; } - .info-box-3 .chart.chart-line { - height: 100%; - line-height: 40px; } - .info-box-3 .chart.chart-line canvas { - vertical-align: baseline !important; } - .info-box-3 .content { - display: inline-block; - padding: 7px 16px; } - .info-box-3 .content .text { - font-size: 13px; - margin-top: 11px; - color: #555; } - .info-box-3 .content .number { - font-weight: normal; - font-size: 26px; - margin-top: -4px; - color: #555; } - -.info-box-3.hover-zoom-effect .icon i { - -moz-transition: all 0.3s ease; - -o-transition: all 0.3s ease; - -webkit-transition: all 0.3s ease; - transition: all 0.3s ease; } - -.info-box-3.hover-zoom-effect:hover .icon i { - opacity: 0.4; - -moz-transform: rotate(-32deg) scale(1.4); - -ms-transform: rotate(-32deg) scale(1.4); - -o-transform: rotate(-32deg) scale(1.4); - -webkit-transform: rotate(-32deg) scale(1.4); - transform: rotate(-32deg) scale(1.4); } - -.info-box-3.hover-expand-effect:after { - background-color: rgba(0, 0, 0, 0.05); - content: "."; - position: absolute; - left: 0; - top: 0; - width: 0; - height: 100%; - color: transparent; - -moz-transition: all 0.95s; - -o-transition: all 0.95s; - -webkit-transition: all 0.95s; - transition: all 0.95s; } - -.info-box-3.hover-expand-effect:hover:after { - width: 100%; } - -.info-box-4 { - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - height: 80px; - display: flex; - cursor: default; - background-color: #fff; - position: relative; - overflow: hidden; - margin-bottom: 30px; } - .info-box-4 .icon { - position: absolute; - right: 10px; - bottom: 2px; - text-align: center; } - .info-box-4 .icon i { - color: rgba(0, 0, 0, 0.15); - font-size: 60px; } - .info-box-4 .chart { - margin-right: 5px; } - .info-box-4 .chart.chart-bar { - height: 100%; - line-height: 50px; } - .info-box-4 .chart.chart-bar canvas { - vertical-align: baseline !important; } - .info-box-4 .chart.chart-pie { - height: 100%; - line-height: 34px; } - .info-box-4 .chart.chart-pie canvas { - vertical-align: baseline !important; } - .info-box-4 .chart.chart-line { - height: 100%; - line-height: 40px; } - .info-box-4 .chart.chart-line canvas { - vertical-align: baseline !important; } - .info-box-4 .content { - display: inline-block; - padding: 7px 16px; } - .info-box-4 .content .text { - font-size: 13px; - margin-top: 11px; - color: #555; } - .info-box-4 .content .number { - font-weight: normal; - font-size: 26px; - margin-top: -4px; - color: #555; } - -.info-box-4.hover-zoom-effect .icon i { - -moz-transition: all 0.3s ease; - -o-transition: all 0.3s ease; - -webkit-transition: all 0.3s ease; - transition: all 0.3s ease; } - -.info-box-4.hover-zoom-effect:hover .icon i { - opacity: 0.4; - -moz-transform: rotate(-32deg) scale(1.4); - -ms-transform: rotate(-32deg) scale(1.4); - -o-transform: rotate(-32deg) scale(1.4); - -webkit-transform: rotate(-32deg) scale(1.4); - transform: rotate(-32deg) scale(1.4); } - -.info-box-4.hover-expand-effect:after { - background-color: rgba(0, 0, 0, 0.05); - content: "."; - position: absolute; - left: 0; - top: 0; - width: 0; - height: 100%; - color: transparent; - -moz-transition: all 0.95s; - -o-transition: all 0.95s; - -webkit-transition: all 0.95s; - transition: all 0.95s; } - -.info-box-4.hover-expand-effect:hover:after { - width: 100%; } - -/* Alerts ====================================== */ -.alert { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - -ms-box-shadow: none; - box-shadow: none; - border: none; - color: #fff !important; } - .alert .alert-link { - color: #fff; - text-decoration: underline; - font-weight: bold; } - -.alert-success { - background-color: #2b982b; } - -.alert-info { - background-color: #00b0e4; } - -.alert-warning { - background-color: #ff9600 !important; } - -.alert-danger { - background-color: #fb483a !important; } - -.alert-dismissible .close { - color: #fff; - opacity: 1; - border: none; - text-shadow: none; } - -/* Dialogs (SweetAlert) ======================== */ -.sweet-alert { - -webkit-border-radius: 0 !important; - -moz-border-radius: 0 !important; - -ms-border-radius: 0 !important; - border-radius: 0 !important; } - .sweet-alert p { - font-size: 14px !important; } - .sweet-alert .sa-input-error { - top: 23px !important; - right: 13px !important; } - .sweet-alert h2 { - font-size: 18px !important; - margin: 0 0 5px 0 !important; } - .sweet-alert button { - font-size: 15px !important; - -webkit-border-radius: 0 !important; - -moz-border-radius: 0 !important; - -ms-border-radius: 0 !important; - border-radius: 0 !important; - padding: 5px 20px !important; } - -/* Checkbox & Radio ============================ */ -[type="checkbox"] + label { - padding-left: 26px; - height: 25px; - line-height: 21px; - font-size: 13px; - font-weight: normal; } - -[type="checkbox"]:checked + label:before { - top: -4px; - left: -2px; - width: 11px; - height: 19px; } - -[type="checkbox"]:checked.chk-col-red + label:before { - border-right: 2px solid #F44336; - border-bottom: 2px solid #F44336; } - -[type="checkbox"]:checked.chk-col-pink + label:before { - border-right: 2px solid #E91E63; - border-bottom: 2px solid #E91E63; } - -[type="checkbox"]:checked.chk-col-purple + label:before { - border-right: 2px solid #9C27B0; - border-bottom: 2px solid #9C27B0; } - -[type="checkbox"]:checked.chk-col-deep-purple + label:before { - border-right: 2px solid #673AB7; - border-bottom: 2px solid #673AB7; } - -[type="checkbox"]:checked.chk-col-indigo + label:before { - border-right: 2px solid #3F51B5; - border-bottom: 2px solid #3F51B5; } - -[type="checkbox"]:checked.chk-col-blue + label:before { - border-right: 2px solid #2196F3; - border-bottom: 2px solid #2196F3; } - -[type="checkbox"]:checked.chk-col-light-blue + label:before { - border-right: 2px solid #03A9F4; - border-bottom: 2px solid #03A9F4; } - -[type="checkbox"]:checked.chk-col-cyan + label:before { - border-right: 2px solid #00BCD4; - border-bottom: 2px solid #00BCD4; } - -[type="checkbox"]:checked.chk-col-teal + label:before { - border-right: 2px solid #009688; - border-bottom: 2px solid #009688; } - -[type="checkbox"]:checked.chk-col-green + label:before { - border-right: 2px solid #4CAF50; - border-bottom: 2px solid #4CAF50; } - -[type="checkbox"]:checked.chk-col-light-green + label:before { - border-right: 2px solid #8BC34A; - border-bottom: 2px solid #8BC34A; } - -[type="checkbox"]:checked.chk-col-lime + label:before { - border-right: 2px solid #CDDC39; - border-bottom: 2px solid #CDDC39; } - -[type="checkbox"]:checked.chk-col-yellow + label:before { - border-right: 2px solid #ffe821; - border-bottom: 2px solid #ffe821; } - -[type="checkbox"]:checked.chk-col-amber + label:before { - border-right: 2px solid #FFC107; - border-bottom: 2px solid #FFC107; } - -[type="checkbox"]:checked.chk-col-orange + label:before { - border-right: 2px solid #FF9800; - border-bottom: 2px solid #FF9800; } - -[type="checkbox"]:checked.chk-col-deep-orange + label:before { - border-right: 2px solid #FF5722; - border-bottom: 2px solid #FF5722; } - -[type="checkbox"]:checked.chk-col-brown + label:before { - border-right: 2px solid #795548; - border-bottom: 2px solid #795548; } - -[type="checkbox"]:checked.chk-col-grey + label:before { - border-right: 2px solid #9E9E9E; - border-bottom: 2px solid #9E9E9E; } - -[type="checkbox"]:checked.chk-col-blue-grey + label:before { - border-right: 2px solid #607D8B; - border-bottom: 2px solid #607D8B; } - -[type="checkbox"]:checked.chk-col-black + label:before { - border-right: 2px solid #000000; - border-bottom: 2px solid #000000; } - -[type="checkbox"]:checked.chk-col-white + label:before { - border-right: 2px solid #ffffff; - border-bottom: 2px solid #ffffff; } - -[type="checkbox"].filled-in:checked + label:after { - top: 0; - width: 20px; - height: 20px; - border: 2px solid #26a69a; - background-color: #26a69a; - z-index: 0; } - -[type="checkbox"].filled-in:checked + label:before { - border-right: 2px solid #fff !important; - border-bottom: 2px solid #fff !important; } - -[type="checkbox"].filled-in:checked.chk-col-red + label:after { - border: 2px solid #F44336; - background-color: #F44336; } - -[type="checkbox"].filled-in:checked.chk-col-pink + label:after { - border: 2px solid #E91E63; - background-color: #E91E63; } - -[type="checkbox"].filled-in:checked.chk-col-purple + label:after { - border: 2px solid #9C27B0; - background-color: #9C27B0; } - -[type="checkbox"].filled-in:checked.chk-col-deep-purple + label:after { - border: 2px solid #673AB7; - background-color: #673AB7; } - -[type="checkbox"].filled-in:checked.chk-col-indigo + label:after { - border: 2px solid #3F51B5; - background-color: #3F51B5; } - -[type="checkbox"].filled-in:checked.chk-col-blue + label:after { - border: 2px solid #2196F3; - background-color: #2196F3; } - -[type="checkbox"].filled-in:checked.chk-col-light-blue + label:after { - border: 2px solid #03A9F4; - background-color: #03A9F4; } - -[type="checkbox"].filled-in:checked.chk-col-cyan + label:after { - border: 2px solid #00BCD4; - background-color: #00BCD4; } - -[type="checkbox"].filled-in:checked.chk-col-teal + label:after { - border: 2px solid #009688; - background-color: #009688; } - -[type="checkbox"].filled-in:checked.chk-col-green + label:after { - border: 2px solid #4CAF50; - background-color: #4CAF50; } - -[type="checkbox"].filled-in:checked.chk-col-light-green + label:after { - border: 2px solid #8BC34A; - background-color: #8BC34A; } - -[type="checkbox"].filled-in:checked.chk-col-lime + label:after { - border: 2px solid #CDDC39; - background-color: #CDDC39; } - -[type="checkbox"].filled-in:checked.chk-col-yellow + label:after { - border: 2px solid #ffe821; - background-color: #ffe821; } - -[type="checkbox"].filled-in:checked.chk-col-amber + label:after { - border: 2px solid #FFC107; - background-color: #FFC107; } - -[type="checkbox"].filled-in:checked.chk-col-orange + label:after { - border: 2px solid #FF9800; - background-color: #FF9800; } - -[type="checkbox"].filled-in:checked.chk-col-deep-orange + label:after { - border: 2px solid #FF5722; - background-color: #FF5722; } - -[type="checkbox"].filled-in:checked.chk-col-brown + label:after { - border: 2px solid #795548; - background-color: #795548; } - -[type="checkbox"].filled-in:checked.chk-col-grey + label:after { - border: 2px solid #9E9E9E; - background-color: #9E9E9E; } - -[type="checkbox"].filled-in:checked.chk-col-blue-grey + label:after { - border: 2px solid #607D8B; - background-color: #607D8B; } - -[type="checkbox"].filled-in:checked.chk-col-black + label:after { - border: 2px solid #000000; - background-color: #000000; } - -[type="checkbox"].filled-in:checked.chk-col-white + label:after { - border: 2px solid #ffffff; - background-color: #ffffff; } - -[type="radio"]:not(:checked) + label { - padding-left: 26px; - height: 25px; - line-height: 25px; - font-size: 13px; - font-weight: normal; } - -[type="radio"]:checked + label { - padding-left: 26px; - height: 25px; - line-height: 25px; - font-size: 13px; - font-weight: normal; } - -[type="radio"].radio-col-red:checked + label:after { - background-color: #F44336; - border-color: #F44336; } - -[type="radio"].radio-col-pink:checked + label:after { - background-color: #E91E63; - border-color: #E91E63; } - -[type="radio"].radio-col-purple:checked + label:after { - background-color: #9C27B0; - border-color: #9C27B0; } - -[type="radio"].radio-col-deep-purple:checked + label:after { - background-color: #673AB7; - border-color: #673AB7; } - -[type="radio"].radio-col-indigo:checked + label:after { - background-color: #3F51B5; - border-color: #3F51B5; } - -[type="radio"].radio-col-blue:checked + label:after { - background-color: #2196F3; - border-color: #2196F3; } - -[type="radio"].radio-col-light-blue:checked + label:after { - background-color: #03A9F4; - border-color: #03A9F4; } - -[type="radio"].radio-col-cyan:checked + label:after { - background-color: #00BCD4; - border-color: #00BCD4; } - -[type="radio"].radio-col-teal:checked + label:after { - background-color: #009688; - border-color: #009688; } - -[type="radio"].radio-col-green:checked + label:after { - background-color: #4CAF50; - border-color: #4CAF50; } - -[type="radio"].radio-col-light-green:checked + label:after { - background-color: #8BC34A; - border-color: #8BC34A; } - -[type="radio"].radio-col-lime:checked + label:after { - background-color: #CDDC39; - border-color: #CDDC39; } - -[type="radio"].radio-col-yellow:checked + label:after { - background-color: #ffe821; - border-color: #ffe821; } - -[type="radio"].radio-col-amber:checked + label:after { - background-color: #FFC107; - border-color: #FFC107; } - -[type="radio"].radio-col-orange:checked + label:after { - background-color: #FF9800; - border-color: #FF9800; } - -[type="radio"].radio-col-deep-orange:checked + label:after { - background-color: #FF5722; - border-color: #FF5722; } - -[type="radio"].radio-col-brown:checked + label:after { - background-color: #795548; - border-color: #795548; } - -[type="radio"].radio-col-grey:checked + label:after { - background-color: #9E9E9E; - border-color: #9E9E9E; } - -[type="radio"].radio-col-blue-grey:checked + label:after { - background-color: #607D8B; - border-color: #607D8B; } - -[type="radio"].radio-col-black:checked + label:after { - background-color: #000000; - border-color: #000000; } - -[type="radio"].radio-col-white:checked + label:after { - background-color: #ffffff; - border-color: #ffffff; } - -[type="radio"].with-gap.radio-col-red:checked + label:before { - border: 2px solid #F44336; } - -[type="radio"].with-gap.radio-col-red:checked + label:after { - background-color: #F44336; - border: 2px solid #F44336; } - -[type="radio"].with-gap.radio-col-pink:checked + label:before { - border: 2px solid #E91E63; } - -[type="radio"].with-gap.radio-col-pink:checked + label:after { - background-color: #E91E63; - border: 2px solid #E91E63; } - -[type="radio"].with-gap.radio-col-purple:checked + label:before { - border: 2px solid #9C27B0; } - -[type="radio"].with-gap.radio-col-purple:checked + label:after { - background-color: #9C27B0; - border: 2px solid #9C27B0; } - -[type="radio"].with-gap.radio-col-deep-purple:checked + label:before { - border: 2px solid #673AB7; } - -[type="radio"].with-gap.radio-col-deep-purple:checked + label:after { - background-color: #673AB7; - border: 2px solid #673AB7; } - -[type="radio"].with-gap.radio-col-indigo:checked + label:before { - border: 2px solid #3F51B5; } - -[type="radio"].with-gap.radio-col-indigo:checked + label:after { - background-color: #3F51B5; - border: 2px solid #3F51B5; } - -[type="radio"].with-gap.radio-col-blue:checked + label:before { - border: 2px solid #2196F3; } - -[type="radio"].with-gap.radio-col-blue:checked + label:after { - background-color: #2196F3; - border: 2px solid #2196F3; } - -[type="radio"].with-gap.radio-col-light-blue:checked + label:before { - border: 2px solid #03A9F4; } - -[type="radio"].with-gap.radio-col-light-blue:checked + label:after { - background-color: #03A9F4; - border: 2px solid #03A9F4; } - -[type="radio"].with-gap.radio-col-cyan:checked + label:before { - border: 2px solid #00BCD4; } - -[type="radio"].with-gap.radio-col-cyan:checked + label:after { - background-color: #00BCD4; - border: 2px solid #00BCD4; } - -[type="radio"].with-gap.radio-col-teal:checked + label:before { - border: 2px solid #009688; } - -[type="radio"].with-gap.radio-col-teal:checked + label:after { - background-color: #009688; - border: 2px solid #009688; } - -[type="radio"].with-gap.radio-col-green:checked + label:before { - border: 2px solid #4CAF50; } - -[type="radio"].with-gap.radio-col-green:checked + label:after { - background-color: #4CAF50; - border: 2px solid #4CAF50; } - -[type="radio"].with-gap.radio-col-light-green:checked + label:before { - border: 2px solid #8BC34A; } - -[type="radio"].with-gap.radio-col-light-green:checked + label:after { - background-color: #8BC34A; - border: 2px solid #8BC34A; } - -[type="radio"].with-gap.radio-col-lime:checked + label:before { - border: 2px solid #CDDC39; } - -[type="radio"].with-gap.radio-col-lime:checked + label:after { - background-color: #CDDC39; - border: 2px solid #CDDC39; } - -[type="radio"].with-gap.radio-col-yellow:checked + label:before { - border: 2px solid #ffe821; } - -[type="radio"].with-gap.radio-col-yellow:checked + label:after { - background-color: #ffe821; - border: 2px solid #ffe821; } - -[type="radio"].with-gap.radio-col-amber:checked + label:before { - border: 2px solid #FFC107; } - -[type="radio"].with-gap.radio-col-amber:checked + label:after { - background-color: #FFC107; - border: 2px solid #FFC107; } - -[type="radio"].with-gap.radio-col-orange:checked + label:before { - border: 2px solid #FF9800; } - -[type="radio"].with-gap.radio-col-orange:checked + label:after { - background-color: #FF9800; - border: 2px solid #FF9800; } - -[type="radio"].with-gap.radio-col-deep-orange:checked + label:before { - border: 2px solid #FF5722; } - -[type="radio"].with-gap.radio-col-deep-orange:checked + label:after { - background-color: #FF5722; - border: 2px solid #FF5722; } - -[type="radio"].with-gap.radio-col-brown:checked + label:before { - border: 2px solid #795548; } - -[type="radio"].with-gap.radio-col-brown:checked + label:after { - background-color: #795548; - border: 2px solid #795548; } - -[type="radio"].with-gap.radio-col-grey:checked + label:before { - border: 2px solid #9E9E9E; } - -[type="radio"].with-gap.radio-col-grey:checked + label:after { - background-color: #9E9E9E; - border: 2px solid #9E9E9E; } - -[type="radio"].with-gap.radio-col-blue-grey:checked + label:before { - border: 2px solid #607D8B; } - -[type="radio"].with-gap.radio-col-blue-grey:checked + label:after { - background-color: #607D8B; - border: 2px solid #607D8B; } - -[type="radio"].with-gap.radio-col-black:checked + label:before { - border: 2px solid #000000; } - -[type="radio"].with-gap.radio-col-black:checked + label:after { - background-color: #000000; - border: 2px solid #000000; } - -[type="radio"].with-gap.radio-col-white:checked + label:before { - border: 2px solid #ffffff; } - -[type="radio"].with-gap.radio-col-white:checked + label:after { - background-color: #ffffff; - border: 2px solid #ffffff; } - -/* Switch ====================================== */ -.switch label { - font-weight: normal; - font-size: 13px; } - .switch label .lever { - margin: 0 14px; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-red:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(244, 67, 54, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-red { - background-color: rgba(244, 67, 54, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-red:after { - background-color: #F44336; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-pink:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(233, 30, 99, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-pink { - background-color: rgba(233, 30, 99, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-pink:after { - background-color: #E91E63; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-purple:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(156, 39, 176, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-purple { - background-color: rgba(156, 39, 176, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-purple:after { - background-color: #9C27B0; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-deep-purple:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(103, 58, 183, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-deep-purple { - background-color: rgba(103, 58, 183, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-deep-purple:after { - background-color: #673AB7; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-indigo:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(63, 81, 181, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-indigo { - background-color: rgba(63, 81, 181, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-indigo:after { - background-color: #3F51B5; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-blue:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(33, 150, 243, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-blue { - background-color: rgba(33, 150, 243, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-blue:after { - background-color: #2196F3; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-light-blue:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(3, 169, 244, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-light-blue { - background-color: rgba(3, 169, 244, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-light-blue:after { - background-color: #03A9F4; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-cyan:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(0, 188, 212, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-cyan { - background-color: rgba(0, 188, 212, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-cyan:after { - background-color: #00BCD4; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-teal:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(0, 150, 136, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-teal { - background-color: rgba(0, 150, 136, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-teal:after { - background-color: #009688; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-green:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(76, 175, 80, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-green { - background-color: rgba(76, 175, 80, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-green:after { - background-color: #4CAF50; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-light-green:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(139, 195, 74, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-light-green { - background-color: rgba(139, 195, 74, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-light-green:after { - background-color: #8BC34A; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-lime:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(205, 220, 57, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-lime { - background-color: rgba(205, 220, 57, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-lime:after { - background-color: #CDDC39; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-yellow:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(255, 232, 33, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-yellow { - background-color: rgba(255, 232, 33, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-yellow:after { - background-color: #ffe821; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-amber:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(255, 193, 7, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-amber { - background-color: rgba(255, 193, 7, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-amber:after { - background-color: #FFC107; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-orange:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(255, 152, 0, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-orange { - background-color: rgba(255, 152, 0, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-orange:after { - background-color: #FF9800; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-deep-orange:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(255, 87, 34, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-deep-orange { - background-color: rgba(255, 87, 34, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-deep-orange:after { - background-color: #FF5722; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-brown:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(121, 85, 72, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-brown { - background-color: rgba(121, 85, 72, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-brown:after { - background-color: #795548; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-grey:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(158, 158, 158, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-grey { - background-color: rgba(158, 158, 158, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-grey:after { - background-color: #9E9E9E; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-blue-grey:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(96, 125, 139, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-blue-grey { - background-color: rgba(96, 125, 139, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-blue-grey:after { - background-color: #607D8B; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-black:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(0, 0, 0, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-black { - background-color: rgba(0, 0, 0, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-black:after { - background-color: #000000; } - .switch label input[type=checkbox]:checked:not(:disabled) ~ .lever.switch-col-white:active:after { - box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(255, 255, 255, 0.1); } - .switch label input[type=checkbox]:checked + .lever.switch-col-white { - background-color: rgba(255, 255, 255, 0.5); } - .switch label input[type=checkbox]:checked + .lever.switch-col-white:after { - background-color: #ffffff; } - -/* DateTime Picker ============================= */ -.dtp div.dtp-date, -.dtp div.dtp-time { - background: #007d72; } - -.dtp > .dtp-content > .dtp-date-view > header.dtp-header { - background: #009688; } - -.dtp .dtp-buttons .dtp-btn-ok { - margin-left: 10px; } - -.dtp .dtp-buttons .dtp-btn-clear { - margin-right: 10px !important; } - -.dtp .p10 > a { - color: #fff; } - -.dtp div.dtp-actual-year { - font-size: 1.5em; - color: #ffffff; } - -.dtp table.dtp-picker-days tr td a.selected { - background: #007d72; - color: #fff; } - -/* Bootstrap Select ============================ */ -.bootstrap-select { - box-shadow: none !important; - border-bottom: 1px solid #ddd !important; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - .bootstrap-select .dropdown-toggle:focus, .bootstrap-select .dropdown-toggle:active { - outline: none !important; } - .bootstrap-select .bs-searchbox, - .bootstrap-select .bs-actionsbox, - .bootstrap-select .bs-donebutton { - padding: 0 0 5px 0; - border-bottom: 1px solid #e9e9e9; } - .bootstrap-select .bs-searchbox .form-control, - .bootstrap-select .bs-actionsbox .form-control, - .bootstrap-select .bs-donebutton .form-control { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none !important; - -moz-box-shadow: none !important; - -ms-box-shadow: none !important; - box-shadow: none !important; - border: none; - margin-left: 30px; } - .bootstrap-select .bs-searchbox { - position: relative; } - .bootstrap-select .bs-searchbox:after { - content: '\E8B6'; - font-family: 'Material Icons'; - position: absolute; - top: 0; - left: 10px; - font-size: 25px; } - .bootstrap-select ul.dropdown-menu { - margin-top: 0 !important; } - .bootstrap-select .dropdown-menu li.selected a { - background-color: #eee !important; - color: #555 !important; } - .bootstrap-select .dropdown-menu .active a { - background-color: transparent; - color: #333 !important; } - .bootstrap-select .dropdown-menu .notify { - background-color: #F44336 !important; - color: #fff !important; - border: none !important; } - -.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark { - margin-top: 9px; } - -/* Tooltip & Popovers ========================== */ -.tooltip { - font-size: 13px; } - .tooltip .tooltip-inner { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - -.popover { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - border: 1px solid rgba(0, 0, 0, 0.08); } - .popover .popover-title { - font-weight: bold; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - background-color: #e9e9e9; - border-bottom: 1px solid #ddd; } - .popover .popover-content { - font-size: 13px; - color: #777; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - -/* Nav Tabs ==================================== */ -.nav-tabs { - border-bottom: 2px solid #eee; } - .nav-tabs > li { - position: relative; - top: 3px; - left: -2px; } - .nav-tabs > li > a { - border: none !important; - color: #999 !important; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - .nav-tabs > li > a:hover, .nav-tabs > li > a:active, .nav-tabs > li > a:focus { - background-color: transparent !important; } - .nav-tabs > li > a:before { - content: ''; - position: absolute; - left: 0; - width: 100%; - height: 0; - border-bottom: 2px solid #2196F3; - bottom: 2px; - -moz-transform: scaleX(0); - -ms-transform: scaleX(0); - -o-transform: scaleX(0); - -webkit-transform: scaleX(0); - transform: scaleX(0); - -moz-transition: 0.1s ease-in; - -o-transition: 0.1s ease-in; - -webkit-transition: 0.1s ease-in; - transition: 0.1s ease-in; } - .nav-tabs > li > a .material-icons { - position: relative; - top: 7px; - margin-bottom: 8px; } - .nav-tabs li.active a { - color: #222 !important; } - .nav-tabs li.active a:hover, .nav-tabs li.active a:active, .nav-tabs li.active a:focus { - background-color: transparent !important; } - .nav-tabs li.active a:before { - -moz-transform: scaleX(1); - -ms-transform: scaleX(1); - -o-transform: scaleX(1); - -webkit-transform: scaleX(1); - transform: scaleX(1); } - .nav-tabs + .tab-content { - padding: 15px 0; } - -.nav-tabs.tab-col-red > li > a:before { - border-bottom: 2px solid #F44336; } - -.nav-tabs.tab-col-pink > li > a:before { - border-bottom: 2px solid #E91E63; } - -.nav-tabs.tab-col-purple > li > a:before { - border-bottom: 2px solid #9C27B0; } - -.nav-tabs.tab-col-deep-purple > li > a:before { - border-bottom: 2px solid #673AB7; } - -.nav-tabs.tab-col-indigo > li > a:before { - border-bottom: 2px solid #3F51B5; } - -.nav-tabs.tab-col-blue > li > a:before { - border-bottom: 2px solid #2196F3; } - -.nav-tabs.tab-col-light-blue > li > a:before { - border-bottom: 2px solid #03A9F4; } - -.nav-tabs.tab-col-cyan > li > a:before { - border-bottom: 2px solid #00BCD4; } - -.nav-tabs.tab-col-teal > li > a:before { - border-bottom: 2px solid #009688; } - -.nav-tabs.tab-col-green > li > a:before { - border-bottom: 2px solid #4CAF50; } - -.nav-tabs.tab-col-light-green > li > a:before { - border-bottom: 2px solid #8BC34A; } - -.nav-tabs.tab-col-lime > li > a:before { - border-bottom: 2px solid #CDDC39; } - -.nav-tabs.tab-col-yellow > li > a:before { - border-bottom: 2px solid #ffe821; } - -.nav-tabs.tab-col-amber > li > a:before { - border-bottom: 2px solid #FFC107; } - -.nav-tabs.tab-col-orange > li > a:before { - border-bottom: 2px solid #FF9800; } - -.nav-tabs.tab-col-deep-orange > li > a:before { - border-bottom: 2px solid #FF5722; } - -.nav-tabs.tab-col-brown > li > a:before { - border-bottom: 2px solid #795548; } - -.nav-tabs.tab-col-grey > li > a:before { - border-bottom: 2px solid #9E9E9E; } - -.nav-tabs.tab-col-blue-grey > li > a:before { - border-bottom: 2px solid #607D8B; } - -.nav-tabs.tab-col-black > li > a:before { - border-bottom: 2px solid #000000; } - -.nav-tabs.tab-col-white > li > a:before { - border-bottom: 2px solid #ffffff; } - -/* Thumbnails ================================== */ -.thumbnail { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - .thumbnail p:not(button) { - color: #999999; - font-size: 14px; } - .thumbnail h3 { - font-weight: bold; - font-size: 17px; } - -/* Modals ====================================== */ -.modal .modal-header { - border: none; - padding: 25px 25px 5px 25px; } - .modal .modal-header .modal-title { - font-weight: bold; - font-size: 16px; } - -.modal .modal-content { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - box-shadow: 0 5px 20px rgba(0, 0, 0, 0.31) !important; - border: none; } - .modal .modal-content .modal-body { - color: #777; - padding: 15px 25px; } - -.modal .modal-footer { - border: none; } - -.modal-col-red { - background-color: #F44336; } - .modal-col-red .modal-body, - .modal-col-red .modal-title { - color: #fff !important; } - .modal-col-red .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-red .modal-footer .btn-link { - color: #fff !important; } - .modal-col-red .modal-footer .btn-link:hover, .modal-col-red .modal-footer .btn-link:active, .modal-col-red .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-pink { - background-color: #E91E63; } - .modal-col-pink .modal-body, - .modal-col-pink .modal-title { - color: #fff !important; } - .modal-col-pink .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-pink .modal-footer .btn-link { - color: #fff !important; } - .modal-col-pink .modal-footer .btn-link:hover, .modal-col-pink .modal-footer .btn-link:active, .modal-col-pink .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-purple { - background-color: #9C27B0; } - .modal-col-purple .modal-body, - .modal-col-purple .modal-title { - color: #fff !important; } - .modal-col-purple .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-purple .modal-footer .btn-link { - color: #fff !important; } - .modal-col-purple .modal-footer .btn-link:hover, .modal-col-purple .modal-footer .btn-link:active, .modal-col-purple .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-deep-purple { - background-color: #673AB7; } - .modal-col-deep-purple .modal-body, - .modal-col-deep-purple .modal-title { - color: #fff !important; } - .modal-col-deep-purple .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-deep-purple .modal-footer .btn-link { - color: #fff !important; } - .modal-col-deep-purple .modal-footer .btn-link:hover, .modal-col-deep-purple .modal-footer .btn-link:active, .modal-col-deep-purple .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-indigo { - background-color: #3F51B5; } - .modal-col-indigo .modal-body, - .modal-col-indigo .modal-title { - color: #fff !important; } - .modal-col-indigo .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-indigo .modal-footer .btn-link { - color: #fff !important; } - .modal-col-indigo .modal-footer .btn-link:hover, .modal-col-indigo .modal-footer .btn-link:active, .modal-col-indigo .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-blue { - background-color: #2196F3; } - .modal-col-blue .modal-body, - .modal-col-blue .modal-title { - color: #fff !important; } - .modal-col-blue .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-blue .modal-footer .btn-link { - color: #fff !important; } - .modal-col-blue .modal-footer .btn-link:hover, .modal-col-blue .modal-footer .btn-link:active, .modal-col-blue .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-light-blue { - background-color: #03A9F4; } - .modal-col-light-blue .modal-body, - .modal-col-light-blue .modal-title { - color: #fff !important; } - .modal-col-light-blue .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-light-blue .modal-footer .btn-link { - color: #fff !important; } - .modal-col-light-blue .modal-footer .btn-link:hover, .modal-col-light-blue .modal-footer .btn-link:active, .modal-col-light-blue .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-cyan { - background-color: #00BCD4; } - .modal-col-cyan .modal-body, - .modal-col-cyan .modal-title { - color: #fff !important; } - .modal-col-cyan .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-cyan .modal-footer .btn-link { - color: #fff !important; } - .modal-col-cyan .modal-footer .btn-link:hover, .modal-col-cyan .modal-footer .btn-link:active, .modal-col-cyan .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-teal { - background-color: #009688; } - .modal-col-teal .modal-body, - .modal-col-teal .modal-title { - color: #fff !important; } - .modal-col-teal .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-teal .modal-footer .btn-link { - color: #fff !important; } - .modal-col-teal .modal-footer .btn-link:hover, .modal-col-teal .modal-footer .btn-link:active, .modal-col-teal .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-green { - background-color: #4CAF50; } - .modal-col-green .modal-body, - .modal-col-green .modal-title { - color: #fff !important; } - .modal-col-green .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-green .modal-footer .btn-link { - color: #fff !important; } - .modal-col-green .modal-footer .btn-link:hover, .modal-col-green .modal-footer .btn-link:active, .modal-col-green .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-light-green { - background-color: #8BC34A; } - .modal-col-light-green .modal-body, - .modal-col-light-green .modal-title { - color: #fff !important; } - .modal-col-light-green .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-light-green .modal-footer .btn-link { - color: #fff !important; } - .modal-col-light-green .modal-footer .btn-link:hover, .modal-col-light-green .modal-footer .btn-link:active, .modal-col-light-green .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-lime { - background-color: #CDDC39; } - .modal-col-lime .modal-body, - .modal-col-lime .modal-title { - color: #fff !important; } - .modal-col-lime .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-lime .modal-footer .btn-link { - color: #fff !important; } - .modal-col-lime .modal-footer .btn-link:hover, .modal-col-lime .modal-footer .btn-link:active, .modal-col-lime .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-yellow { - background-color: #ffe821; } - .modal-col-yellow .modal-body, - .modal-col-yellow .modal-title { - color: #fff !important; } - .modal-col-yellow .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-yellow .modal-footer .btn-link { - color: #fff !important; } - .modal-col-yellow .modal-footer .btn-link:hover, .modal-col-yellow .modal-footer .btn-link:active, .modal-col-yellow .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-amber { - background-color: #FFC107; } - .modal-col-amber .modal-body, - .modal-col-amber .modal-title { - color: #fff !important; } - .modal-col-amber .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-amber .modal-footer .btn-link { - color: #fff !important; } - .modal-col-amber .modal-footer .btn-link:hover, .modal-col-amber .modal-footer .btn-link:active, .modal-col-amber .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-orange { - background-color: #FF9800; } - .modal-col-orange .modal-body, - .modal-col-orange .modal-title { - color: #fff !important; } - .modal-col-orange .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-orange .modal-footer .btn-link { - color: #fff !important; } - .modal-col-orange .modal-footer .btn-link:hover, .modal-col-orange .modal-footer .btn-link:active, .modal-col-orange .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-deep-orange { - background-color: #FF5722; } - .modal-col-deep-orange .modal-body, - .modal-col-deep-orange .modal-title { - color: #fff !important; } - .modal-col-deep-orange .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-deep-orange .modal-footer .btn-link { - color: #fff !important; } - .modal-col-deep-orange .modal-footer .btn-link:hover, .modal-col-deep-orange .modal-footer .btn-link:active, .modal-col-deep-orange .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-brown { - background-color: #795548; } - .modal-col-brown .modal-body, - .modal-col-brown .modal-title { - color: #fff !important; } - .modal-col-brown .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-brown .modal-footer .btn-link { - color: #fff !important; } - .modal-col-brown .modal-footer .btn-link:hover, .modal-col-brown .modal-footer .btn-link:active, .modal-col-brown .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-grey { - background-color: #9E9E9E; } - .modal-col-grey .modal-body, - .modal-col-grey .modal-title { - color: #fff !important; } - .modal-col-grey .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-grey .modal-footer .btn-link { - color: #fff !important; } - .modal-col-grey .modal-footer .btn-link:hover, .modal-col-grey .modal-footer .btn-link:active, .modal-col-grey .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-blue-grey { - background-color: #607D8B; } - .modal-col-blue-grey .modal-body, - .modal-col-blue-grey .modal-title { - color: #fff !important; } - .modal-col-blue-grey .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-blue-grey .modal-footer .btn-link { - color: #fff !important; } - .modal-col-blue-grey .modal-footer .btn-link:hover, .modal-col-blue-grey .modal-footer .btn-link:active, .modal-col-blue-grey .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-black { - background-color: #000000; } - .modal-col-black .modal-body, - .modal-col-black .modal-title { - color: #fff !important; } - .modal-col-black .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-black .modal-footer .btn-link { - color: #fff !important; } - .modal-col-black .modal-footer .btn-link:hover, .modal-col-black .modal-footer .btn-link:active, .modal-col-black .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -.modal-col-white { - background-color: #ffffff; } - .modal-col-white .modal-body, - .modal-col-white .modal-title { - color: #fff !important; } - .modal-col-white .modal-footer { - background-color: rgba(0, 0, 0, 0.12); } - .modal-col-white .modal-footer .btn-link { - color: #fff !important; } - .modal-col-white .modal-footer .btn-link:hover, .modal-col-white .modal-footer .btn-link:active, .modal-col-white .modal-footer .btn-link:focus { - background-color: rgba(0, 0, 0, 0.12); } - -/* Labels ====================================== */ -.label { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - -.label-primary { - background-color: #1f91f3; } - -.label-success { - background-color: #2b982b; } - -.label-info { - background-color: #00b0e4; } - -.label-warning { - background-color: #ff9600; } - -.label-danger { - background-color: #fb483a; } - -/* Collapse ==================================== */ -.collapse .well, -.collapse.in .well, -.collapsing .well { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - margin-bottom: 0; } - -/* Tables ====================================== */ -.table tbody tr td, .table tbody tr th { - padding: 10px; - border-top: 1px solid #eee; - border-bottom: 1px solid #eee; } - -.table tbody tr.primary td, .table tbody tr.primary th { - background-color: #1f91f3; - color: #fff; } - -.table tbody tr.success td, .table tbody tr.success th { - background-color: #2b982b; - color: #fff; } - -.table tbody tr.info td, .table tbody tr.info th { - background-color: #00b0e4; - color: #fff; } - -.table tbody tr.warning td, .table tbody tr.warning th { - background-color: #ff9600; - color: #fff; } - -.table tbody tr.danger td, .table tbody tr.danger th { - background-color: #fb483a; - color: #fff; } - -.table thead tr th { - padding: 10px; - border-bottom: 1px solid #eee; } - -.table-bordered { - border-top: 1px solid #eee; } - .table-bordered tbody tr td, .table-bordered tbody tr th { - padding: 10px; - border: 1px solid #eee; } - .table-bordered thead tr th { - padding: 10px; - border: 1px solid #eee; } - -/* Panel ======================================= */ -.panel-group .panel-col-red { - border: 1px solid #F44336; } - .panel-group .panel-col-red .panel-title { - background-color: #F44336 !important; - color: #fff; } - .panel-group .panel-col-red .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-pink { - border: 1px solid #E91E63; } - .panel-group .panel-col-pink .panel-title { - background-color: #E91E63 !important; - color: #fff; } - .panel-group .panel-col-pink .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-purple { - border: 1px solid #9C27B0; } - .panel-group .panel-col-purple .panel-title { - background-color: #9C27B0 !important; - color: #fff; } - .panel-group .panel-col-purple .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-deep-purple { - border: 1px solid #673AB7; } - .panel-group .panel-col-deep-purple .panel-title { - background-color: #673AB7 !important; - color: #fff; } - .panel-group .panel-col-deep-purple .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-indigo { - border: 1px solid #3F51B5; } - .panel-group .panel-col-indigo .panel-title { - background-color: #3F51B5 !important; - color: #fff; } - .panel-group .panel-col-indigo .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-blue { - border: 1px solid #2196F3; } - .panel-group .panel-col-blue .panel-title { - background-color: #2196F3 !important; - color: #fff; } - .panel-group .panel-col-blue .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-light-blue { - border: 1px solid #03A9F4; } - .panel-group .panel-col-light-blue .panel-title { - background-color: #03A9F4 !important; - color: #fff; } - .panel-group .panel-col-light-blue .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-cyan { - border: 1px solid #00BCD4; } - .panel-group .panel-col-cyan .panel-title { - background-color: #00BCD4 !important; - color: #fff; } - .panel-group .panel-col-cyan .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-teal { - border: 1px solid #009688; } - .panel-group .panel-col-teal .panel-title { - background-color: #009688 !important; - color: #fff; } - .panel-group .panel-col-teal .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-green { - border: 1px solid #4CAF50; } - .panel-group .panel-col-green .panel-title { - background-color: #4CAF50 !important; - color: #fff; } - .panel-group .panel-col-green .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-light-green { - border: 1px solid #8BC34A; } - .panel-group .panel-col-light-green .panel-title { - background-color: #8BC34A !important; - color: #fff; } - .panel-group .panel-col-light-green .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-lime { - border: 1px solid #CDDC39; } - .panel-group .panel-col-lime .panel-title { - background-color: #CDDC39 !important; - color: #fff; } - .panel-group .panel-col-lime .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-yellow { - border: 1px solid #ffe821; } - .panel-group .panel-col-yellow .panel-title { - background-color: #ffe821 !important; - color: #fff; } - .panel-group .panel-col-yellow .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-amber { - border: 1px solid #FFC107; } - .panel-group .panel-col-amber .panel-title { - background-color: #FFC107 !important; - color: #fff; } - .panel-group .panel-col-amber .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-orange { - border: 1px solid #FF9800; } - .panel-group .panel-col-orange .panel-title { - background-color: #FF9800 !important; - color: #fff; } - .panel-group .panel-col-orange .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-deep-orange { - border: 1px solid #FF5722; } - .panel-group .panel-col-deep-orange .panel-title { - background-color: #FF5722 !important; - color: #fff; } - .panel-group .panel-col-deep-orange .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-brown { - border: 1px solid #795548; } - .panel-group .panel-col-brown .panel-title { - background-color: #795548 !important; - color: #fff; } - .panel-group .panel-col-brown .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-grey { - border: 1px solid #9E9E9E; } - .panel-group .panel-col-grey .panel-title { - background-color: #9E9E9E !important; - color: #fff; } - .panel-group .panel-col-grey .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-blue-grey { - border: 1px solid #607D8B; } - .panel-group .panel-col-blue-grey .panel-title { - background-color: #607D8B !important; - color: #fff; } - .panel-group .panel-col-blue-grey .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-black { - border: 1px solid #000000; } - .panel-group .panel-col-black .panel-title { - background-color: #000000 !important; - color: #fff; } - .panel-group .panel-col-black .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel-col-white { - border: 1px solid #ffffff; } - .panel-group .panel-col-white .panel-title { - background-color: #ffffff !important; - color: #fff; } - .panel-group .panel-col-white .panel-body { - border-top-color: transparent !important; } - -.panel-group .panel { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - .panel-group .panel .panel-title .material-icons { - float: left; - line-height: 16px; - margin-right: 8px; } - .panel-group .panel .panel-heading { - padding: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - .panel-group .panel .panel-heading a { - display: block; - padding: 10px 15px; } - .panel-group .panel .panel-heading a:hover, .panel-group .panel .panel-heading a:focus, .panel-group .panel .panel-heading a:active { - text-decoration: none; } - .panel-group .panel .panel-body { - color: #555; } - -.panel-group .panel-primary { - border: 1px solid #1f91f3; } - .panel-group .panel-primary .panel-title { - background-color: #1f91f3; } - -.panel-group .panel-success { - border: 1px solid #2b982b; } - .panel-group .panel-success .panel-title { - background-color: #2b982b; - color: #fff; } - -.panel-group .panel-warning { - border: 1px solid #ff9600; } - .panel-group .panel-warning .panel-title { - background-color: #ff9600; - color: #fff; } - -.panel-group .panel-danger { - border: 1px solid #fb483a; } - .panel-group .panel-danger .panel-title { - background-color: #fb483a; - color: #fff; } - -.full-body .panel-col-red .panel-body { - border-top-color: #fff !important; - background-color: #F44336; - color: #fff; } - -.full-body .panel-col-pink .panel-body { - border-top-color: #fff !important; - background-color: #E91E63; - color: #fff; } - -.full-body .panel-col-purple .panel-body { - border-top-color: #fff !important; - background-color: #9C27B0; - color: #fff; } - -.full-body .panel-col-deep-purple .panel-body { - border-top-color: #fff !important; - background-color: #673AB7; - color: #fff; } - -.full-body .panel-col-indigo .panel-body { - border-top-color: #fff !important; - background-color: #3F51B5; - color: #fff; } - -.full-body .panel-col-blue .panel-body { - border-top-color: #fff !important; - background-color: #2196F3; - color: #fff; } - -.full-body .panel-col-light-blue .panel-body { - border-top-color: #fff !important; - background-color: #03A9F4; - color: #fff; } - -.full-body .panel-col-cyan .panel-body { - border-top-color: #fff !important; - background-color: #00BCD4; - color: #fff; } - -.full-body .panel-col-teal .panel-body { - border-top-color: #fff !important; - background-color: #009688; - color: #fff; } - -.full-body .panel-col-green .panel-body { - border-top-color: #fff !important; - background-color: #4CAF50; - color: #fff; } - -.full-body .panel-col-light-green .panel-body { - border-top-color: #fff !important; - background-color: #8BC34A; - color: #fff; } - -.full-body .panel-col-lime .panel-body { - border-top-color: #fff !important; - background-color: #CDDC39; - color: #fff; } - -.full-body .panel-col-yellow .panel-body { - border-top-color: #fff !important; - background-color: #ffe821; - color: #fff; } - -.full-body .panel-col-amber .panel-body { - border-top-color: #fff !important; - background-color: #FFC107; - color: #fff; } - -.full-body .panel-col-orange .panel-body { - border-top-color: #fff !important; - background-color: #FF9800; - color: #fff; } - -.full-body .panel-col-deep-orange .panel-body { - border-top-color: #fff !important; - background-color: #FF5722; - color: #fff; } - -.full-body .panel-col-brown .panel-body { - border-top-color: #fff !important; - background-color: #795548; - color: #fff; } - -.full-body .panel-col-grey .panel-body { - border-top-color: #fff !important; - background-color: #9E9E9E; - color: #fff; } - -.full-body .panel-col-blue-grey .panel-body { - border-top-color: #fff !important; - background-color: #607D8B; - color: #fff; } - -.full-body .panel-col-black .panel-body { - border-top-color: #fff !important; - background-color: #000000; - color: #fff; } - -.full-body .panel-col-white .panel-body { - border-top-color: #fff !important; - background-color: #ffffff; - color: #fff; } - -.full-body .panel-primary .panel-body { - border-top-color: #fff !important; - background-color: #1f91f3; - color: #fff; } - -.full-body .panel-success .panel-body { - border-top-color: #fff !important; - background-color: #2b982b; - color: #fff; } - -.full-body .panel-warning .panel-body { - border-top-color: #fff !important; - background-color: #ff9600; - color: #fff; } - -.full-body .panel-danger .panel-body { - border-top-color: #fff !important; - background-color: #fb483a; - color: #fff; } - -/* Progress Bars =============================== */ -.progress { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - height: 22px; } - .progress .progress-bar { - line-height: 23px; - background-color: #1f91f3; } - .progress .progress-bar-success { - background-color: #2b982b; } - .progress .progress-bar-info { - background-color: #00b0e4; } - .progress .progress-bar-warning { - background-color: #ff9600; } - .progress .progress-bar-danger { - background-color: #fb483a; } - -/* Ion Range Slider ============================ */ -.irs .irs-min, -.irs .irs-max, -.irs .irs-from, -.irs .irs-to, -.irs .irs-single { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - -/* Input Group ================================= */ -.input-group { - width: 100%; - margin-bottom: 20px; } - .input-group .form-line { - display: inline-block; - width: 100%; - border-bottom: 1px solid #ddd; - position: relative; } - .input-group .form-line:after { - content: ''; - position: absolute; - left: 0; - width: 100%; - bottom: -2px; - -moz-transform: scaleX(0); - -ms-transform: scaleX(0); - -o-transform: scaleX(0); - -webkit-transform: scaleX(0); - transform: scaleX(0); - -moz-transition: 0.25s ease-in; - -o-transition: 0.25s ease-in; - -webkit-transition: 0.25s ease-in; - transition: 0.25s ease-in; - border-bottom: 2px solid #1f91f3; } - .input-group .form-line + .input-group-addon { - padding-right: 0; - padding-left: 10px; } - .input-group .help-info { - float: right; - font-size: 12px; - margin-top: 5px; - color: #999; } - .input-group label.error { - font-size: 12px; - display: block; - margin-top: 5px; - font-weight: normal; - color: #F44336; } - .input-group .form-line.error:after { - border-bottom: 2px solid #F44336; } - .input-group .form-line.success:after { - border-bottom: 2px solid #4CAF50; } - .input-group .form-line.warning:after { - border-bottom: 2px solid #FFC107; } - .input-group .form-line.focused:after { - -moz-transform: scaleX(1); - -ms-transform: scaleX(1); - -o-transform: scaleX(1); - -webkit-transform: scaleX(1); - transform: scaleX(1); } - .input-group .form-line.focused .form-label { - bottom: 25px; - left: 0; - font-size: 12px; } - .input-group .input-group-addon { - border: none; - background-color: transparent; - padding-left: 0; - font-weight: bold; } - .input-group .input-group-addon .material-icons { - font-size: 18px; - color: #555; } - .input-group input[type="text"], - .input-group .form-control { - border: none; - box-shadow: none; - padding-left: 0; } - .input-group .form-control:focus { - -webkit-box-shadow: none !important; - -moz-box-shadow: none !important; - -ms-box-shadow: none !important; - box-shadow: none !important; } - -.input-group.input-group-sm .input-group-addon i { - font-size: 14px; } - -.input-group.input-group-sm .form-control { - font-size: 12px; } - -.input-group.input-group-lg .input-group-addon i { - font-size: 26px; } - -.input-group.input-group-lg .form-control { - font-size: 18px; } - -.form-control-label { - text-align: right; } - .form-control-label label { - margin-top: 8px; } - -.form-horizontal .form-group { - margin-bottom: 0; } - -.form-group { - width: 100%; - margin-bottom: 25px; } - .form-group .form-control { - width: 100%; - border: none; - box-shadow: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - padding-left: 0; } - .form-group .help-info { - float: right; - font-size: 12px; - margin-top: 5px; - color: #999; } - .form-group label.error { - font-size: 12px; - display: block; - margin-top: 5px; - font-weight: normal; - color: #F44336; } - .form-group .form-line { - width: 100%; - position: relative; - border-bottom: 1px solid #ddd; } - .form-group .form-line:after { - content: ''; - position: absolute; - left: 0; - width: 100%; - height: 0; - bottom: -1px; - -moz-transform: scaleX(0); - -ms-transform: scaleX(0); - -o-transform: scaleX(0); - -webkit-transform: scaleX(0); - transform: scaleX(0); - -moz-transition: 0.25s ease-in; - -o-transition: 0.25s ease-in; - -webkit-transition: 0.25s ease-in; - transition: 0.25s ease-in; - border-bottom: 2px solid #1f91f3; } - .form-group .form-line .form-label { - font-weight: normal; - color: #aaa; - position: absolute; - top: 10px; - left: 0; - cursor: text; - -moz-transition: 0.2s; - -o-transition: 0.2s; - -webkit-transition: 0.2s; - transition: 0.2s; } - .form-group .form-line.error:after { - border-bottom: 2px solid #F44336; } - .form-group .form-line.success:after { - border-bottom: 2px solid #4CAF50; } - .form-group .form-line.warning:after { - border-bottom: 2px solid #FFC107; } - .form-group .form-line.focused:after { - -moz-transform: scaleX(1); - -ms-transform: scaleX(1); - -o-transform: scaleX(1); - -webkit-transform: scaleX(1); - transform: scaleX(1); } - .form-group .form-line.focused .form-label { - top: -10px; - left: 0; - font-size: 12px; } - -.form-group-sm .form-label { - font-size: 12px; } - -.form-group-sm .form-line.focused .form-label { - bottom: 20px; - font-size: 10px; } - -.form-group-lg .form-label { - font-size: 18px; } - -.form-group-lg .form-line.focused .form-label { - bottom: 35px; - font-size: 12px; } - -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - background-color: transparent; } - -/* Color Picker ================================ */ -.colorpicker { - z-index: 1; } - .colorpicker:before, .colorpicker:after { - display: none !important; } - -/* Dropzone ==================================== */ -.dropzone { - border: 2px solid transparent !important; - background-color: #eee !important; } - .dropzone .dz-message .drag-icon-cph .material-icons { - font-size: 80px; - color: #777; } - -.dz-drag-hover { - border: 2px dashed #888 !important; } - -/* Breadcrumbs ================================= */ -.breadcrumb { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - background-color: transparent; - font-size: 13px; - margin-bottom: 10px; } - .breadcrumb li a { - color: #444; - text-decoration: none; } - .breadcrumb li a .material-icons { - font-size: 18px; - position: relative; - top: 4px; } - .breadcrumb li .material-icons { - font-size: 18px; - position: relative; - top: 4px; } - .breadcrumb > li + li:before { - content: '>\00a0'; } - -.breadcrumb-col-red li a { - color: #F44336 !important; - font-weight: bold; } - -.breadcrumb-bg-red { - background-color: #F44336 !important; } - .breadcrumb-bg-red li { - color: #fff !important; } - .breadcrumb-bg-red li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-red li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-red li + li:before { - color: #fff; } - -.breadcrumb-col-pink li a { - color: #E91E63 !important; - font-weight: bold; } - -.breadcrumb-bg-pink { - background-color: #E91E63 !important; } - .breadcrumb-bg-pink li { - color: #fff !important; } - .breadcrumb-bg-pink li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-pink li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-pink li + li:before { - color: #fff; } - -.breadcrumb-col-purple li a { - color: #9C27B0 !important; - font-weight: bold; } - -.breadcrumb-bg-purple { - background-color: #9C27B0 !important; } - .breadcrumb-bg-purple li { - color: #fff !important; } - .breadcrumb-bg-purple li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-purple li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-purple li + li:before { - color: #fff; } - -.breadcrumb-col-deep-purple li a { - color: #673AB7 !important; - font-weight: bold; } - -.breadcrumb-bg-deep-purple { - background-color: #673AB7 !important; } - .breadcrumb-bg-deep-purple li { - color: #fff !important; } - .breadcrumb-bg-deep-purple li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-deep-purple li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-deep-purple li + li:before { - color: #fff; } - -.breadcrumb-col-indigo li a { - color: #3F51B5 !important; - font-weight: bold; } - -.breadcrumb-bg-indigo { - background-color: #3F51B5 !important; } - .breadcrumb-bg-indigo li { - color: #fff !important; } - .breadcrumb-bg-indigo li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-indigo li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-indigo li + li:before { - color: #fff; } - -.breadcrumb-col-blue li a { - color: #2196F3 !important; - font-weight: bold; } - -.breadcrumb-bg-blue { - background-color: #2196F3 !important; } - .breadcrumb-bg-blue li { - color: #fff !important; } - .breadcrumb-bg-blue li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-blue li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-blue li + li:before { - color: #fff; } - -.breadcrumb-col-light-blue li a { - color: #03A9F4 !important; - font-weight: bold; } - -.breadcrumb-bg-light-blue { - background-color: #03A9F4 !important; } - .breadcrumb-bg-light-blue li { - color: #fff !important; } - .breadcrumb-bg-light-blue li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-light-blue li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-light-blue li + li:before { - color: #fff; } - -.breadcrumb-col-cyan li a { - color: #00BCD4 !important; - font-weight: bold; } - -.breadcrumb-bg-cyan { - background-color: #00BCD4 !important; } - .breadcrumb-bg-cyan li { - color: #fff !important; } - .breadcrumb-bg-cyan li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-cyan li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-cyan li + li:before { - color: #fff; } - -.breadcrumb-col-teal li a { - color: #009688 !important; - font-weight: bold; } - -.breadcrumb-bg-teal { - background-color: #009688 !important; } - .breadcrumb-bg-teal li { - color: #fff !important; } - .breadcrumb-bg-teal li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-teal li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-teal li + li:before { - color: #fff; } - -.breadcrumb-col-green li a { - color: #4CAF50 !important; - font-weight: bold; } - -.breadcrumb-bg-green { - background-color: #4CAF50 !important; } - .breadcrumb-bg-green li { - color: #fff !important; } - .breadcrumb-bg-green li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-green li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-green li + li:before { - color: #fff; } - -.breadcrumb-col-light-green li a { - color: #8BC34A !important; - font-weight: bold; } - -.breadcrumb-bg-light-green { - background-color: #8BC34A !important; } - .breadcrumb-bg-light-green li { - color: #fff !important; } - .breadcrumb-bg-light-green li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-light-green li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-light-green li + li:before { - color: #fff; } - -.breadcrumb-col-lime li a { - color: #CDDC39 !important; - font-weight: bold; } - -.breadcrumb-bg-lime { - background-color: #CDDC39 !important; } - .breadcrumb-bg-lime li { - color: #fff !important; } - .breadcrumb-bg-lime li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-lime li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-lime li + li:before { - color: #fff; } - -.breadcrumb-col-yellow li a { - color: #ffe821 !important; - font-weight: bold; } - -.breadcrumb-bg-yellow { - background-color: #ffe821 !important; } - .breadcrumb-bg-yellow li { - color: #fff !important; } - .breadcrumb-bg-yellow li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-yellow li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-yellow li + li:before { - color: #fff; } - -.breadcrumb-col-amber li a { - color: #FFC107 !important; - font-weight: bold; } - -.breadcrumb-bg-amber { - background-color: #FFC107 !important; } - .breadcrumb-bg-amber li { - color: #fff !important; } - .breadcrumb-bg-amber li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-amber li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-amber li + li:before { - color: #fff; } - -.breadcrumb-col-orange li a { - color: #FF9800 !important; - font-weight: bold; } - -.breadcrumb-bg-orange { - background-color: #FF9800 !important; } - .breadcrumb-bg-orange li { - color: #fff !important; } - .breadcrumb-bg-orange li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-orange li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-orange li + li:before { - color: #fff; } - -.breadcrumb-col-deep-orange li a { - color: #FF5722 !important; - font-weight: bold; } - -.breadcrumb-bg-deep-orange { - background-color: #FF5722 !important; } - .breadcrumb-bg-deep-orange li { - color: #fff !important; } - .breadcrumb-bg-deep-orange li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-deep-orange li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-deep-orange li + li:before { - color: #fff; } - -.breadcrumb-col-brown li a { - color: #795548 !important; - font-weight: bold; } - -.breadcrumb-bg-brown { - background-color: #795548 !important; } - .breadcrumb-bg-brown li { - color: #fff !important; } - .breadcrumb-bg-brown li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-brown li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-brown li + li:before { - color: #fff; } - -.breadcrumb-col-grey li a { - color: #9E9E9E !important; - font-weight: bold; } - -.breadcrumb-bg-grey { - background-color: #9E9E9E !important; } - .breadcrumb-bg-grey li { - color: #fff !important; } - .breadcrumb-bg-grey li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-grey li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-grey li + li:before { - color: #fff; } - -.breadcrumb-col-blue-grey li a { - color: #607D8B !important; - font-weight: bold; } - -.breadcrumb-bg-blue-grey { - background-color: #607D8B !important; } - .breadcrumb-bg-blue-grey li { - color: #fff !important; } - .breadcrumb-bg-blue-grey li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-blue-grey li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-blue-grey li + li:before { - color: #fff; } - -.breadcrumb-col-black li a { - color: #000000 !important; - font-weight: bold; } - -.breadcrumb-bg-black { - background-color: #000000 !important; } - .breadcrumb-bg-black li { - color: #fff !important; } - .breadcrumb-bg-black li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-black li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-black li + li:before { - color: #fff; } - -.breadcrumb-col-white li a { - color: #ffffff !important; - font-weight: bold; } - -.breadcrumb-bg-white { - background-color: #ffffff !important; } - .breadcrumb-bg-white li { - color: #fff !important; } - .breadcrumb-bg-white li a { - color: #fff; - font-weight: bold; } - .breadcrumb-bg-white li a .material-icons { - padding-bottom: 8px; } - .breadcrumb-bg-white li + li:before { - color: #fff; } - -/* Badge | List Group Item ===================== */ -.badge { - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - -ms-border-radius: 2px; - border-radius: 2px; } - -.list-group-item { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - -moz-transition: 0.5s; - -o-transition: 0.5s; - -webkit-transition: 0.5s; - transition: 0.5s; } - -.list-group .active { - background-color: #2196F3; - border-color: #2196F3; } - .list-group .active:hover, .list-group .active:focus, .list-group .active:active { - background-color: #2196F3; - border-color: #2196F3; } - .list-group .active .list-group-item-text { - color: #dfe9f1; - font-size: 13px; } - .list-group .active .list-group-item-text:hover, .list-group .active .list-group-item-text:active, .list-group .active .list-group-item-text:focus { - color: #dfe9f1; } - -.list-group .list-group-item.active:hover .list-group-item-text, .list-group .list-group-item.active:focus .list-group-item-text, .list-group .list-group-item.active:active .list-group-item-text { - color: #dfe9f1; } - -.list-group .list-group-item:first-child, .list-group .list-group-item:last-child { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - -.list-group .list-group-item .list-group-item-heading { - font-weight: bold; - font-size: 17px; } - -.list-group .list-group-item-success { - background-color: #2b982b; - border: none; - color: #fff; } - .list-group .list-group-item-success:hover, .list-group .list-group-item-success:focus { - background-color: #2b982b; - color: #fff; - opacity: 0.8; } - -.list-group .list-group-item-info { - background-color: #00b0e4; - border: none; - color: #fff; } - .list-group .list-group-item-info:hover, .list-group .list-group-item-info:focus { - background-color: #00b0e4; - color: #fff; - opacity: 0.8; } - -.list-group .list-group-item-warning { - background-color: #ff9600; - border: none; - color: #fff; } - .list-group .list-group-item-warning:hover, .list-group .list-group-item-warning:focus { - background-color: #ff9600; - color: #fff; - opacity: 0.8; } - -.list-group .list-group-item-danger { - background-color: #fb483a; - border: none; - color: #fff; } - .list-group .list-group-item-danger:hover, .list-group .list-group-item-danger:focus { - background-color: #fb483a; - color: #fff; - opacity: 0.8; } - -.list-group .pl-red { - stroke: #F44336; } - -.list-group .list-group-bg-red { - background-color: #F44336; - border: none; - color: #fff; } - .list-group .list-group-bg-red:hover, .list-group .list-group-bg-red:focus { - background-color: #F44336; - color: #fff; - opacity: 0.8; } - -.list-group .pl-pink { - stroke: #E91E63; } - -.list-group .list-group-bg-pink { - background-color: #E91E63; - border: none; - color: #fff; } - .list-group .list-group-bg-pink:hover, .list-group .list-group-bg-pink:focus { - background-color: #E91E63; - color: #fff; - opacity: 0.8; } - -.list-group .pl-purple { - stroke: #9C27B0; } - -.list-group .list-group-bg-purple { - background-color: #9C27B0; - border: none; - color: #fff; } - .list-group .list-group-bg-purple:hover, .list-group .list-group-bg-purple:focus { - background-color: #9C27B0; - color: #fff; - opacity: 0.8; } - -.list-group .pl-deep-purple { - stroke: #673AB7; } - -.list-group .list-group-bg-deep-purple { - background-color: #673AB7; - border: none; - color: #fff; } - .list-group .list-group-bg-deep-purple:hover, .list-group .list-group-bg-deep-purple:focus { - background-color: #673AB7; - color: #fff; - opacity: 0.8; } - -.list-group .pl-indigo { - stroke: #3F51B5; } - -.list-group .list-group-bg-indigo { - background-color: #3F51B5; - border: none; - color: #fff; } - .list-group .list-group-bg-indigo:hover, .list-group .list-group-bg-indigo:focus { - background-color: #3F51B5; - color: #fff; - opacity: 0.8; } - -.list-group .pl-blue { - stroke: #2196F3; } - -.list-group .list-group-bg-blue { - background-color: #2196F3; - border: none; - color: #fff; } - .list-group .list-group-bg-blue:hover, .list-group .list-group-bg-blue:focus { - background-color: #2196F3; - color: #fff; - opacity: 0.8; } - -.list-group .pl-light-blue { - stroke: #03A9F4; } - -.list-group .list-group-bg-light-blue { - background-color: #03A9F4; - border: none; - color: #fff; } - .list-group .list-group-bg-light-blue:hover, .list-group .list-group-bg-light-blue:focus { - background-color: #03A9F4; - color: #fff; - opacity: 0.8; } - -.list-group .pl-cyan { - stroke: #00BCD4; } - -.list-group .list-group-bg-cyan { - background-color: #00BCD4; - border: none; - color: #fff; } - .list-group .list-group-bg-cyan:hover, .list-group .list-group-bg-cyan:focus { - background-color: #00BCD4; - color: #fff; - opacity: 0.8; } - -.list-group .pl-teal { - stroke: #009688; } - -.list-group .list-group-bg-teal { - background-color: #009688; - border: none; - color: #fff; } - .list-group .list-group-bg-teal:hover, .list-group .list-group-bg-teal:focus { - background-color: #009688; - color: #fff; - opacity: 0.8; } - -.list-group .pl-green { - stroke: #4CAF50; } - -.list-group .list-group-bg-green { - background-color: #4CAF50; - border: none; - color: #fff; } - .list-group .list-group-bg-green:hover, .list-group .list-group-bg-green:focus { - background-color: #4CAF50; - color: #fff; - opacity: 0.8; } - -.list-group .pl-light-green { - stroke: #8BC34A; } - -.list-group .list-group-bg-light-green { - background-color: #8BC34A; - border: none; - color: #fff; } - .list-group .list-group-bg-light-green:hover, .list-group .list-group-bg-light-green:focus { - background-color: #8BC34A; - color: #fff; - opacity: 0.8; } - -.list-group .pl-lime { - stroke: #CDDC39; } - -.list-group .list-group-bg-lime { - background-color: #CDDC39; - border: none; - color: #fff; } - .list-group .list-group-bg-lime:hover, .list-group .list-group-bg-lime:focus { - background-color: #CDDC39; - color: #fff; - opacity: 0.8; } - -.list-group .pl-yellow { - stroke: #ffe821; } - -.list-group .list-group-bg-yellow { - background-color: #ffe821; - border: none; - color: #fff; } - .list-group .list-group-bg-yellow:hover, .list-group .list-group-bg-yellow:focus { - background-color: #ffe821; - color: #fff; - opacity: 0.8; } - -.list-group .pl-amber { - stroke: #FFC107; } - -.list-group .list-group-bg-amber { - background-color: #FFC107; - border: none; - color: #fff; } - .list-group .list-group-bg-amber:hover, .list-group .list-group-bg-amber:focus { - background-color: #FFC107; - color: #fff; - opacity: 0.8; } - -.list-group .pl-orange { - stroke: #FF9800; } - -.list-group .list-group-bg-orange { - background-color: #FF9800; - border: none; - color: #fff; } - .list-group .list-group-bg-orange:hover, .list-group .list-group-bg-orange:focus { - background-color: #FF9800; - color: #fff; - opacity: 0.8; } - -.list-group .pl-deep-orange { - stroke: #FF5722; } - -.list-group .list-group-bg-deep-orange { - background-color: #FF5722; - border: none; - color: #fff; } - .list-group .list-group-bg-deep-orange:hover, .list-group .list-group-bg-deep-orange:focus { - background-color: #FF5722; - color: #fff; - opacity: 0.8; } - -.list-group .pl-brown { - stroke: #795548; } - -.list-group .list-group-bg-brown { - background-color: #795548; - border: none; - color: #fff; } - .list-group .list-group-bg-brown:hover, .list-group .list-group-bg-brown:focus { - background-color: #795548; - color: #fff; - opacity: 0.8; } - -.list-group .pl-grey { - stroke: #9E9E9E; } - -.list-group .list-group-bg-grey { - background-color: #9E9E9E; - border: none; - color: #fff; } - .list-group .list-group-bg-grey:hover, .list-group .list-group-bg-grey:focus { - background-color: #9E9E9E; - color: #fff; - opacity: 0.8; } - -.list-group .pl-blue-grey { - stroke: #607D8B; } - -.list-group .list-group-bg-blue-grey { - background-color: #607D8B; - border: none; - color: #fff; } - .list-group .list-group-bg-blue-grey:hover, .list-group .list-group-bg-blue-grey:focus { - background-color: #607D8B; - color: #fff; - opacity: 0.8; } - -.list-group .pl-black { - stroke: #000000; } - -.list-group .list-group-bg-black { - background-color: #000000; - border: none; - color: #fff; } - .list-group .list-group-bg-black:hover, .list-group .list-group-bg-black:focus { - background-color: #000000; - color: #fff; - opacity: 0.8; } - -.list-group .pl-white { - stroke: #ffffff; } - -.list-group .list-group-bg-white { - background-color: #ffffff; - border: none; - color: #fff; } - .list-group .list-group-bg-white:hover, .list-group .list-group-bg-white:focus { - background-color: #ffffff; - color: #fff; - opacity: 0.8; } - -/* Pagination & Pager ========================== */ -.pager li > a { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - border: none; - background-color: transparent; - color: #222; - font-weight: bold; } - -.pager li a:focus, -.pager li a:active { - background-color: transparent; } - -.pagination .disabled a, -.pagination .disabled a:hover, -.pagination .disabled a:focus, -.pagination .disabled a:active { - color: #bbb; } - -.pagination li.active a { - background-color: #2196F3; } - -.pagination li { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - .pagination li a:focus, - .pagination li a:active { - background-color: transparent; - color: #555; } - -.pagination > li > a { - border: none; - font-weight: bold; - color: #555; } - -.pagination > li:first-child > a, -.pagination > li:last-child > a { - width: auto; - height: 32px; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - .pagination > li:first-child > a .material-icons, - .pagination > li:last-child > a .material-icons { - position: relative; - bottom: 2px; } - -.pagination-sm > li:first-child > a, -.pagination-sm > li:last-child > a { - width: 28px; - height: 28px; } - .pagination-sm > li:first-child > a .material-icons, - .pagination-sm > li:last-child > a .material-icons { - position: relative; - top: -1px; - left: -6px; - font-size: 20px; } - -.pagination-lg > li:first-child > a, -.pagination-lg > li:last-child > a { - width: 44px; - height: 44px; } - .pagination-lg > li:first-child > a .material-icons, - .pagination-lg > li:last-child > a .material-icons { - font-size: 30px; - position: relative; - top: -3px; - left: -10px; } - -/* Media Object ================================ */ -.media { - margin-bottom: 25px; } - .media .media-body { - color: #777; - font-size: 13px; } - .media .media-body .media-heading { - font-size: 16px; - font-weight: bold; - color: #333; } - -/* Form Wizard ================================= */ -.wizard, -.tabcontrol { - display: block; - width: 100%; - overflow: hidden; } - -.wizard a, -.tabcontrol a { - outline: 0; } - -.wizard ul, -.tabcontrol ul { - list-style: none !important; - padding: 0; - margin: 0; } - -.wizard ul > li, .tabcontrol ul > li { - display: block; - padding: 0; } - -/* Accessibility */ -.wizard > .steps .current-info, -.tabcontrol > .steps .current-info, -.wizard > .content > .title, -.tabcontrol > .content > .title { - position: absolute; - left: -999em; } - -.wizard > .steps { - position: relative; - display: block; - width: 100%; } - -.wizard.vertical > .steps { - float: left; - width: 30%; } - -.wizard.vertical > .steps > ul > li { - float: none; - width: 100%; } - -.wizard.vertical > .content { - float: left; - margin: 0 0 0.5em 0; - width: 70%; } - -.wizard.vertical > .actions { - float: right; - width: 100%; } - -.wizard.vertical > .actions > ul > li { - margin: 0 0 0 1em; } - -.wizard > .steps .number { - font-size: 1.429em; } - -.wizard > .steps > ul > li { - width: 25%; - float: left; } - -.wizard > .actions > ul > li { - float: left; } - -.wizard > .steps a { - display: block; - width: auto; - margin: 0 0.5em 0.5em; - padding: 1em 1em; - text-decoration: none; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; } - .wizard > .steps a:hover, .wizard > .steps a:active { - display: block; - width: auto; - margin: 0 0.5em 0.5em; - padding: 1em 1em; - text-decoration: none; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; } - -.wizard > .steps .disabled a { - background: #eee; - color: #aaa; - cursor: default; } - .wizard > .steps .disabled a:hover, .wizard > .steps .disabled a:active { - background: #eee; - color: #aaa; - cursor: default; } - -.wizard > .steps .current a { - background: #2184be; - color: #fff; - cursor: default; } - .wizard > .steps .current a:hover, .wizard > .steps .current a:active { - background: #2184be; - color: #fff; - cursor: default; } - -.wizard > .steps .done a { - background: #9dc8e2; - color: #fff; } - .wizard > .steps .done a:hover, .wizard > .steps .done a:active { - background: #9dc8e2; - color: #fff; } - -.wizard > .steps .error a { - background: #ff3111; - color: #fff; } - .wizard > .steps .error a:hover, .wizard > .steps .error a:active { - background: #ff3111; - color: #fff; } - -.wizard > .content { - border: 1px solid #ddd; - display: block; - margin: 0.5em; - min-height: 35em; - overflow: hidden; - position: relative; - width: auto; } - -.wizard > .actions { - position: relative; - display: block; - text-align: right; - width: 100%; } - -.wizard > .actions > ul { - display: inline-block; - text-align: right; } - .wizard > .actions > ul > li { - margin: 0 0.5em; } - -.wizard > .actions a { - background: #009688; - color: #fff; - display: block; - padding: 0.5em 1em; - text-decoration: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - .wizard > .actions a:hover, .wizard > .actions a:active { - background: #009688; - color: #fff; - display: block; - padding: 0.5em 1em; - text-decoration: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - -.wizard > .actions .disabled a { - background: #eee; - color: #aaa; } - .wizard > .actions .disabled a:hover, .wizard > .actions .disabled a:active { - background: #eee; - color: #aaa; } - -.tabcontrol > .steps { - position: relative; - display: block; - width: 100%; } - .tabcontrol > .steps > ul { - position: relative; - margin: 6px 0 0 0; - top: 1px; - z-index: 1; } - .tabcontrol > .steps > ul > li { - float: left; - margin: 5px 2px 0 0; - padding: 1px; - -webkit-border-top-left-radius: 5px; - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topleft: 5px; - -moz-border-radius-topright: 5px; - border-top-left-radius: 5px; - border-top-right-radius: 5px; } - .tabcontrol > .steps > ul > li:hover { - background: #edecec; - border: 1px solid #bbb; - padding: 0; } - .tabcontrol > .steps > ul > li.current { - background: #fff; - border: 1px solid #bbb; - border-bottom: 0 none; - padding: 0 0 1px 0; - margin-top: 0; } - .tabcontrol > .steps > ul > li.current > a { - padding: 15px 30px 10px 30px; } - .tabcontrol > .steps > ul > li > a { - color: #5f5f5f; - display: inline-block; - border: 0 none; - margin: 0; - padding: 10px 30px; - text-decoration: none; } - .tabcontrol > .steps > ul > li > a:hover { - text-decoration: none; } - -.tabcontrol > .content { - position: relative; - display: inline-block; - width: 100%; - height: 35em; - overflow: hidden; - border-top: 1px solid #bbb; - padding-top: 20px; } - .tabcontrol > .content > .body { - float: left; - position: absolute; - width: 95%; - height: 95%; - padding: 2.5%; } - .tabcontrol > .content > .body ul { - list-style: disc !important; } - .tabcontrol > .content > .body ul > li { - display: list-item; } - -.wizard .content { - min-height: 245px; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - overflow-y: auto; } - .wizard .content .body { - padding: 15px; } - -.wizard .steps a { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - -moz-transition: 0.5s; - -o-transition: 0.5s; - -webkit-transition: 0.5s; - transition: 0.5s; } - .wizard .steps a:active, .wizard .steps a:focus, .wizard .steps a:hover { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - -.wizard .steps .done a { - background-color: rgba(0, 150, 136, 0.6); } - .wizard .steps .done a:hover, .wizard .steps .done a:active, .wizard .steps .done a:focus { - background-color: rgba(0, 150, 136, 0.5); } - -.wizard .steps .error a { - background-color: #F44336 !important; } - -.wizard .steps .current a { - background-color: #009688; } - .wizard .steps .current a:active, .wizard .steps .current a:focus, .wizard .steps .current a:hover { - background-color: #009688; } - -/* Waves ======================================= */ -.waves-effect.waves-red .waves-ripple { - background: rgba(244, 67, 54, 0.5); } - -.waves-effect.waves-pink .waves-ripple { - background: rgba(233, 30, 99, 0.5); } - -.waves-effect.waves-purple .waves-ripple { - background: rgba(156, 39, 176, 0.5); } - -.waves-effect.waves-deep-purple .waves-ripple { - background: rgba(103, 58, 183, 0.5); } - -.waves-effect.waves-indigo .waves-ripple { - background: rgba(63, 81, 181, 0.5); } - -.waves-effect.waves-blue .waves-ripple { - background: rgba(33, 150, 243, 0.5); } - -.waves-effect.waves-light-blue .waves-ripple { - background: rgba(3, 169, 244, 0.5); } - -.waves-effect.waves-cyan .waves-ripple { - background: rgba(0, 188, 212, 0.5); } - -.waves-effect.waves-teal .waves-ripple { - background: rgba(0, 150, 136, 0.5); } - -.waves-effect.waves-green .waves-ripple { - background: rgba(76, 175, 80, 0.5); } - -.waves-effect.waves-light-green .waves-ripple { - background: rgba(139, 195, 74, 0.5); } - -.waves-effect.waves-lime .waves-ripple { - background: rgba(205, 220, 57, 0.5); } - -.waves-effect.waves-yellow .waves-ripple { - background: rgba(255, 232, 33, 0.5); } - -.waves-effect.waves-amber .waves-ripple { - background: rgba(255, 193, 7, 0.5); } - -.waves-effect.waves-orange .waves-ripple { - background: rgba(255, 152, 0, 0.5); } - -.waves-effect.waves-deep-orange .waves-ripple { - background: rgba(255, 87, 34, 0.5); } - -.waves-effect.waves-brown .waves-ripple { - background: rgba(121, 85, 72, 0.5); } - -.waves-effect.waves-grey .waves-ripple { - background: rgba(158, 158, 158, 0.5); } - -.waves-effect.waves-blue-grey .waves-ripple { - background: rgba(96, 125, 139, 0.5); } - -.waves-effect.waves-black .waves-ripple { - background: rgba(0, 0, 0, 0.5); } - -.waves-effect.waves-white .waves-ripple { - background: rgba(255, 255, 255, 0.5); } - -/* Page Loader ================================= */ -.page-loader-wrapper { - z-index: 99999999; - position: fixed; - top: 0; - left: 0; - bottom: 0; - right: 0; - width: 100%; - height: 100%; - background: #eee; - overflow: hidden; - text-align: center; } - .page-loader-wrapper p { - font-size: 13px; - margin-top: 10px; - font-weight: bold; - color: #444; } - .page-loader-wrapper .loader { - position: relative; - top: calc(50% - 30px); } - -/* Preloaders ================================== */ -.md-preloader .pl-red { - stroke: #F44336; } - -.md-preloader .pl-pink { - stroke: #E91E63; } - -.md-preloader .pl-purple { - stroke: #9C27B0; } - -.md-preloader .pl-deep-purple { - stroke: #673AB7; } - -.md-preloader .pl-indigo { - stroke: #3F51B5; } - -.md-preloader .pl-blue { - stroke: #2196F3; } - -.md-preloader .pl-light-blue { - stroke: #03A9F4; } - -.md-preloader .pl-cyan { - stroke: #00BCD4; } - -.md-preloader .pl-teal { - stroke: #009688; } - -.md-preloader .pl-green { - stroke: #4CAF50; } - -.md-preloader .pl-light-green { - stroke: #8BC34A; } - -.md-preloader .pl-lime { - stroke: #CDDC39; } - -.md-preloader .pl-yellow { - stroke: #ffe821; } - -.md-preloader .pl-amber { - stroke: #FFC107; } - -.md-preloader .pl-orange { - stroke: #FF9800; } - -.md-preloader .pl-deep-orange { - stroke: #FF5722; } - -.md-preloader .pl-brown { - stroke: #795548; } - -.md-preloader .pl-grey { - stroke: #9E9E9E; } - -.md-preloader .pl-blue-grey { - stroke: #607D8B; } - -.md-preloader .pl-black { - stroke: #000000; } - -.md-preloader .pl-white { - stroke: #ffffff; } - -.preloader { - display: inline-block; - position: relative; - width: 50px; - height: 50px; - -webkit-animation: container-rotate 1568ms linear infinite; - -moz-animation: container-rotate 1568ms linear infinite; - -o-animation: container-rotate 1568ms linear infinite; - animation: container-rotate 1568ms linear infinite; } - .preloader.pl-size-xl { - width: 75px; - height: 75px; } - .preloader.pl-size-l { - width: 60px; - height: 60px; } - .preloader.pl-size-md { - width: 50px; - height: 50px; } - .preloader.pl-size-sm { - width: 40px; - height: 40px; } - .preloader.pl-size-xs { - width: 25px; - height: 25px; } - -.spinner-layer { - position: absolute; - width: 100%; - height: 100%; - border-color: #F44336; - -ms-opacity: 1; - opacity: 1; - -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - -moz-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - -o-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; } - .spinner-layer.pl-red { - border-color: #F44336; } - .spinner-layer.pl-pink { - border-color: #E91E63; } - .spinner-layer.pl-purple { - border-color: #9C27B0; } - .spinner-layer.pl-deep-purple { - border-color: #673AB7; } - .spinner-layer.pl-indigo { - border-color: #3F51B5; } - .spinner-layer.pl-blue { - border-color: #2196F3; } - .spinner-layer.pl-light-blue { - border-color: #03A9F4; } - .spinner-layer.pl-cyan { - border-color: #00BCD4; } - .spinner-layer.pl-teal { - border-color: #009688; } - .spinner-layer.pl-green { - border-color: #4CAF50; } - .spinner-layer.pl-light-green { - border-color: #8BC34A; } - .spinner-layer.pl-lime { - border-color: #CDDC39; } - .spinner-layer.pl-yellow { - border-color: #ffe821; } - .spinner-layer.pl-amber { - border-color: #FFC107; } - .spinner-layer.pl-orange { - border-color: #FF9800; } - .spinner-layer.pl-deep-orange { - border-color: #FF5722; } - .spinner-layer.pl-brown { - border-color: #795548; } - .spinner-layer.pl-grey { - border-color: #9E9E9E; } - .spinner-layer.pl-blue-grey { - border-color: #607D8B; } - .spinner-layer.pl-black { - border-color: #000000; } - .spinner-layer.pl-white { - border-color: #ffffff; } - -.right { - float: right !important; } - -.gap-patch { - position: absolute; - top: 0; - left: 45%; - width: 10%; - height: 100%; - overflow: hidden; - border-color: inherit; } - .gap-patch.circle { - width: 1000%; - left: -450%; } - -.circle-clipper { - display: inline-block; - position: relative; - width: 50%; - height: 100%; - overflow: hidden; - border-color: inherit; } - .circle-clipper .circle { - width: 200%; - height: 100%; - border-width: 3px; - border-style: solid; - border-color: inherit; - border-bottom-color: transparent !important; - -ms-border-radius: 50%; - border-radius: 50%; - -webkit-animation: none; - animation: none; - position: absolute; - top: 0; - right: 0; - bottom: 0; } - .circle-clipper.left .circle { - left: 0; - border-right-color: transparent !important; - -webkit-transform: rotate(129deg); - -moz-transform: rotate(129deg); - -ms-transform: rotate(129deg); - -o-transform: rotate(129deg); - transform: rotate(129deg); - -webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - -moz-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - -o-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; } - .circle-clipper.right .circle { - left: -100%; - border-left-color: transparent !important; - -webkit-transform: rotate(-129deg); - -moz-transform: rotate(-129deg); - -ms-transform: rotate(-129deg); - -o-transform: rotate(-129deg); - transform: rotate(-129deg); - -webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - -moz-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - -o-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; - animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; } - -@-webkit-keyframes container-rotate { - to { - -webkit-transform: rotate(360deg); - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - transform: rotate(360deg); } } - -@keyframes container-rotate { - to { - -moz-transform: rotate(360deg); - -ms-transform: rotate(360deg); - -o-transform: rotate(360deg); - -webkit-transform: rotate(360deg); - transform: rotate(360deg); } } - -@-webkit-keyframes fill-unfill-rotate { - 12.5% { - -webkit-transform: rotate(135deg); - transform: rotate(135deg); } - 25% { - -webkit-transform: rotate(270deg); - transform: rotate(270deg); } - 37.5% { - -webkit-transform: rotate(405deg); - transform: rotate(405deg); } - 50% { - -webkit-transform: rotate(540deg); - transform: rotate(540deg); } - 62.5% { - -webkit-transform: rotate(675deg); - transform: rotate(675deg); } - 75% { - -webkit-transform: rotate(810deg); - transform: rotate(810deg); } - 87.5% { - -webkit-transform: rotate(945deg); - transform: rotate(945deg); } - to { - -webkit-transform: rotate(1080deg); - transform: rotate(1080deg); } } - -@keyframes fill-unfill-rotate { - 12.5% { - transform: rotate(135deg); } - 25% { - transform: rotate(270deg); } - 37.5% { - transform: rotate(405deg); } - 50% { - transform: rotate(540deg); } - 62.5% { - transform: rotate(675deg); } - 75% { - transform: rotate(810deg); } - 87.5% { - transform: rotate(945deg); } - to { - transform: rotate(1080deg); } } - -@-webkit-keyframes left-spin { - from { - -webkit-transform: rotate(130deg); - -moz-transform: rotate(130deg); - -ms-transform: rotate(130deg); - -o-transform: rotate(130deg); - transform: rotate(130deg); } - 50% { - -webkit-transform: rotate(-5deg); - -moz-transform: rotate(-5deg); - -ms-transform: rotate(-5deg); - -o-transform: rotate(-5deg); - transform: rotate(-5deg); } - to { - -webkit-transform: rotate(130deg); - -moz-transform: rotate(130deg); - -ms-transform: rotate(130deg); - -o-transform: rotate(130deg); - transform: rotate(130deg); } } - -@keyframes left-spin { - from { - -moz-transform: rotate(130deg); - -ms-transform: rotate(130deg); - -o-transform: rotate(130deg); - -webkit-transform: rotate(130deg); - transform: rotate(130deg); } - 50% { - -moz-transform: rotate(-5deg); - -ms-transform: rotate(-5deg); - -o-transform: rotate(-5deg); - -webkit-transform: rotate(-5deg); - transform: rotate(-5deg); } - to { - -moz-transform: rotate(130deg); - -ms-transform: rotate(130deg); - -o-transform: rotate(130deg); - -webkit-transform: rotate(130deg); - transform: rotate(130deg); } } - -@-webkit-keyframes right-spin { - from { - -webkit-transform: rotate(-130deg); - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - transform: rotate(-130deg); } - 50% { - -webkit-transform: rotate(5deg); - -moz-transform: rotate(5deg); - -ms-transform: rotate(5deg); - -o-transform: rotate(5deg); - transform: rotate(5deg); } - to { - -webkit-transform: rotate(-130deg); - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - transform: rotate(-130deg); } } - -@-moz-keyframes right-spin { - from { - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); } - 50% { - -moz-transform: rotate(5deg); - -ms-transform: rotate(5deg); - -o-transform: rotate(5deg); - -webkit-transform: rotate(5deg); - transform: rotate(5deg); } - to { - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); } } - -@keyframes right-spin { - from { - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); } - 50% { - -moz-transform: rotate(5deg); - -ms-transform: rotate(5deg); - -o-transform: rotate(5deg); - -webkit-transform: rotate(5deg); - transform: rotate(5deg); } - to { - -moz-transform: rotate(-130deg); - -ms-transform: rotate(-130deg); - -o-transform: rotate(-130deg); - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); } } - -/* Navbars ===================================== */ -.navbar { - font-family: "Roboto", sans-serif; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - -ms-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); - border: none; - position: fixed; - top: 0; - left: 0; - z-index: 12; - width: 100%; } - .navbar .navbar-brand { - white-space: nowrap; - -ms-text-overflow: ellipsis; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; - overflow: hidden; } - .navbar .navbar-custom-right-menu { - float: right; } - .navbar .navbar-toggle { - text-decoration: none; - color: #fff; - width: 20px; - height: 20px; - margin-top: -4px; - margin-right: 17px; } - .navbar .navbar-toggle:before { - content: '\E8D5'; - font-family: 'Material Icons'; - font-size: 26px; } - .navbar .navbar-collapse.in { - overflow: visible; } - -.ls-closed .sidebar { - margin-left: -300px; } - -.ls-closed section.content { - margin-left: 15px; } - -.ls-closed .bars:after, .ls-closed .bars:before { - font-family: 'Material Icons'; - font-size: 24px; - position: absolute; - top: 18px; - left: 20px; - margin-right: 10px; - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - -webkit-transform: scale(0); - transform: scale(0); - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - -webkit-transition: all 0.3s; - transition: all 0.3s; } - -.ls-closed .bars:before { - content: '\E5D2'; - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - -webkit-transform: scale(1); - transform: scale(1); } - -.ls-closed .bars:after { - content: '\E5C4'; - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - -webkit-transform: scale(0); - transform: scale(0); } - -.ls-closed .navbar-brand { - margin-left: 30px; } - -.overlay-open .bars:before { - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - -webkit-transform: scale(0); - transform: scale(0); } - -.overlay-open .bars:after { - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - -webkit-transform: scale(1); - transform: scale(1); } - -.navbar-header { - padding: 10px 7px; } - .navbar-header .bars { - float: left; - text-decoration: none; } - -.navbar-nav > li > a { - padding: 7px 7px 2px 7px; - margin-top: 17px; - margin-left: 5px; } - -.navbar-nav .dropdown-menu { - margin-top: -40px !important; } - -.label-count { - position: absolute; - top: 2px; - right: 6px; - font-size: 10px; - line-height: 15px; - background-color: #000; - padding: 0 4px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - border-radius: 3px; } - -.col-red .navbar .navbar-brand, -.col-red .navbar .navbar-brand:hover, -.col-red .navbar .navbar-brand:active, -.col-red .navbar .navbar-brand:focus { - color: #fff; } - -.col-red .navbar .nav > li > a:hover, -.col-red .navbar .nav > li > a:focus, -.col-red .navbar .nav .open > a, -.col-red .navbar .nav .open > a:hover, -.col-red .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-red .navbar .nav > li > a { - color: #fff; } - -.col-red .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-red .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-pink .navbar .navbar-brand, -.col-pink .navbar .navbar-brand:hover, -.col-pink .navbar .navbar-brand:active, -.col-pink .navbar .navbar-brand:focus { - color: #fff; } - -.col-pink .navbar .nav > li > a:hover, -.col-pink .navbar .nav > li > a:focus, -.col-pink .navbar .nav .open > a, -.col-pink .navbar .nav .open > a:hover, -.col-pink .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-pink .navbar .nav > li > a { - color: #fff; } - -.col-pink .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-pink .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-purple .navbar .navbar-brand, -.col-purple .navbar .navbar-brand:hover, -.col-purple .navbar .navbar-brand:active, -.col-purple .navbar .navbar-brand:focus { - color: #fff; } - -.col-purple .navbar .nav > li > a:hover, -.col-purple .navbar .nav > li > a:focus, -.col-purple .navbar .nav .open > a, -.col-purple .navbar .nav .open > a:hover, -.col-purple .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-purple .navbar .nav > li > a { - color: #fff; } - -.col-purple .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-purple .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-deep-purple .navbar .navbar-brand, -.col-deep-purple .navbar .navbar-brand:hover, -.col-deep-purple .navbar .navbar-brand:active, -.col-deep-purple .navbar .navbar-brand:focus { - color: #fff; } - -.col-deep-purple .navbar .nav > li > a:hover, -.col-deep-purple .navbar .nav > li > a:focus, -.col-deep-purple .navbar .nav .open > a, -.col-deep-purple .navbar .nav .open > a:hover, -.col-deep-purple .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-deep-purple .navbar .nav > li > a { - color: #fff; } - -.col-deep-purple .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-deep-purple .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-indigo .navbar .navbar-brand, -.col-indigo .navbar .navbar-brand:hover, -.col-indigo .navbar .navbar-brand:active, -.col-indigo .navbar .navbar-brand:focus { - color: #fff; } - -.col-indigo .navbar .nav > li > a:hover, -.col-indigo .navbar .nav > li > a:focus, -.col-indigo .navbar .nav .open > a, -.col-indigo .navbar .nav .open > a:hover, -.col-indigo .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-indigo .navbar .nav > li > a { - color: #fff; } - -.col-indigo .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-indigo .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-blue .navbar .navbar-brand, -.col-blue .navbar .navbar-brand:hover, -.col-blue .navbar .navbar-brand:active, -.col-blue .navbar .navbar-brand:focus { - color: #fff; } - -.col-blue .navbar .nav > li > a:hover, -.col-blue .navbar .nav > li > a:focus, -.col-blue .navbar .nav .open > a, -.col-blue .navbar .nav .open > a:hover, -.col-blue .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-blue .navbar .nav > li > a { - color: #fff; } - -.col-blue .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-blue .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-light-blue .navbar .navbar-brand, -.col-light-blue .navbar .navbar-brand:hover, -.col-light-blue .navbar .navbar-brand:active, -.col-light-blue .navbar .navbar-brand:focus { - color: #fff; } - -.col-light-blue .navbar .nav > li > a:hover, -.col-light-blue .navbar .nav > li > a:focus, -.col-light-blue .navbar .nav .open > a, -.col-light-blue .navbar .nav .open > a:hover, -.col-light-blue .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-light-blue .navbar .nav > li > a { - color: #fff; } - -.col-light-blue .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-light-blue .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-cyan .navbar .navbar-brand, -.col-cyan .navbar .navbar-brand:hover, -.col-cyan .navbar .navbar-brand:active, -.col-cyan .navbar .navbar-brand:focus { - color: #fff; } - -.col-cyan .navbar .nav > li > a:hover, -.col-cyan .navbar .nav > li > a:focus, -.col-cyan .navbar .nav .open > a, -.col-cyan .navbar .nav .open > a:hover, -.col-cyan .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-cyan .navbar .nav > li > a { - color: #fff; } - -.col-cyan .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-cyan .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-teal .navbar .navbar-brand, -.col-teal .navbar .navbar-brand:hover, -.col-teal .navbar .navbar-brand:active, -.col-teal .navbar .navbar-brand:focus { - color: #fff; } - -.col-teal .navbar .nav > li > a:hover, -.col-teal .navbar .nav > li > a:focus, -.col-teal .navbar .nav .open > a, -.col-teal .navbar .nav .open > a:hover, -.col-teal .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-teal .navbar .nav > li > a { - color: #fff; } - -.col-teal .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-teal .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-green .navbar .navbar-brand, -.col-green .navbar .navbar-brand:hover, -.col-green .navbar .navbar-brand:active, -.col-green .navbar .navbar-brand:focus { - color: #fff; } - -.col-green .navbar .nav > li > a:hover, -.col-green .navbar .nav > li > a:focus, -.col-green .navbar .nav .open > a, -.col-green .navbar .nav .open > a:hover, -.col-green .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-green .navbar .nav > li > a { - color: #fff; } - -.col-green .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-green .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-light-green .navbar .navbar-brand, -.col-light-green .navbar .navbar-brand:hover, -.col-light-green .navbar .navbar-brand:active, -.col-light-green .navbar .navbar-brand:focus { - color: #fff; } - -.col-light-green .navbar .nav > li > a:hover, -.col-light-green .navbar .nav > li > a:focus, -.col-light-green .navbar .nav .open > a, -.col-light-green .navbar .nav .open > a:hover, -.col-light-green .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-light-green .navbar .nav > li > a { - color: #fff; } - -.col-light-green .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-light-green .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-lime .navbar .navbar-brand, -.col-lime .navbar .navbar-brand:hover, -.col-lime .navbar .navbar-brand:active, -.col-lime .navbar .navbar-brand:focus { - color: #fff; } - -.col-lime .navbar .nav > li > a:hover, -.col-lime .navbar .nav > li > a:focus, -.col-lime .navbar .nav .open > a, -.col-lime .navbar .nav .open > a:hover, -.col-lime .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-lime .navbar .nav > li > a { - color: #fff; } - -.col-lime .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-lime .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-yellow .navbar .navbar-brand, -.col-yellow .navbar .navbar-brand:hover, -.col-yellow .navbar .navbar-brand:active, -.col-yellow .navbar .navbar-brand:focus { - color: #fff; } - -.col-yellow .navbar .nav > li > a:hover, -.col-yellow .navbar .nav > li > a:focus, -.col-yellow .navbar .nav .open > a, -.col-yellow .navbar .nav .open > a:hover, -.col-yellow .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-yellow .navbar .nav > li > a { - color: #fff; } - -.col-yellow .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-yellow .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-amber .navbar .navbar-brand, -.col-amber .navbar .navbar-brand:hover, -.col-amber .navbar .navbar-brand:active, -.col-amber .navbar .navbar-brand:focus { - color: #fff; } - -.col-amber .navbar .nav > li > a:hover, -.col-amber .navbar .nav > li > a:focus, -.col-amber .navbar .nav .open > a, -.col-amber .navbar .nav .open > a:hover, -.col-amber .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-amber .navbar .nav > li > a { - color: #fff; } - -.col-amber .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-amber .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-orange .navbar .navbar-brand, -.col-orange .navbar .navbar-brand:hover, -.col-orange .navbar .navbar-brand:active, -.col-orange .navbar .navbar-brand:focus { - color: #fff; } - -.col-orange .navbar .nav > li > a:hover, -.col-orange .navbar .nav > li > a:focus, -.col-orange .navbar .nav .open > a, -.col-orange .navbar .nav .open > a:hover, -.col-orange .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-orange .navbar .nav > li > a { - color: #fff; } - -.col-orange .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-orange .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-deep-orange .navbar .navbar-brand, -.col-deep-orange .navbar .navbar-brand:hover, -.col-deep-orange .navbar .navbar-brand:active, -.col-deep-orange .navbar .navbar-brand:focus { - color: #fff; } - -.col-deep-orange .navbar .nav > li > a:hover, -.col-deep-orange .navbar .nav > li > a:focus, -.col-deep-orange .navbar .nav .open > a, -.col-deep-orange .navbar .nav .open > a:hover, -.col-deep-orange .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-deep-orange .navbar .nav > li > a { - color: #fff; } - -.col-deep-orange .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-deep-orange .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-brown .navbar .navbar-brand, -.col-brown .navbar .navbar-brand:hover, -.col-brown .navbar .navbar-brand:active, -.col-brown .navbar .navbar-brand:focus { - color: #fff; } - -.col-brown .navbar .nav > li > a:hover, -.col-brown .navbar .nav > li > a:focus, -.col-brown .navbar .nav .open > a, -.col-brown .navbar .nav .open > a:hover, -.col-brown .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-brown .navbar .nav > li > a { - color: #fff; } - -.col-brown .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-brown .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-grey .navbar .navbar-brand, -.col-grey .navbar .navbar-brand:hover, -.col-grey .navbar .navbar-brand:active, -.col-grey .navbar .navbar-brand:focus { - color: #fff; } - -.col-grey .navbar .nav > li > a:hover, -.col-grey .navbar .nav > li > a:focus, -.col-grey .navbar .nav .open > a, -.col-grey .navbar .nav .open > a:hover, -.col-grey .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-grey .navbar .nav > li > a { - color: #fff; } - -.col-grey .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-grey .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-blue-grey .navbar .navbar-brand, -.col-blue-grey .navbar .navbar-brand:hover, -.col-blue-grey .navbar .navbar-brand:active, -.col-blue-grey .navbar .navbar-brand:focus { - color: #fff; } - -.col-blue-grey .navbar .nav > li > a:hover, -.col-blue-grey .navbar .nav > li > a:focus, -.col-blue-grey .navbar .nav .open > a, -.col-blue-grey .navbar .nav .open > a:hover, -.col-blue-grey .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-blue-grey .navbar .nav > li > a { - color: #fff; } - -.col-blue-grey .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-blue-grey .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-black .navbar .navbar-brand, -.col-black .navbar .navbar-brand:hover, -.col-black .navbar .navbar-brand:active, -.col-black .navbar .navbar-brand:focus { - color: #fff; } - -.col-black .navbar .nav > li > a:hover, -.col-black .navbar .nav > li > a:focus, -.col-black .navbar .nav .open > a, -.col-black .navbar .nav .open > a:hover, -.col-black .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-black .navbar .nav > li > a { - color: #fff; } - -.col-black .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-black .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -.col-white .navbar .navbar-brand, -.col-white .navbar .navbar-brand:hover, -.col-white .navbar .navbar-brand:active, -.col-white .navbar .navbar-brand:focus { - color: #fff; } - -.col-white .navbar .nav > li > a:hover, -.col-white .navbar .nav > li > a:focus, -.col-white .navbar .nav .open > a, -.col-white .navbar .nav .open > a:hover, -.col-white .navbar .nav .open > a:focus { - background-color: rgba(0, 0, 0, 0.05); } - -.col-white .navbar .nav > li > a { - color: #fff; } - -.col-white .navbar .bars { - float: left; - padding: 10px 20px; - font-size: 22px; - color: #fff; - margin-right: 10px; - margin-left: -10px; - margin-top: 4px; } - -.col-white .navbar .bars:hover { - background-color: rgba(0, 0, 0, 0.08); } - -/* Dropdown Menu =============================== */ -.dropdown-menu { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - margin-top: -35px !important; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); - border: none; } - .dropdown-menu .divider { - margin: 5px 0; } - .dropdown-menu .header { - font-size: 13px; - font-weight: bold; - min-width: 270px; - border-bottom: 1px solid #eee; - text-align: center; - padding: 4px 0 6px 0; } - .dropdown-menu ul.menu { - padding-left: 0; } - .dropdown-menu ul.menu.tasks h4 { - color: #333; - font-size: 13px; - margin: 0 0 8px 0; } - .dropdown-menu ul.menu.tasks h4 small { - float: right; - margin-top: 6px; } - .dropdown-menu ul.menu.tasks .progress { - height: 7px; - margin-bottom: 7px; } - .dropdown-menu ul.menu .icon-circle { - width: 36px; - height: 36px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - -ms-border-radius: 50%; - border-radius: 50%; - color: #fff; - text-align: center; - display: inline-block; } - .dropdown-menu ul.menu .icon-circle i { - font-size: 18px; - line-height: 36px; } - .dropdown-menu ul.menu li { - border-bottom: 1px solid #eee; } - .dropdown-menu ul.menu li:last-child { - border-bottom: none; } - .dropdown-menu ul.menu li a { - padding: 7px 11px; - text-decoration: none; - -moz-transition: 0.5s; - -o-transition: 0.5s; - -webkit-transition: 0.5s; - transition: 0.5s; } - .dropdown-menu ul.menu li a:hover { - background-color: #e9e9e9; } - .dropdown-menu ul.menu .menu-info { - display: inline-block; - position: relative; - top: 3px; - left: 5px; } - .dropdown-menu ul.menu .menu-info h4 { - margin: 0; - font-size: 13px; - color: #333; } - .dropdown-menu ul.menu .menu-info p { - margin: 0; - font-size: 11px; - color: #aaa; } - .dropdown-menu ul.menu .menu-info p .material-icons { - font-size: 13px; - color: #aaa; - position: relative; - top: 2px; } - .dropdown-menu .footer a { - text-align: center; - border-top: 1px solid #eee; - padding: 5px 0 5px 0; - font-size: 12px; - margin-bottom: -5px; } - .dropdown-menu .footer a:hover { - background-color: transparent; } - .dropdown-menu > li > a { - padding: 7px 18px; - color: #666; - -moz-transition: all 0.5s; - -o-transition: all 0.5s; - -webkit-transition: all 0.5s; - transition: all 0.5s; - font-size: 14px; - line-height: 25px; } - .dropdown-menu > li > a:hover { - background-color: rgba(0, 0, 0, 0.075); } - .dropdown-menu > li > a i.material-icons { - float: left; - margin-right: 7px; - margin-top: 2px; - font-size: 20px; } - -.dropdown-animated { - -webkit-animation-duration: .3s !important; - -moz-animation-duration: .3s !important; - -o-animation-duration: .3s !important; - animation-duration: .3s !important; } - -/* Left Sidebar & Overlay ====================== */ -.overlay { - position: fixed; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); - display: none; - z-index: 10; } - -.overlay-open .sidebar { - margin-left: 0; - z-index: 99999999; } - -.sidebar { - -moz-transition: all 0.5s; - -o-transition: all 0.5s; - -webkit-transition: all 0.5s; - transition: all 0.5s; - font-family: "Roboto", sans-serif; - background: #fdfdfd; - width: 225px; - overflow: hidden; - display: inline-block; - height: calc(100vh - 70px); - position: fixed; - top: 70px; - left: 0; - -webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); - -ms-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); - box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); - z-index: 11 !important; } - .sidebar .legal { - position: absolute; - bottom: 0; - width: 100%; - border-top: 1px solid #eee; - padding: 15px; - overflow: hidden; } - .sidebar .legal .copyright { - font-size: 13px; - white-space: nowrap; - -ms-text-overflow: ellipsis; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; - overflow: hidden; } - .sidebar .legal .copyright a { - font-weight: bold; - text-decoration: none; } - .sidebar .legal .version { - white-space: nowrap; - -ms-text-overflow: ellipsis; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; - overflow: hidden; - margin-top: 5px; - font-size: 13px; } - .sidebar .user-info { - padding: 13px 15px 12px 15px; - white-space: nowrap; - position: relative; - border-bottom: 1px solid #e9e9e9; - background: url("../images/user-img-background.jpg") no-repeat no-repeat; - height: 135px; } - .sidebar .user-info .image { - margin-right: 12px; - display: inline-block; } - .sidebar .user-info .image img { - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - -ms-border-radius: 50%; - border-radius: 50%; - vertical-align: bottom !important; } - .sidebar .user-info .info-container { - cursor: default; - display: block; - position: relative; - top: 25px; } - .sidebar .user-info .info-container .name { - white-space: nowrap; - -ms-text-overflow: ellipsis; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; - overflow: hidden; - font-size: 14px; - max-width: 200px; - color: #fff; } - .sidebar .user-info .info-container .email { - white-space: nowrap; - -ms-text-overflow: ellipsis; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; - overflow: hidden; - font-size: 12px; - max-width: 200px; - color: #fff; } - .sidebar .user-info .info-container .user-helper-dropdown { - position: absolute; - right: -3px; - bottom: -12px; - -webkit-box-shadow: none; - -moz-box-shadow: none; - -ms-box-shadow: none; - box-shadow: none; - cursor: pointer; - color: #fff; } - .sidebar .menu { - position: relative; - overflow-y: auto; - height: 90vh; } - .sidebar .menu .list { - list-style: none; - padding-left: 0; } - .sidebar .menu .list li.active > :first-child span { - font-weight: bold; } - .sidebar .menu .list .header { - background: #eee; - font-size: 12px; - font-weight: 600; - padding: 8px 16px; } - .sidebar .menu .list i.material-icons { - margin-top: 4px; } - .sidebar .menu .list .menu-toggle:after, .sidebar .menu .list .menu-toggle:before { - position: absolute; - top: calc(50% - 14px); - right: 17px; - font-size: 19px; - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - -webkit-transform: scale(0); - transform: scale(0); - -moz-transition: all 0.3s; - -o-transition: all 0.3s; - -webkit-transition: all 0.3s; - transition: all 0.3s; } - .sidebar .menu .list .menu-toggle:before { - content: '+'; - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - -webkit-transform: scale(1); - transform: scale(1); } - .sidebar .menu .list .menu-toggle:after { - content: '\2013'; - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - -webkit-transform: scale(0); - transform: scale(0); } - .sidebar .menu .list .menu-toggle.toggled:before { - -moz-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - -webkit-transform: scale(0); - transform: scale(0); } - .sidebar .menu .list .menu-toggle.toggled:after { - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - -webkit-transform: scale(1); - transform: scale(1); } - .sidebar .menu .list a { - color: #747474; - position: relative; - display: inline-flex; - vertical-align: middle; - width: 100%; - padding: 10px 13px; } - .sidebar .menu .list a:hover, .sidebar .menu .list a:active, .sidebar .menu .list a:focus { - text-decoration: none !important; } - .sidebar .menu .list a small { - position: absolute; - top: calc(50% - 7.5px); - right: 15px; } - .sidebar .menu .list a span { - margin: 7px 0 7px 12px; - color: #333; - font-weight: bold; - font-size: 14px; - overflow: hidden; } - .sidebar .menu .list .ml-menu { - list-style: none; - display: none; - padding-left: 0; } - .sidebar .menu .list .ml-menu span { - font-weight: normal; - font-size: 14px; - margin: 3px 0 1px 6px; } - .sidebar .menu .list .ml-menu li a { - padding-left: 55px; - padding-top: 7px; - padding-bottom: 7px; } - .sidebar .menu .list .ml-menu li.active a.toggled:not(.menu-toggle) { - font-weight: 600; - margin-left: 5px; } - .sidebar .menu .list .ml-menu li.active a.toggled:not(.menu-toggle):before { - content: '\E315'; - font-family: 'Material Icons'; - position: relative; - font-size: 21px; - height: 20px; - top: -5px; - right: 0; } - .sidebar .menu .list .ml-menu li .ml-menu li a { - padding-left: 80px; } - .sidebar .menu .list .ml-menu li .ml-menu .ml-menu li a { - padding-left: 95px; } - -.right-sidebar { - width: 280px; - height: calc(100vh - 70px); - position: fixed; - right: -300px; - top: 70px; - background: #fdfdfd; - z-index: 11 !important; - -webkit-box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.1); - -moz-box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.1); - -ms-box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.1); - box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.1); - overflow: hidden; - -moz-transition: 0.5s; - -o-transition: 0.5s; - -webkit-transition: 0.5s; - transition: 0.5s; } - .right-sidebar.open { - right: 0; } - .right-sidebar .nav-tabs { - font-weight: 600; - font-size: 13px; - width: 100%; - margin-left: 2px; } - .right-sidebar .nav-tabs li { - text-align: center; } - .right-sidebar .nav-tabs li > a { - margin-right: 0; } - .right-sidebar .nav-tabs li:first-child { - width: 45%; } - .right-sidebar .nav-tabs li:last-child { - width: 55%; } - -/* Bootstrap Notify ============================ */ -.bootstrap-notify-container { - max-width: 320px; - text-align: center; } - -/* Jquery Nestable ============================= */ -.dd-handle { - background-color: #f9f9f9 !important; } - .dd-handle:hover { - color: #2196F3; } - -.nestable-dark-theme .dd-handle { - background: #ccc !important; - border: 1px solid #999 !important; } - -.dd3-handle { - background: #999 !important; } - -.dd3-content:hover { - color: #2196F3; } - -/* Login Page ================================== */ -.login-page { - background-color: #00BCD4; - padding-left: 0; - max-width: 360px; - margin: 5% auto; - overflow-x: hidden; } - .login-page .login-box .msg { - color: #555; - margin-bottom: 30px; - text-align: center; } - .login-page .login-box a { - font-size: 14px; - text-decoration: none; - color: #00BCD4; } - .login-page .login-box .logo { - margin-bottom: 20px; } - .login-page .login-box .logo a { - font-size: 36px; - display: block; - width: 100%; - text-align: center; - color: #fff; } - .login-page .login-box .logo small { - display: block; - width: 100%; - text-align: center; - color: #fff; - margin-top: -5px; } - -/* Sign Up Page ================================ */ -.signup-page { - background-color: #00BCD4; - padding-left: 0; - max-width: 360px; - margin: 5% auto; - overflow-x: hidden; } - .signup-page .signup-box .msg { - color: #555; - margin-bottom: 30px; - text-align: center; } - .signup-page .signup-box a { - font-size: 14px; - text-decoration: none; - color: #00BCD4; } - .signup-page .signup-box .logo { - margin-bottom: 20px; } - .signup-page .signup-box .logo a { - font-size: 36px; - display: block; - width: 100%; - text-align: center; - color: #fff; } - .signup-page .signup-box .logo small { - display: block; - width: 100%; - text-align: center; - color: #fff; - margin-top: -5px; } - -/* Forgot Password Page ======================== */ -.fp-page { - background-color: #00BCD4; - padding-left: 0; - max-width: 360px; - margin: 5% auto; - overflow-x: hidden; } - .fp-page .fp-box .msg { - color: #555; - margin-bottom: 30px; - text-align: center; } - .fp-page .fp-box a { - font-size: 14px; - text-decoration: none; - color: #00BCD4; } - .fp-page .fp-box .logo { - margin-bottom: 20px; } - .fp-page .fp-box .logo a { - font-size: 36px; - display: block; - width: 100%; - text-align: center; - color: #fff; } - .fp-page .fp-box .logo small { - display: block; - width: 100%; - text-align: center; - color: #fff; - margin-top: -5px; } - -/* 404 Not Found Page ========================== */ -.four-zero-four { - width: 100%; - text-align: center; - margin: 5% auto; } - .four-zero-four .four-zero-four-container .error-code { - font-size: 160px; } - .four-zero-four .four-zero-four-container .error-message { - font-size: 26px; - color: #333; - font-weight: bold; - margin-top: -40px; } - .four-zero-four .four-zero-four-container .button-place { - margin-top: 32px; } - -/* 500 Server Error Page ======================= */ -.five-zero-zero { - width: 100%; - text-align: center; - margin: 5% auto; } - .five-zero-zero .five-zero-zero-container .error-code { - font-size: 160px; } - .five-zero-zero .five-zero-zero-container .error-message { - font-size: 27px; - color: #333; - font-weight: bold; - margin-top: -40px; } - .five-zero-zero .five-zero-zero-container .button-place { - margin-top: 32px; } - -/* Maps ======================================== */ -/* Google Maps */ -.gmap { - width: 100%; - height: 400px; } - -/* jVector Map */ -.jvector-map { - width: 100%; - height: 600px; } - -/* Charts ====================================== */ -/* Morris */ -.morris-hover.morris-default-style { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; } - -/* Flot */ -.flot-chart { - width: 100%; - height: 320px; } - -.panel-switch-btn { - position: relative; - right: 20px; - z-index: 9; } - .panel-switch-btn label { - font-weight: bold !important; } - -.legendLabel { - width: 85px !important; - position: relative; - left: 3px; } - -#multiple_axis_chart .legendLabel { - width: 160px !important; } - -/* Sparkline */ -.sparkline { - text-align: center; } - -/* Searchbar =================================== */ -.search-bar { - position: fixed; - top: -100px; - left: 0; - z-index: 9999999; - width: 100%; - -moz-transition: 0.25s; - -o-transition: 0.25s; - -webkit-transition: 0.25s; - transition: 0.25s; } - .search-bar.open { - top: 0; } - .search-bar .search-icon { - position: absolute; - top: 20px; - left: 14px; } - .search-bar .search-icon .material-icons { - font-size: 32px; - color: #999; } - .search-bar .close-search { - position: absolute; - cursor: pointer; - font-size: 30px; - top: 16px; - right: 18px; } - .search-bar .close-search .material-icons { - color: #999; - opacity: 1; - -moz-transition: 0.5s; - -o-transition: 0.5s; - -webkit-transition: 0.5s; - transition: 0.5s; } - .search-bar .close-search .material-icons:hover { - opacity: .5; } - .search-bar input[type="text"] { - width: 100%; - font-size: 16px; - padding: 25px 60px 23px 56px; - border: none; } - -/* Jquery DataTable ============================ */ -.dataTables_wrapper { - position: relative; } - .dataTables_wrapper select { - border: none; - border-bottom: 1px solid #ddd; - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - -ms-box-shadow: none; - box-shadow: none; } - .dataTables_wrapper select:active, .dataTables_wrapper select:focus { - -webkit-box-shadow: none; - -moz-box-shadow: none; - -ms-box-shadow: none; - box-shadow: none; } - .dataTables_wrapper input[type="search"] { - -webkit-border-radius: 0; - -moz-border-radius: 0; - -ms-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - -ms-box-shadow: none; - box-shadow: none; - border: none; - font-size: 12px; - border-bottom: 1px solid #ddd; } - .dataTables_wrapper input[type="search"]:focus, .dataTables_wrapper input[type="search"]:active { - border-bottom: 2px solid #1f91f3; } - .dataTables_wrapper .dt-buttons { - float: left; } - .dataTables_wrapper .dt-buttons a.dt-button { - background-color: #607D8B; - color: #fff; - padding: 7px 12px; - margin-right: 5px; - text-decoration: none; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.16), 0 2px 10px rgba(0, 0, 0, 0.12); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - -ms-border-radius: 2px; - border-radius: 2px; - border: none; - font-size: 13px; - outline: none; } - .dataTables_wrapper .dt-buttons a.dt-button:active { - opacity: 0.8; } - -.dt-button-info { - position: fixed; - top: 50%; - left: 50%; - min-width: 400px; - text-align: center; - background-color: #fff; - border: 2px solid #999; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - border-radius: 3px; - margin-top: -100px; - margin-left: -200px; - z-index: 21; } - .dt-button-info h2 { - color: #777; } - .dt-button-info div { - color: #777; - margin-bottom: 20px; } - -/* Light Gallery ================================ */ -.lg-outer .lg-thumb-item, -.lg-outer .lg-toogle-thumb { - -webkit-border-radius: 0 !important; - -moz-border-radius: 0 !important; - -ms-border-radius: 0 !important; - border-radius: 0 !important; } - -/* For Internet Explorer 10 ===================== */ -html.ie10 .sidebar .menu .list li { - line-height: 30px; } - -html.ie10 .sidebar .menu .list .ml-menu li.active a:not(.menu-toggle).toggled:before { - top: 6px !important; - line-height: 20px !important; } - -html.ie10 .sidebar .user-info .info-container { - top: 15px; } - -html.ie10 .search-bar input[type="text"] { - padding: 26px 60px 26px 56px; } - -html.ie10 .dropdown-menu ul.menu li a { - margin-top: -22px; } - -html.ie10 .bs-searchbox .form-control { - width: 90%; } - -/* For Internet Explorer 11 ===================== */ -html.ie11 .sidebar .menu .list .ml-menu li.active a:not(.menu-toggle).toggled:before { - top: 6px !important; - line-height: 20px !important; } - -html.ie11 .sidebar .user-info .info-container { - top: 15px; } - -html.ie11 .search-bar input[type="text"] { - padding: 26px 60px 26px 56px; } - -html.ie11 .dropdown-menu ul.menu li a { - margin-top: -22px; } - -html.ie11 .bs-searchbox .form-control { - width: 90%; } - diff --git a/Plan/common/src/main/resources/assets/plan/web/css/style.min.css b/Plan/common/src/main/resources/assets/plan/web/css/style.min.css deleted file mode 100644 index 0a2eec53f..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/css/style.min.css +++ /dev/null @@ -1 +0,0 @@ -@import url(materialize.css);.navbar{font-family:"Roboto",sans-serif;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;-webkit-box-shadow:0 1px 5px rgba(0,0,0,.3);-moz-box-shadow:0 1px 5px rgba(0,0,0,.3);-ms-box-shadow:0 1px 5px rgba(0,0,0,.3);box-shadow:0 1px 5px rgba(0,0,0,.3);border:none;position:fixed;top:0;left:0;z-index:12;width:100%;}.navbar .navbar-brand{white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;}.navbar .navbar-custom-right-menu{float:right;}.navbar .navbar-toggle{text-decoration:none;color:#fff;width:20px;height:20px;margin-top:-4px;margin-right:17px;}.navbar .navbar-toggle:before{content:'';font-family:'Material Icons';font-size:26px;}.navbar .navbar-collapse.in{overflow:visible;}.ls-closed .sidebar{margin-left:-300px;}.ls-closed section.content{margin-left:15px;}.ls-closed .bars:after,.ls-closed .bars:before{font-family:'Material Icons';font-size:24px;position:absolute;top:18px;left:20px;margin-right:10px;-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);-webkit-transform:scale(0);transform:scale(0);-moz-transition:all .3s;-o-transition:all .3s;-webkit-transition:all .3s;transition:all .3s;}.ls-closed .bars:before{content:'';-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);}.ls-closed .bars:after{content:'';-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);-webkit-transform:scale(0);transform:scale(0);}.ls-closed .navbar-brand{margin-left:30px;}.overlay-open .bars:before{-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);-webkit-transform:scale(0);transform:scale(0);}.overlay-open .bars:after{-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);}.navbar-header{padding:10px 7px;}.navbar-header .bars{float:left;text-decoration:none;}.navbar-nav>li>a{padding:7px 7px 2px 7px;margin-top:17px;margin-left:5px;}.navbar-nav .dropdown-menu{margin-top:-40px !important;}.label-count{position:absolute;top:2px;right:6px;font-size:10px;line-height:15px;background-color:#000;padding:0 4px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;}.col-red .navbar .navbar-brand,.col-red .navbar .navbar-brand:hover,.col-red .navbar .navbar-brand:active,.col-red .navbar .navbar-brand:focus{color:#fff;}.col-red .navbar .nav>li>a:hover,.col-red .navbar .nav>li>a:focus,.col-red .navbar .nav .open>a,.col-red .navbar .nav .open>a:hover,.col-red .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-red .navbar .nav>li>a{color:#fff;}.col-red .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-red .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-pink .navbar .navbar-brand,.col-pink .navbar .navbar-brand:hover,.col-pink .navbar .navbar-brand:active,.col-pink .navbar .navbar-brand:focus{color:#fff;}.col-pink .navbar .nav>li>a:hover,.col-pink .navbar .nav>li>a:focus,.col-pink .navbar .nav .open>a,.col-pink .navbar .nav .open>a:hover,.col-pink .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-pink .navbar .nav>li>a{color:#fff;}.col-pink .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-pink .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-purple .navbar .navbar-brand,.col-purple .navbar .navbar-brand:hover,.col-purple .navbar .navbar-brand:active,.col-purple .navbar .navbar-brand:focus{color:#fff;}.col-purple .navbar .nav>li>a:hover,.col-purple .navbar .nav>li>a:focus,.col-purple .navbar .nav .open>a,.col-purple .navbar .nav .open>a:hover,.col-purple .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-purple .navbar .nav>li>a{color:#fff;}.col-purple .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-purple .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-deep-purple .navbar .navbar-brand,.col-deep-purple .navbar .navbar-brand:hover,.col-deep-purple .navbar .navbar-brand:active,.col-deep-purple .navbar .navbar-brand:focus{color:#fff;}.col-deep-purple .navbar .nav>li>a:hover,.col-deep-purple .navbar .nav>li>a:focus,.col-deep-purple .navbar .nav .open>a,.col-deep-purple .navbar .nav .open>a:hover,.col-deep-purple .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-deep-purple .navbar .nav>li>a{color:#fff;}.col-deep-purple .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-deep-purple .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-indigo .navbar .navbar-brand,.col-indigo .navbar .navbar-brand:hover,.col-indigo .navbar .navbar-brand:active,.col-indigo .navbar .navbar-brand:focus{color:#fff;}.col-indigo .navbar .nav>li>a:hover,.col-indigo .navbar .nav>li>a:focus,.col-indigo .navbar .nav .open>a,.col-indigo .navbar .nav .open>a:hover,.col-indigo .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-indigo .navbar .nav>li>a{color:#fff;}.col-indigo .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-indigo .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-blue .navbar .navbar-brand,.col-blue .navbar .navbar-brand:hover,.col-blue .navbar .navbar-brand:active,.col-blue .navbar .navbar-brand:focus{color:#fff;}.col-blue .navbar .nav>li>a:hover,.col-blue .navbar .nav>li>a:focus,.col-blue .navbar .nav .open>a,.col-blue .navbar .nav .open>a:hover,.col-blue .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-blue .navbar .nav>li>a{color:#fff;}.col-blue .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-blue .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-light-blue .navbar .navbar-brand,.col-light-blue .navbar .navbar-brand:hover,.col-light-blue .navbar .navbar-brand:active,.col-light-blue .navbar .navbar-brand:focus{color:#fff;}.col-light-blue .navbar .nav>li>a:hover,.col-light-blue .navbar .nav>li>a:focus,.col-light-blue .navbar .nav .open>a,.col-light-blue .navbar .nav .open>a:hover,.col-light-blue .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-light-blue .navbar .nav>li>a{color:#fff;}.col-light-blue .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-light-blue .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-cyan .navbar .navbar-brand,.col-cyan .navbar .navbar-brand:hover,.col-cyan .navbar .navbar-brand:active,.col-cyan .navbar .navbar-brand:focus{color:#fff;}.col-cyan .navbar .nav>li>a:hover,.col-cyan .navbar .nav>li>a:focus,.col-cyan .navbar .nav .open>a,.col-cyan .navbar .nav .open>a:hover,.col-cyan .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-cyan .navbar .nav>li>a{color:#fff;}.col-cyan .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-cyan .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-teal .navbar .navbar-brand,.col-teal .navbar .navbar-brand:hover,.col-teal .navbar .navbar-brand:active,.col-teal .navbar .navbar-brand:focus{color:#fff;}.col-teal .navbar .nav>li>a:hover,.col-teal .navbar .nav>li>a:focus,.col-teal .navbar .nav .open>a,.col-teal .navbar .nav .open>a:hover,.col-teal .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-teal .navbar .nav>li>a{color:#fff;}.col-teal .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-teal .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-green .navbar .navbar-brand,.col-green .navbar .navbar-brand:hover,.col-green .navbar .navbar-brand:active,.col-green .navbar .navbar-brand:focus{color:#fff;}.col-green .navbar .nav>li>a:hover,.col-green .navbar .nav>li>a:focus,.col-green .navbar .nav .open>a,.col-green .navbar .nav .open>a:hover,.col-green .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-green .navbar .nav>li>a{color:#fff;}.col-green .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-green .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-light-green .navbar .navbar-brand,.col-light-green .navbar .navbar-brand:hover,.col-light-green .navbar .navbar-brand:active,.col-light-green .navbar .navbar-brand:focus{color:#fff;}.col-light-green .navbar .nav>li>a:hover,.col-light-green .navbar .nav>li>a:focus,.col-light-green .navbar .nav .open>a,.col-light-green .navbar .nav .open>a:hover,.col-light-green .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-light-green .navbar .nav>li>a{color:#fff;}.col-light-green .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-light-green .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-lime .navbar .navbar-brand,.col-lime .navbar .navbar-brand:hover,.col-lime .navbar .navbar-brand:active,.col-lime .navbar .navbar-brand:focus{color:#fff;}.col-lime .navbar .nav>li>a:hover,.col-lime .navbar .nav>li>a:focus,.col-lime .navbar .nav .open>a,.col-lime .navbar .nav .open>a:hover,.col-lime .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-lime .navbar .nav>li>a{color:#fff;}.col-lime .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-lime .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-yellow .navbar .navbar-brand,.col-yellow .navbar .navbar-brand:hover,.col-yellow .navbar .navbar-brand:active,.col-yellow .navbar .navbar-brand:focus{color:#fff;}.col-yellow .navbar .nav>li>a:hover,.col-yellow .navbar .nav>li>a:focus,.col-yellow .navbar .nav .open>a,.col-yellow .navbar .nav .open>a:hover,.col-yellow .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-yellow .navbar .nav>li>a{color:#fff;}.col-yellow .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-yellow .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-amber .navbar .navbar-brand,.col-amber .navbar .navbar-brand:hover,.col-amber .navbar .navbar-brand:active,.col-amber .navbar .navbar-brand:focus{color:#fff;}.col-amber .navbar .nav>li>a:hover,.col-amber .navbar .nav>li>a:focus,.col-amber .navbar .nav .open>a,.col-amber .navbar .nav .open>a:hover,.col-amber .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-amber .navbar .nav>li>a{color:#fff;}.col-amber .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-amber .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-orange .navbar .navbar-brand,.col-orange .navbar .navbar-brand:hover,.col-orange .navbar .navbar-brand:active,.col-orange .navbar .navbar-brand:focus{color:#fff;}.col-orange .navbar .nav>li>a:hover,.col-orange .navbar .nav>li>a:focus,.col-orange .navbar .nav .open>a,.col-orange .navbar .nav .open>a:hover,.col-orange .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-orange .navbar .nav>li>a{color:#fff;}.col-orange .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-orange .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-deep-orange .navbar .navbar-brand,.col-deep-orange .navbar .navbar-brand:hover,.col-deep-orange .navbar .navbar-brand:active,.col-deep-orange .navbar .navbar-brand:focus{color:#fff;}.col-deep-orange .navbar .nav>li>a:hover,.col-deep-orange .navbar .nav>li>a:focus,.col-deep-orange .navbar .nav .open>a,.col-deep-orange .navbar .nav .open>a:hover,.col-deep-orange .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-deep-orange .navbar .nav>li>a{color:#fff;}.col-deep-orange .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-deep-orange .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-brown .navbar .navbar-brand,.col-brown .navbar .navbar-brand:hover,.col-brown .navbar .navbar-brand:active,.col-brown .navbar .navbar-brand:focus{color:#fff;}.col-brown .navbar .nav>li>a:hover,.col-brown .navbar .nav>li>a:focus,.col-brown .navbar .nav .open>a,.col-brown .navbar .nav .open>a:hover,.col-brown .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-brown .navbar .nav>li>a{color:#fff;}.col-brown .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-brown .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-grey .navbar .navbar-brand,.col-grey .navbar .navbar-brand:hover,.col-grey .navbar .navbar-brand:active,.col-grey .navbar .navbar-brand:focus{color:#fff;}.col-grey .navbar .nav>li>a:hover,.col-grey .navbar .nav>li>a:focus,.col-grey .navbar .nav .open>a,.col-grey .navbar .nav .open>a:hover,.col-grey .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-grey .navbar .nav>li>a{color:#fff;}.col-grey .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-grey .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-blue-grey .navbar .navbar-brand,.col-blue-grey .navbar .navbar-brand:hover,.col-blue-grey .navbar .navbar-brand:active,.col-blue-grey .navbar .navbar-brand:focus{color:#fff;}.col-blue-grey .navbar .nav>li>a:hover,.col-blue-grey .navbar .nav>li>a:focus,.col-blue-grey .navbar .nav .open>a,.col-blue-grey .navbar .nav .open>a:hover,.col-blue-grey .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-blue-grey .navbar .nav>li>a{color:#fff;}.col-blue-grey .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-blue-grey .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-black .navbar .navbar-brand,.col-black .navbar .navbar-brand:hover,.col-black .navbar .navbar-brand:active,.col-black .navbar .navbar-brand:focus{color:#fff;}.col-black .navbar .nav>li>a:hover,.col-black .navbar .nav>li>a:focus,.col-black .navbar .nav .open>a,.col-black .navbar .nav .open>a:hover,.col-black .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-black .navbar .nav>li>a{color:#fff;}.col-black .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-black .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-white .navbar .navbar-brand,.col-white .navbar .navbar-brand:hover,.col-white .navbar .navbar-brand:active,.col-white .navbar .navbar-brand:focus{color:#fff;}.col-white .navbar .nav>li>a:hover,.col-white .navbar .nav>li>a:focus,.col-white .navbar .nav .open>a,.col-white .navbar .nav .open>a:hover,.col-white .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-white .navbar .nav>li>a{color:#fff;}.col-white .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-white .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.material-icons.md-18{font-size:18px;}.material-icons.md-24{font-size:24px;}.material-icons.md-26{font-size:26px;}.material-icons.md-28{font-size:28px;}.material-icons.md-30{font-size:30px;}.material-icons.md-32{font-size:32px;}.material-icons.md-36{font-size:36px;}.material-icons.md-48{font-size:48px;}.m-l--125{margin-left:-125px;}.m-t--125{margin-top:-125px;}.m-r--125{margin-right:-125px;}.m-b--125{margin-bottom:-125px;}.m-l--120{margin-left:-120px;}.m-t--120{margin-top:-120px;}.m-r--120{margin-right:-120px;}.m-b--120{margin-bottom:-120px;}.m-l--115{margin-left:-115px;}.m-t--115{margin-top:-115px;}.m-r--115{margin-right:-115px;}.m-b--115{margin-bottom:-115px;}.m-l--110{margin-left:-110px;}.m-t--110{margin-top:-110px;}.m-r--110{margin-right:-110px;}.m-b--110{margin-bottom:-110px;}.m-l--105{margin-left:-105px;}.m-t--105{margin-top:-105px;}.m-r--105{margin-right:-105px;}.m-b--105{margin-bottom:-105px;}.m-l--100{margin-left:-100px;}.m-t--100{margin-top:-100px;}.m-r--100{margin-right:-100px;}.m-b--100{margin-bottom:-100px;}.m-l--95{margin-left:-95px;}.m-t--95{margin-top:-95px;}.m-r--95{margin-right:-95px;}.m-b--95{margin-bottom:-95px;}.m-l--90{margin-left:-90px;}.m-t--90{margin-top:-90px;}.m-r--90{margin-right:-90px;}.m-b--90{margin-bottom:-90px;}.m-l--85{margin-left:-85px;}.m-t--85{margin-top:-85px;}.m-r--85{margin-right:-85px;}.m-b--85{margin-bottom:-85px;}.m-l--80{margin-left:-80px;}.m-t--80{margin-top:-80px;}.m-r--80{margin-right:-80px;}.m-b--80{margin-bottom:-80px;}.m-l--75{margin-left:-75px;}.m-t--75{margin-top:-75px;}.m-r--75{margin-right:-75px;}.m-b--75{margin-bottom:-75px;}.m-l--70{margin-left:-70px;}.m-t--70{margin-top:-70px;}.m-r--70{margin-right:-70px;}.m-b--70{margin-bottom:-70px;}.m-l--65{margin-left:-65px;}.m-t--65{margin-top:-65px;}.m-r--65{margin-right:-65px;}.m-b--65{margin-bottom:-65px;}.m-l--60{margin-left:-60px;}.m-t--60{margin-top:-60px;}.m-r--60{margin-right:-60px;}.m-b--60{margin-bottom:-60px;}.m-l--55{margin-left:-55px;}.m-t--55{margin-top:-55px;}.m-r--55{margin-right:-55px;}.m-b--55{margin-bottom:-55px;}.m-l--50{margin-left:-50px;}.m-t--50{margin-top:-50px;}.m-r--50{margin-right:-50px;}.m-b--50{margin-bottom:-50px;}.m-l--45{margin-left:-45px;}.m-t--45{margin-top:-45px;}.m-r--45{margin-right:-45px;}.m-b--45{margin-bottom:-45px;}.m-l--40{margin-left:-40px;}.m-t--40{margin-top:-40px;}.m-r--40{margin-right:-40px;}.m-b--40{margin-bottom:-40px;}.m-l--35{margin-left:-35px;}.m-t--35{margin-top:-35px;}.m-r--35{margin-right:-35px;}.m-b--35{margin-bottom:-35px;}.m-l--30{margin-left:-30px;}.m-t--30{margin-top:-30px;}.m-r--30{margin-right:-30px;}.m-b--30{margin-bottom:-30px;}.m-l--25{margin-left:-25px;}.m-t--25{margin-top:-25px;}.m-r--25{margin-right:-25px;}.m-b--25{margin-bottom:-25px;}.m-l--20{margin-left:-20px;}.m-t--20{margin-top:-20px;}.m-r--20{margin-right:-20px;}.m-b--20{margin-bottom:-20px;}.m-l--15{margin-left:-15px;}.m-t--15{margin-top:-15px;}.m-r--15{margin-right:-15px;}.m-b--15{margin-bottom:-15px;}.m-l--10{margin-left:-10px;}.m-t--10{margin-top:-10px;}.m-r--10{margin-right:-10px;}.m-b--10{margin-bottom:-10px;}.m-l--5{margin-left:-5px;}.m-t--5{margin-top:-5px;}.m-r--5{margin-right:-5px;}.m-b--5{margin-bottom:-5px;}.m-l-0{margin-left:0;}.m-t-0{margin-top:0;}.m-r-0{margin-right:0;}.m-b-0{margin-bottom:0;}.m-l-5{margin-left:5px;}.m-t-5{margin-top:5px;}.m-r-5{margin-right:5px;}.m-b-5{margin-bottom:5px;}.m-l-10{margin-left:10px;}.m-t-10{margin-top:10px;}.m-r-10{margin-right:10px;}.m-b-10{margin-bottom:10px;}.m-l-15{margin-left:15px;}.m-t-15{margin-top:15px;}.m-r-15{margin-right:15px;}.m-b-15{margin-bottom:15px;}.m-l-20{margin-left:20px;}.m-t-20{margin-top:20px;}.m-r-20{margin-right:20px;}.m-b-20{margin-bottom:20px;}.m-l-25{margin-left:25px;}.m-t-25{margin-top:25px;}.m-r-25{margin-right:25px;}.m-b-25{margin-bottom:25px;}.m-l-30{margin-left:30px;}.m-t-30{margin-top:30px;}.m-r-30{margin-right:30px;}.m-b-30{margin-bottom:30px;}.m-l-35{margin-left:35px;}.m-t-35{margin-top:35px;}.m-r-35{margin-right:35px;}.m-b-35{margin-bottom:35px;}.m-l-40{margin-left:40px;}.m-t-40{margin-top:40px;}.m-r-40{margin-right:40px;}.m-b-40{margin-bottom:40px;}.m-l-45{margin-left:45px;}.m-t-45{margin-top:45px;}.m-r-45{margin-right:45px;}.m-b-45{margin-bottom:45px;}.m-l-50{margin-left:50px;}.m-t-50{margin-top:50px;}.m-r-50{margin-right:50px;}.m-b-50{margin-bottom:50px;}.m-l-55{margin-left:55px;}.m-t-55{margin-top:55px;}.m-r-55{margin-right:55px;}.m-b-55{margin-bottom:55px;}.m-l-60{margin-left:60px;}.m-t-60{margin-top:60px;}.m-r-60{margin-right:60px;}.m-b-60{margin-bottom:60px;}.m-l-65{margin-left:65px;}.m-t-65{margin-top:65px;}.m-r-65{margin-right:65px;}.m-b-65{margin-bottom:65px;}.m-l-70{margin-left:70px;}.m-t-70{margin-top:70px;}.m-r-70{margin-right:70px;}.m-b-70{margin-bottom:70px;}.m-l-75{margin-left:75px;}.m-t-75{margin-top:75px;}.m-r-75{margin-right:75px;}.m-b-75{margin-bottom:75px;}.m-l-80{margin-left:80px;}.m-t-80{margin-top:80px;}.m-r-80{margin-right:80px;}.m-b-80{margin-bottom:80px;}.m-l-85{margin-left:85px;}.m-t-85{margin-top:85px;}.m-r-85{margin-right:85px;}.m-b-85{margin-bottom:85px;}.m-l-90{margin-left:90px;}.m-t-90{margin-top:90px;}.m-r-90{margin-right:90px;}.m-b-90{margin-bottom:90px;}.m-l-95{margin-left:95px;}.m-t-95{margin-top:95px;}.m-r-95{margin-right:95px;}.m-b-95{margin-bottom:95px;}.m-l-100{margin-left:100px;}.m-t-100{margin-top:100px;}.m-r-100{margin-right:100px;}.m-b-100{margin-bottom:100px;}.m-l-105{margin-left:105px;}.m-t-105{margin-top:105px;}.m-r-105{margin-right:105px;}.m-b-105{margin-bottom:105px;}.m-l-110{margin-left:110px;}.m-t-110{margin-top:110px;}.m-r-110{margin-right:110px;}.m-b-110{margin-bottom:110px;}.m-l-115{margin-left:115px;}.m-t-115{margin-top:115px;}.m-r-115{margin-right:115px;}.m-b-115{margin-bottom:115px;}.m-l-120{margin-left:120px;}.m-t-120{margin-top:120px;}.m-r-120{margin-right:120px;}.m-b-120{margin-bottom:120px;}.m-l-125{margin-left:125px;}.m-t-125{margin-top:125px;}.m-r-125{margin-right:125px;}.m-b-125{margin-bottom:125px;}.margin-0{margin:0;}.p-l-0{padding-left:0;}.p-t-0{padding-top:0;}.p-r-0{padding-right:0;}.p-b-0{padding-bottom:0;}.p-l-5{padding-left:5px;}.p-t-5{padding-top:5px;}.p-r-5{padding-right:5px;}.p-b-5{padding-bottom:5px;}.p-l-10{padding-left:10px;}.p-t-10{padding-top:10px;}.p-r-10{padding-right:10px;}.p-b-10{padding-bottom:10px;}.p-l-15{padding-left:15px;}.p-t-15{padding-top:15px;}.p-r-15{padding-right:15px;}.p-b-15{padding-bottom:15px;}.p-l-20{padding-left:20px;}.p-t-20{padding-top:20px;}.p-r-20{padding-right:20px;}.p-b-20{padding-bottom:20px;}.p-l-25{padding-left:25px;}.p-t-25{padding-top:25px;}.p-r-25{padding-right:25px;}.p-b-25{padding-bottom:25px;}.p-l-30{padding-left:30px;}.p-t-30{padding-top:30px;}.p-r-30{padding-right:30px;}.p-b-30{padding-bottom:30px;}.p-l-35{padding-left:35px;}.p-t-35{padding-top:35px;}.p-r-35{padding-right:35px;}.p-b-35{padding-bottom:35px;}.p-l-40{padding-left:40px;}.p-t-40{padding-top:40px;}.p-r-40{padding-right:40px;}.p-b-40{padding-bottom:40px;}.p-l-45{padding-left:45px;}.p-t-45{padding-top:45px;}.p-r-45{padding-right:45px;}.p-b-45{padding-bottom:45px;}.p-l-50{padding-left:50px;}.p-t-50{padding-top:50px;}.p-r-50{padding-right:50px;}.p-b-50{padding-bottom:50px;}.p-l-55{padding-left:55px;}.p-t-55{padding-top:55px;}.p-r-55{padding-right:55px;}.p-b-55{padding-bottom:55px;}.p-l-60{padding-left:60px;}.p-t-60{padding-top:60px;}.p-r-60{padding-right:60px;}.p-b-60{padding-bottom:60px;}.p-l-65{padding-left:65px;}.p-t-65{padding-top:65px;}.p-r-65{padding-right:65px;}.p-b-65{padding-bottom:65px;}.p-l-70{padding-left:70px;}.p-t-70{padding-top:70px;}.p-r-70{padding-right:70px;}.p-b-70{padding-bottom:70px;}.p-l-75{padding-left:75px;}.p-t-75{padding-top:75px;}.p-r-75{padding-right:75px;}.p-b-75{padding-bottom:75px;}.p-l-80{padding-left:80px;}.p-t-80{padding-top:80px;}.p-r-80{padding-right:80px;}.p-b-80{padding-bottom:80px;}.p-l-85{padding-left:85px;}.p-t-85{padding-top:85px;}.p-r-85{padding-right:85px;}.p-b-85{padding-bottom:85px;}.p-l-90{padding-left:90px;}.p-t-90{padding-top:90px;}.p-r-90{padding-right:90px;}.p-b-90{padding-bottom:90px;}.p-l-95{padding-left:95px;}.p-t-95{padding-top:95px;}.p-r-95{padding-right:95px;}.p-b-95{padding-bottom:95px;}.p-l-100{padding-left:100px;}.p-t-100{padding-top:100px;}.p-r-100{padding-right:100px;}.p-b-100{padding-bottom:100px;}.p-l-105{padding-left:105px;}.p-t-105{padding-top:105px;}.p-r-105{padding-right:105px;}.p-b-105{padding-bottom:105px;}.p-l-110{padding-left:110px;}.p-t-110{padding-top:110px;}.p-r-110{padding-right:110px;}.p-b-110{padding-bottom:110px;}.p-l-115{padding-left:115px;}.p-t-115{padding-top:115px;}.p-r-115{padding-right:115px;}.p-b-115{padding-bottom:115px;}.p-l-120{padding-left:120px;}.p-t-120{padding-top:120px;}.p-r-120{padding-right:120px;}.p-b-120{padding-bottom:120px;}.p-l-125{padding-left:125px;}.p-t-125{padding-top:125px;}.p-r-125{padding-right:125px;}.p-b-125{padding-bottom:125px;}.padding-0{padding:0;}.font-6{font-size:6px;}.font-7{font-size:7px;}.font-8{font-size:8px;}.font-9{font-size:9px;}.font-10{font-size:10px;}.font-11{font-size:11px;}.font-12{font-size:12px;}.font-13{font-size:13px;}.font-14{font-size:14px;}.font-15{font-size:15px;}.font-16{font-size:16px;}.font-17{font-size:17px;}.font-18{font-size:18px;}.font-19{font-size:19px;}.font-20{font-size:20px;}.font-21{font-size:21px;}.font-22{font-size:22px;}.font-23{font-size:23px;}.font-24{font-size:24px;}.font-25{font-size:25px;}.font-26{font-size:26px;}.font-27{font-size:27px;}.font-28{font-size:28px;}.font-29{font-size:29px;}.font-30{font-size:30px;}.font-31{font-size:31px;}.font-32{font-size:32px;}.font-33{font-size:33px;}.font-34{font-size:34px;}.font-35{font-size:35px;}.font-36{font-size:36px;}.font-37{font-size:37px;}.font-38{font-size:38px;}.font-39{font-size:39px;}.font-40{font-size:40px;}.font-41{font-size:41px;}.font-42{font-size:42px;}.font-43{font-size:43px;}.font-44{font-size:44px;}.font-45{font-size:45px;}.font-46{font-size:46px;}.font-47{font-size:47px;}.font-48{font-size:48px;}.font-49{font-size:49px;}.font-50{font-size:50px;}.align-left{text-align:left;}.align-center{text-align:center;}.align-right{text-align:right;}.align-justify{text-align:justify;}.no-resize{resize:none;}.font-bold{font-weight:bold;}.font-italic{font-style:italic;}.font-underline{text-decoration:underline;}.font-line-through{text-decoration:line-through;}.font-overline{text-decoration:overline;}.block-header{margin-bottom:15px;}.block-header h2{margin:0 !important;color:#666 !important;font-weight:normal;font-size:16px;}.block-header h2 small{display:block;font-size:12px;margin-top:8px;color:#888;}.block-header h2 small a{font-weight:bold;color:#777;}.bg-red{background-color:#f44336 !important;color:#fff;}.bg-red .content .text,.bg-red .content .number{color:#fff !important;}.bg-pink{background-color:#e91e63 !important;color:#fff;}.bg-pink .content .text,.bg-pink .content .number{color:#fff !important;}.bg-purple{background-color:#9c27b0 !important;color:#fff;}.bg-purple .content .text,.bg-purple .content .number{color:#fff !important;}.bg-deep-purple{background-color:#673ab7 !important;color:#fff;}.bg-deep-purple .content .text,.bg-deep-purple .content .number{color:#fff !important;}.bg-indigo{background-color:#3f51b5 !important;color:#fff;}.bg-indigo .content .text,.bg-indigo .content .number{color:#fff !important;}.bg-blue{background-color:#2196f3 !important;color:#fff;}.bg-blue .content .text,.bg-blue .content .number{color:#fff !important;}.bg-light-blue{background-color:#03a9f4 !important;color:#fff;}.bg-light-blue .content .text,.bg-light-blue .content .number{color:#fff !important;}.bg-cyan{background-color:#00bcd4 !important;color:#fff;}.bg-cyan .content .text,.bg-cyan .content .number{color:#fff !important;}.bg-teal{background-color:#009688 !important;color:#fff;}.bg-teal .content .text,.bg-teal .content .number{color:#fff !important;}.bg-green{background-color:#4caf50 !important;color:#fff;}.bg-green .content .text,.bg-green .content .number{color:#fff !important;}.bg-light-green{background-color:#8bc34a !important;color:#fff;}.bg-light-green .content .text,.bg-light-green .content .number{color:#fff !important;}.bg-lime{background-color:#cddc39 !important;color:#fff;}.bg-lime .content .text,.bg-lime .content .number{color:#fff !important;}.bg-yellow{background-color:#ffe821 !important;color:#fff;}.bg-yellow .content .text,.bg-yellow .content .number{color:#fff !important;}.bg-amber{background-color:#ffc107 !important;color:#fff;}.bg-amber .content .text,.bg-amber .content .number{color:#fff !important;}.bg-orange{background-color:#ff9800 !important;color:#fff;}.bg-orange .content .text,.bg-orange .content .number{color:#fff !important;}.bg-deep-orange{background-color:#ff5722 !important;color:#fff;}.bg-deep-orange .content .text,.bg-deep-orange .content .number{color:#fff !important;}.bg-brown{background-color:#795548 !important;color:#fff;}.bg-brown .content .text,.bg-brown .content .number{color:#fff !important;}.bg-grey{background-color:#9e9e9e !important;color:#fff;}.bg-grey .content .text,.bg-grey .content .number{color:#fff !important;}.bg-blue-grey{background-color:#607d8b !important;color:#fff;}.bg-blue-grey .content .text,.bg-blue-grey .content .number{color:#fff !important;}.bg-black{background-color:#000 !important;color:#fff;}.bg-black .content .text,.bg-black .content .number{color:#fff !important;}.bg-white{background-color:#fff !important;color:#fff;}.bg-white .content .text,.bg-white .content .number{color:#fff !important;}.col-red{color:#f44336 !important;}.col-pink{color:#e91e63 !important;}.col-purple{color:#9c27b0 !important;}.col-deep-purple{color:#673ab7 !important;}.col-indigo{color:#3f51b5 !important;}.col-blue{color:#2196f3 !important;}.col-light-blue{color:#03a9f4 !important;}.col-cyan{color:#00bcd4 !important;}.col-teal{color:#009688 !important;}.col-green{color:#4caf50 !important;}.col-light-green{color:#8bc34a !important;}.col-lime{color:#cddc39 !important;}.col-yellow{color:#ffe821 !important;}.col-amber{color:#ffc107 !important;}.col-orange{color:#ff9800 !important;}.col-deep-orange{color:#ff5722 !important;}.col-brown{color:#795548 !important;}.col-grey{color:#9e9e9e !important;}.col-blue-grey{color:#607d8b !important;}.col-black{color:#000 !important;}.col-white{color:#fff !important;}@-ms-keyframes spin{from{-ms-transform:rotate(0deg);-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg);}to{-ms-transform:rotate(360deg);-moz-transform:rotate(360deg);-o-transform:rotate(360deg);-webkit-transform:rotate(360deg);transform:rotate(360deg);}}@-moz-keyframes spin{from{-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg);}to{-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);-webkit-transform:rotate(360deg);transform:rotate(360deg);}}@-webkit-keyframes spin{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg);}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg);}}@keyframes spin{from{-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg);}to{-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);-webkit-transform:rotate(360deg);transform:rotate(360deg);}}.demo-button-sizes .btn{margin-bottom:5px;}.icon-button-demo button{margin-right:5px;margin-bottom:12px;}.icon-and-text-button-demo button{margin-right:5px;margin-bottom:12px;width:16.66666666666667%;}.button-demo ul{padding-left:0;}.button-demo ul li{list-style:none;padding-left:0;display:inline-block;margin-right:7px;}.button-demo ul li .btn{display:block;min-width:175px;}.button-demo .btn{margin-right:8px;margin-bottom:13px;min-width:120px;}.demo-button-groups .btn-group{margin-right:10px;}.demo-button-toolbar .btn-toolbar{float:left;margin-right:25px;}.demo-button-nesting>.btn-group{margin-right:15px;}.demo-single-button-dropdowns>.btn-group{margin-right:10px;}.demo-splite-button-dropdowns>.btn-group{margin-right:10px;}.demo-dropup .dropup{margin-right:10px;}.demo-checkbox label,.demo-radio-button label{min-width:150px;}.demo-knob-chart div{margin-right:15px;}.demo-switch .switch{display:inline-block;min-width:170px;}.demo-switch .demo-switch-title{min-width:95px;display:inline-block;}.demo-color-box{padding:15px 0;text-align:center;margin-bottom:20px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;}.demo-color-box .color-name{font-size:16px;margin-bottom:5px;}.demo-color-box .color-code,.demo-color-box .color-class-name{font-size:13px;}.demo-image-copyright{text-align:right;font-style:italic;font-size:12px;color:#777;margin:5px 0 10px 0;}.demo-image-copyright a{font-weight:bold;color:#555 !important;}.demo-tagsinput-area{margin-bottom:50px !important;}.demo-icon-container .demo-google-material-icon{margin-bottom:5px;text-align:left;}.demo-icon-container .demo-google-material-icon .icon-name{position:relative;top:-8px;left:7px;}.demo-icon-container .demo-google-material-icon .material-icons{width:24px;}.demo-preloader .preloader{margin-right:10px;}.irs-demo{margin-bottom:40px;}.irs-demo .irs{margin-top:15px;}.right-sidebar .nav-tabs+.tab-content{padding:0;}.right-sidebar p{margin:20px 15px 15px 15px;font-weight:bold;text-align:center;}.right-sidebar #settings .setting-list{list-style:none;padding-left:0;margin-bottom:20px;}.right-sidebar #settings .setting-list li{padding:15px;position:relative;border-top:1px solid #eee;}.right-sidebar #settings .setting-list li .switch{position:absolute;top:15px;right:5px;}.demo-choose-skin{list-style:none;padding-left:0;overflow-y:hidden;}.demo-choose-skin li{border-bottom:1px solid #eee;padding:10px 10px 4px 10px;position:relative;cursor:pointer;}.demo-choose-skin li.active{background-color:#eee;}.demo-choose-skin li.active:after{font-family:'Material Icons';position:absolute;top:10px;right:10px;content:'';font-size:18px;font-weight:bold;}.demo-choose-skin li:hover{background-color:#eee;}.demo-choose-skin li div{width:24px;height:24px;display:inline-block;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;}.demo-choose-skin li span{position:relative;bottom:7px;left:5px;}.demo-choose-skin .red{background-color:#f44336;}.demo-choose-skin .pink{background-color:#e91e63;}.demo-choose-skin .purple{background-color:#9c27b0;}.demo-choose-skin .deep-purple{background-color:#673ab7;}.demo-choose-skin .indigo{background-color:#3f51b5;}.demo-choose-skin .blue{background-color:#2196f3;}.demo-choose-skin .light-blue{background-color:#03a9f4;}.demo-choose-skin .cyan{background-color:#00bcd4;}.demo-choose-skin .teal{background-color:#009688;}.demo-choose-skin .green{background-color:#4caf50;}.demo-choose-skin .light-green{background-color:#8bc34a;}.demo-choose-skin .lime{background-color:#cddc39;}.demo-choose-skin .yellow{background-color:#ffe821;}.demo-choose-skin .amber{background-color:#ffc107;}.demo-choose-skin .orange{background-color:#ff9800;}.demo-choose-skin .deep-orange{background-color:#ff5722;}.demo-choose-skin .brown{background-color:#795548;}.demo-choose-skin .grey{background-color:#9e9e9e;}.demo-choose-skin .blue-grey{background-color:#607d8b;}.demo-choose-skin .black{background-color:#000;}.demo-choose-skin .white{background-color:#fff;}@media(max-width:767px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:35px;width:73%;}.navbar .navbar-header{display:inline-block;margin-bottom:-6px;width:calc(100% + 30px);}.navbar .nav>li{display:inline-block;}.navbar .navbar-nav{margin-top:-10px;margin-bottom:1px;margin-left:-7px;}.navbar .navbar-nav .open .dropdown-menu{background-color:#fff;position:absolute;}.navbar .dropdown-menu{margin-left:-50px;}.navbar .js-right-sidebar{margin-top:15px;}.dt-buttons{float:none !important;text-align:center;margin-bottom:15px;}.panel-switch-btn{top:12px;right:0 !important;}}@media(min-width:768px) and (max-width:991px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:20px;}}@media(min-width:992px) and (max-width:1169px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:20px;}}body{background-color:#e9e9e9;-moz-transition:all .5s;-o-transition:all .5s;-webkit-transition:all .5s;transition:all .5s;font-family:'Roboto',Arial,Tahoma,sans-serif;}h1,h2,h3,h4,h5,h6{font-weight:bold;}button,input,select,a{outline:none !important;}.no-animate{-o-transition-property:none !important;-moz-transition-property:none !important;-ms-transition-property:none !important;-webkit-transition-property:none !important;transition-property:none !important;-o-transform:none !important;-moz-transform:none !important;-ms-transform:none !important;-webkit-transform:none !important;transform:none !important;-webkit-animation:none !important;-moz-animation:none !important;-o-animation:none !important;-ms-animation:none !important;animation:none !important;}section.content{margin:100px 15px 0 315px;-moz-transition:.5s;-o-transition:.5s;-webkit-transition:.5s;transition:.5s;}.dashboard-flot-chart{height:275px;}.dashboard-donut-chart{height:265px;}.dashboard-line-chart{height:250px;}.dashboard-stat-list{list-style:none;padding-left:0;margin-top:40px;}.dashboard-stat-list li{padding:16px 0 0 0;}.dashboard-stat-list li small{font-size:8px;}.dashboard-task-infos .progress{height:10px;margin-bottom:0;position:relative;top:6px;}.btn:focus{outline:none !important;}.btn-circle{border:none;outline:none !important;overflow:hidden;width:40px;height:40px;-webkit-border-radius:50%;-moz-border-radius:50%;-ms-border-radius:50%;border-radius:50%;}.btn-circle i{font-size:18px;position:relative;left:-1px;}.btn-link{font-weight:bold;color:#333;-moz-transition:.5s;-o-transition:.5s;-webkit-transition:.5s;transition:.5s;}.btn-link:active,.btn-link:focus{text-decoration:none;color:#333;}.btn-link:hover{text-decoration:none;color:#333;background-color:#ddd;}.btn-circle-lg{border:none;outline:none !important;overflow:hidden;width:50px;height:50px;-webkit-border-radius:50% !important;-moz-border-radius:50% !important;-ms-border-radius:50% !important;border-radius:50% !important;}.btn-circle-lg i{font-size:26px !important;position:relative !important;left:0 !important;top:6px !important;}.btn:not(.btn-link):not(.btn-circle){box-shadow:0 2px 5px rgba(0,0,0,.16),0 2px 10px rgba(0,0,0,.12);-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;border-radius:2px;border:none;font-size:13px;outline:none;}.btn:not(.btn-link):not(.btn-circle):hover{outline:none;}.btn:not(.btn-link):not(.btn-circle) i{font-size:20px;position:relative;top:3px;}.btn:not(.btn-link):not(.btn-circle) span{position:relative;top:-2px;margin-left:3px;}.btn-warning,.btn-warning:hover,.btn-warning:active,.btn-warning:focus{background-color:#ff9600 !important;}.btn-danger,.btn-danger:hover,.btn-danger:active,.btn-danger:focus{background-color:#fb483a !important;}.btn-info,.btn-info:hover,.btn-info:active,.btn-info:focus{background-color:#00b0e4 !important;}.btn-success,.btn-success:hover,.btn-success:active,.btn-success:focus{background-color:#2b982b !important;}.btn-primary,.btn-primary:hover,.btn-primary:active,.btn-primary:focus{background-color:#1f91f3 !important;}.btn-default,.btn-default:hover,.btn-default:active,.btn-default:focus{background-color:#fff !important;}.btn-group,.btn-group-vertical{box-shadow:0 2px 5px rgba(0,0,0,.16),0 2px 10px rgba(0,0,0,.12);}.btn-group .btn,.btn-group-vertical .btn{box-shadow:none !important;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.btn-group .btn .caret,.btn-group-vertical .btn .caret{position:relative;bottom:1px;}.btn-group .btn-group,.btn-group-vertical .btn-group{box-shadow:none !important;}.btn-group .btn+.dropdown-toggle,.btn-group-vertical .btn+.dropdown-toggle{border-left:1px solid rgba(0,0,0,.08) !important;}.bootstrap-tagsinput{-webkit-box-shadow:none !important;-moz-box-shadow:none !important;-ms-box-shadow:none !important;box-shadow:none !important;border:none !important;}.noUi-target{-webkit-touch-callout:none;-webkit-user-select:none;-ms-touch-action:none;touch-action:none;-ms-user-select:none;-moz-user-select:none;user-select:none;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;direction:ltr;}.noUi-target *{-webkit-touch-callout:none;-webkit-user-select:none;-ms-touch-action:none;touch-action:none;-ms-user-select:none;-moz-user-select:none;user-select:none;-moz-box-sizing:border-box;box-sizing:border-box;}.noUi-base{width:100%;height:100%;position:relative;z-index:1;}.noUi-origin{position:absolute;right:0;top:6px;left:0;bottom:0;}.noUi-handle{position:relative;z-index:1;}.noUi-stacking .noUi-handle{z-index:10;}.noUi-state-tap .noUi-origin{-webkit-transition:left .25s,top .25s;transition:left .25s,top .25s;}.noUi-state-drag *{cursor:inherit !important;}.noUi-base{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);}.noUi-horizontal{height:18px;}.noUi-horizontal .noUi-handle{width:34px;height:28px;left:-17px;top:-6px;}.noUi-vertical{width:18px;}.noUi-vertical .noUi-handle{width:28px;height:34px;left:-6px;top:-17px;}.noUi-background{background:#fafafa;box-shadow:inset 0 1px 1px #f0f0f0;}.noUi-connect{background:#3fb8af;box-shadow:inset 0 0 3px rgba(51,51,51,.45);-webkit-transition:background 450ms;transition:background 450ms;}.noUi-origin{border-radius:2px;}.noUi-target{border-radius:4px;border:1px solid #d3d3d3;box-shadow:inset 0 1px 1px #f0f0f0,0 3px 6px -5px #bbb;}.noUi-target.noUi-connect{box-shadow:inset 0 0 3px rgba(51,51,51,.45),0 3px 6px -5px #bbb;}.noUi-dragable{cursor:w-resize;}.noUi-vertical .noUi-dragable{cursor:n-resize;}.noUi-handle{border:1px solid #d9d9d9;border-radius:3px;background:#fff;cursor:default;box-shadow:inset 0 0 1px #fff,inset 0 1px 7px #ebebeb,0 3px 6px -3px #bbb;}.noUi-active{box-shadow:inset 0 0 1px #fff,inset 0 1px 7px #ddd,0 3px 6px -3px #bbb;}.noUi-handle:before{content:"";display:block;position:absolute;height:14px;width:1px;background:#e8e7e6;left:14px;top:6px;}.noUi-handle:after{content:"";display:block;position:absolute;height:14px;width:1px;background:#e8e7e6;left:14px;top:6px;left:17px;}.noUi-vertical .noUi-handle:before{width:14px;height:1px;left:6px;top:14px;}.noUi-vertical .noUi-handle:after{width:14px;height:1px;left:6px;top:14px;top:17px;}[disabled].noUi-connect,[disabled] .noUi-connect{background:#b8b8b8;}[disabled].noUi-origin,[disabled] .noUi-handle{cursor:not-allowed;}.noUi-target{box-shadow:none;border:none;}.noUi-base{height:15px;top:-6px;}.noUi-background{height:3px;top:6px;background-color:#bfbfbf;box-shadow:none;}.noUi-horizontal{height:3px;}.noUi-connect{height:3px;top:6px;background-color:#26a69a;box-shadow:none;}.noUi-horizontal .noUi-handle{width:15px;height:15px;border-radius:50%;box-shadow:none;background-color:#26a69a;border:none;left:-5px;top:-6px;transition:width .2s cubic-bezier(.215,.61,.355,1),height .2s cubic-bezier(.215,.61,.355,1),left .2s cubic-bezier(.215,.61,.355,1),top .2s cubic-bezier(.215,.61,.355,1);}.noUi-handle:before,.noUi-handle:after{content:none;}.noUi-target .noUi-active.noUi-handle{-webkit-box-shadow:0 0 20px rgba(0,0,0,.5);-moz-box-shadow:0 0 20px rgba(0,0,0,.5);-ms-box-shadow:0 0 20px rgba(0,0,0,.5);box-shadow:0 0 20px rgba(0,0,0,.5);}.noUi-target .range-label{position:absolute;height:30px;width:30px;top:-17px;left:-2px;background-color:#26a69a;border-radius:50%;transition:border-radius .25s cubic-bezier(.215,.61,.355,1),transform .25s cubic-bezier(.215,.61,.355,1);transform:scale(.5) rotate(-45deg);transform-origin:50% 100%;}.noUi-target .noUi-active .range-label{border-radius:15px 15px 15px 0;transform:rotate(-45deg) translate(23px,-25px);}.range-label span{width:100%;text-align:center;color:#fff;font-size:12px;transform:rotate(45deg);opacity:0;position:absolute;top:7px;left:-1px;transition:opacity .25s cubic-bezier(.215,.61,.355,1);}.noUi-active .range-label span{opacity:1;}.ms-container{width:auto !important;}.ms-container .ms-list{-webkit-box-shadow:none !important;-moz-box-shadow:none !important;-ms-box-shadow:none !important;box-shadow:none !important;-webkit-border-radius:0 !important;-moz-border-radius:0 !important;-ms-border-radius:0 !important;border-radius:0 !important;}.ms-container .ms-list.ms-focus{-webkit-box-shadow:none !important;-moz-box-shadow:none !important;-ms-box-shadow:none !important;box-shadow:none !important;}.ms-container .ms-selectable,.ms-container .ms-selection{min-width:250px !important;}.ms-container .ms-selectable li.ms-hover,.ms-container .ms-selection li.ms-hover{color:#000 !important;background-color:#e6e6e6 !important;}.ms-container .ms-selectable li.ms-elem-selectable,.ms-container .ms-selectable li.ms-elem-selection,.ms-container .ms-selection li.ms-elem-selectable,.ms-container .ms-selection li.ms-elem-selection{padding:9px 15px 6px 15px !important;}.ms-container .ms-optgroup-label{padding:5px 0 0 8px !important;}.card{background:#fff;min-height:50px;box-shadow:0 2px 10px rgba(0,0,0,.2);position:relative;margin-bottom:30px;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;border-radius:2px;}.card .card-inside-title{margin-top:25px;margin-bottom:15px;display:block;font-size:15px;color:#000;}.card .card-inside-title small{color:#999;display:block;font-size:11px;margin-top:5px;}.card .card-inside-title small a{color:#777;font-weight:bold;}.card .card-inside-title:first-child{margin-top:0;}.card .bg-red,.card .bg-pink,.card .bg-purple,.card .bg-deep-purple,.card .bg-indigo,.card .bg-blue,.card .bg-light-blue,.card .bg-cyan,.card .bg-teal,.card .bg-green,.card .bg-light-green,.card .bg-lime,.card .bg-yellow,.card .bg-amber,.card .bg-orange,.card .bg-deep-orange,.card .bg-brown,.card .bg-grey,.card .bg-blue-grey,.card .bg-black{border-bottom:none !important;color:#fff !important;}.card .bg-red h2,.card .bg-red small,.card .bg-red .material-icons,.card .bg-pink h2,.card .bg-pink small,.card .bg-pink .material-icons,.card .bg-purple h2,.card .bg-purple small,.card .bg-purple .material-icons,.card .bg-deep-purple h2,.card .bg-deep-purple small,.card .bg-deep-purple .material-icons,.card .bg-indigo h2,.card .bg-indigo small,.card .bg-indigo .material-icons,.card .bg-blue h2,.card .bg-blue small,.card .bg-blue .material-icons,.card .bg-light-blue h2,.card .bg-light-blue small,.card .bg-light-blue .material-icons,.card .bg-cyan h2,.card .bg-cyan small,.card .bg-cyan .material-icons,.card .bg-teal h2,.card .bg-teal small,.card .bg-teal .material-icons,.card .bg-green h2,.card .bg-green small,.card .bg-green .material-icons,.card .bg-light-green h2,.card .bg-light-green small,.card .bg-light-green .material-icons,.card .bg-lime h2,.card .bg-lime small,.card .bg-lime .material-icons,.card .bg-yellow h2,.card .bg-yellow small,.card .bg-yellow .material-icons,.card .bg-amber h2,.card .bg-amber small,.card .bg-amber .material-icons,.card .bg-orange h2,.card .bg-orange small,.card .bg-orange .material-icons,.card .bg-deep-orange h2,.card .bg-deep-orange small,.card .bg-deep-orange .material-icons,.card .bg-brown h2,.card .bg-brown small,.card .bg-brown .material-icons,.card .bg-grey h2,.card .bg-grey small,.card .bg-grey .material-icons,.card .bg-blue-grey h2,.card .bg-blue-grey small,.card .bg-blue-grey .material-icons,.card .bg-black h2,.card .bg-black small,.card .bg-black .material-icons{color:#fff !important;}.card .bg-red .badge,.card .bg-pink .badge,.card .bg-purple .badge,.card .bg-deep-purple .badge,.card .bg-indigo .badge,.card .bg-blue .badge,.card .bg-light-blue .badge,.card .bg-cyan .badge,.card .bg-teal .badge,.card .bg-green .badge,.card .bg-light-green .badge,.card .bg-lime .badge,.card .bg-yellow .badge,.card .bg-amber .badge,.card .bg-orange .badge,.card .bg-deep-orange .badge,.card .bg-brown .badge,.card .bg-grey .badge,.card .bg-blue-grey .badge,.card .bg-black .badge{background-color:#fff;color:#555;}.card .header{color:#555;padding:20px;position:relative;border-bottom:1px solid rgba(204,204,204,.35);}.card .header .header-dropdown{position:absolute;top:20px;right:15px;list-style:none;}.card .header .header-dropdown .dropdown-menu li{display:block !important;}.card .header .header-dropdown li{display:inline-block;}.card .header .header-dropdown i{font-size:20px;color:#999;-moz-transition:all .5s;-o-transition:all .5s;-webkit-transition:all .5s;transition:all .5s;}.card .header .header-dropdown i:hover{color:#000;}.card .header h2{margin:0;font-size:18px;font-weight:normal;color:#111;}.card .header h2 small{display:block;font-size:12px;margin-top:5px;color:#999;line-height:15px;}.card .header h2 small a{font-weight:bold;color:#777;}.card .header .col-xs-12 h2{margin-top:5px;}.card .body{font-size:14px;color:#555;padding:20px;}.card .body .col-xs-1,.card .body .col-sm-1,.card .body .col-md-1,.card .body .col-lg-1{margin-bottom:20px;}.card .body .col-xs-2,.card .body .col-sm-2,.card .body .col-md-2,.card .body .col-lg-2{margin-bottom:20px;}.card .body .col-xs-3,.card .body .col-sm-3,.card .body .col-md-3,.card .body .col-lg-3{margin-bottom:20px;}.card .body .col-xs-4,.card .body .col-sm-4,.card .body .col-md-4,.card .body .col-lg-4{margin-bottom:20px;}.card .body .col-xs-5,.card .body .col-sm-5,.card .body .col-md-5,.card .body .col-lg-5{margin-bottom:20px;}.card .body .col-xs-6,.card .body .col-sm-6,.card .body .col-md-6,.card .body .col-lg-6{margin-bottom:20px;}.card .body .col-xs-7,.card .body .col-sm-7,.card .body .col-md-7,.card .body .col-lg-7{margin-bottom:20px;}.card .body .col-xs-8,.card .body .col-sm-8,.card .body .col-md-8,.card .body .col-lg-8{margin-bottom:20px;}.card .body .col-xs-9,.card .body .col-sm-9,.card .body .col-md-9,.card .body .col-lg-9{margin-bottom:20px;}.card .body .col-xs-10,.card .body .col-sm-10,.card .body .col-md-10,.card .body .col-lg-10{margin-bottom:20px;}.card .body .col-xs-11,.card .body .col-sm-11,.card .body .col-md-11,.card .body .col-lg-11{margin-bottom:20px;}.card .body .col-xs-12,.card .body .col-sm-12,.card .body .col-md-12,.card .body .col-lg-12{margin-bottom:20px;}.info-box{box-shadow:0 2px 10px rgba(0,0,0,.2);height:80px;display:flex;cursor:default;background-color:#fff;position:relative;overflow:hidden;margin-bottom:30px;}.info-box .icon{display:inline-block;text-align:center;background-color:rgba(0,0,0,.12);width:80px;}.info-box .icon i{color:#fff;font-size:50px;line-height:80px;}.info-box .icon .chart.chart-bar{height:100%;line-height:100px;}.info-box .icon .chart.chart-bar canvas{vertical-align:baseline !important;}.info-box .icon .chart.chart-pie{height:100%;line-height:123px;}.info-box .icon .chart.chart-pie canvas{vertical-align:baseline !important;}.info-box .icon .chart.chart-line{height:100%;line-height:115px;}.info-box .icon .chart.chart-line canvas{vertical-align:baseline !important;}.info-box .content{display:inline-block;padding:7px 10px;}.info-box .content .text{font-size:13px;margin-top:11px;color:#555;}.info-box .content .number{font-weight:normal;font-size:26px;margin-top:-4px;color:#555;}.info-box.hover-zoom-effect .icon{overflow:hidden;}.info-box.hover-zoom-effect .icon i{-moz-transition:all .3s ease;-o-transition:all .3s ease;-webkit-transition:all .3s ease;transition:all .3s ease;}.info-box.hover-zoom-effect:hover .icon i{opacity:.4;-moz-transform:rotate(-32deg) scale(1.4);-ms-transform:rotate(-32deg) scale(1.4);-o-transform:rotate(-32deg) scale(1.4);-webkit-transform:rotate(-32deg) scale(1.4);transform:rotate(-32deg) scale(1.4);}.info-box.hover-expand-effect:after{background-color:rgba(0,0,0,.05);content:".";position:absolute;left:80px;top:0;width:0;height:100%;color:transparent;-moz-transition:all .95s;-o-transition:all .95s;-webkit-transition:all .95s;transition:all .95s;}.info-box.hover-expand-effect:hover:after{width:100%;}.info-box-2{box-shadow:0 2px 10px rgba(0,0,0,.2);height:80px;display:flex;cursor:default;background-color:#fff;position:relative;overflow:hidden;margin-bottom:30px;}.info-box-2 .icon{display:inline-block;text-align:center;width:80px;}.info-box-2 .icon i{color:#fff;font-size:50px;line-height:80px;}.info-box-2 .chart.chart-bar{height:100%;line-height:105px;}.info-box-2 .chart.chart-bar canvas{vertical-align:baseline !important;}.info-box-2 .chart.chart-pie{height:100%;line-height:123px;}.info-box-2 .chart.chart-pie canvas{vertical-align:baseline !important;}.info-box-2 .chart.chart-line{height:100%;line-height:115px;}.info-box-2 .chart.chart-line canvas{vertical-align:baseline !important;}.info-box-2 .content{display:inline-block;padding:7px 10px;}.info-box-2 .content .text{font-size:13px;margin-top:11px;color:#555;}.info-box-2 .content .number{font-weight:normal;font-size:26px;margin-top:-4px;color:#555;}.info-box-2.hover-zoom-effect .icon{overflow:hidden;}.info-box-2.hover-zoom-effect .icon i{-moz-transition:all .3s ease;-o-transition:all .3s ease;-webkit-transition:all .3s ease;transition:all .3s ease;}.info-box-2.hover-zoom-effect:hover .icon i{opacity:.4;-moz-transform:rotate(-32deg) scale(1.4);-ms-transform:rotate(-32deg) scale(1.4);-o-transform:rotate(-32deg) scale(1.4);-webkit-transform:rotate(-32deg) scale(1.4);transform:rotate(-32deg) scale(1.4);}.info-box-2.hover-expand-effect:after{background-color:rgba(0,0,0,.05);content:".";position:absolute;left:0;top:0;width:0;height:100%;color:transparent;-moz-transition:all .95s;-o-transition:all .95s;-webkit-transition:all .95s;transition:all .95s;}.info-box-2.hover-expand-effect:hover:after{width:100%;}.info-box-3{box-shadow:0 2px 10px rgba(0,0,0,.2);height:80px;display:flex;cursor:default;background-color:#fff;position:relative;overflow:hidden;margin-bottom:30px;}.info-box-3 .icon{position:absolute;right:10px;bottom:2px;text-align:center;}.info-box-3 .icon i{color:rgba(0,0,0,.15);font-size:60px;}.info-box-3 .chart{margin-right:5px;}.info-box-3 .chart.chart-bar{height:100%;line-height:50px;}.info-box-3 .chart.chart-bar canvas{vertical-align:baseline !important;}.info-box-3 .chart.chart-pie{height:100%;line-height:34px;}.info-box-3 .chart.chart-pie canvas{vertical-align:baseline !important;}.info-box-3 .chart.chart-line{height:100%;line-height:40px;}.info-box-3 .chart.chart-line canvas{vertical-align:baseline !important;}.info-box-3 .content{display:inline-block;padding:7px 16px;}.info-box-3 .content .text{font-size:13px;margin-top:11px;color:#555;}.info-box-3 .content .number{font-weight:normal;font-size:26px;margin-top:-4px;color:#555;}.info-box-3.hover-zoom-effect .icon i{-moz-transition:all .3s ease;-o-transition:all .3s ease;-webkit-transition:all .3s ease;transition:all .3s ease;}.info-box-3.hover-zoom-effect:hover .icon i{opacity:.4;-moz-transform:rotate(-32deg) scale(1.4);-ms-transform:rotate(-32deg) scale(1.4);-o-transform:rotate(-32deg) scale(1.4);-webkit-transform:rotate(-32deg) scale(1.4);transform:rotate(-32deg) scale(1.4);}.info-box-3.hover-expand-effect:after{background-color:rgba(0,0,0,.05);content:".";position:absolute;left:0;top:0;width:0;height:100%;color:transparent;-moz-transition:all .95s;-o-transition:all .95s;-webkit-transition:all .95s;transition:all .95s;}.info-box-3.hover-expand-effect:hover:after{width:100%;}.info-box-4{box-shadow:0 2px 10px rgba(0,0,0,.2);height:80px;display:flex;cursor:default;background-color:#fff;position:relative;overflow:hidden;margin-bottom:30px;}.info-box-4 .icon{position:absolute;right:10px;bottom:2px;text-align:center;}.info-box-4 .icon i{color:rgba(0,0,0,.15);font-size:60px;}.info-box-4 .chart{margin-right:5px;}.info-box-4 .chart.chart-bar{height:100%;line-height:50px;}.info-box-4 .chart.chart-bar canvas{vertical-align:baseline !important;}.info-box-4 .chart.chart-pie{height:100%;line-height:34px;}.info-box-4 .chart.chart-pie canvas{vertical-align:baseline !important;}.info-box-4 .chart.chart-line{height:100%;line-height:40px;}.info-box-4 .chart.chart-line canvas{vertical-align:baseline !important;}.info-box-4 .content{display:inline-block;padding:7px 16px;}.info-box-4 .content .text{font-size:13px;margin-top:11px;color:#555;}.info-box-4 .content .number{font-weight:normal;font-size:26px;margin-top:-4px;color:#555;}.info-box-4.hover-zoom-effect .icon i{-moz-transition:all .3s ease;-o-transition:all .3s ease;-webkit-transition:all .3s ease;transition:all .3s ease;}.info-box-4.hover-zoom-effect:hover .icon i{opacity:.4;-moz-transform:rotate(-32deg) scale(1.4);-ms-transform:rotate(-32deg) scale(1.4);-o-transform:rotate(-32deg) scale(1.4);-webkit-transform:rotate(-32deg) scale(1.4);transform:rotate(-32deg) scale(1.4);}.info-box-4.hover-expand-effect:after{background-color:rgba(0,0,0,.05);content:".";position:absolute;left:0;top:0;width:0;height:100%;color:transparent;-moz-transition:all .95s;-o-transition:all .95s;-webkit-transition:all .95s;transition:all .95s;}.info-box-4.hover-expand-effect:hover:after{width:100%;}.alert{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;box-shadow:none;border:none;color:#fff !important;}.alert .alert-link{color:#fff;text-decoration:underline;font-weight:bold;}.alert-success{background-color:#2b982b;}.alert-info{background-color:#00b0e4;}.alert-warning{background-color:#ff9600 !important;}.alert-danger{background-color:#fb483a !important;}.alert-dismissible .close{color:#fff;opacity:1;border:none;text-shadow:none;}.sweet-alert{-webkit-border-radius:0 !important;-moz-border-radius:0 !important;-ms-border-radius:0 !important;border-radius:0 !important;}.sweet-alert p{font-size:14px !important;}.sweet-alert .sa-input-error{top:23px !important;right:13px !important;}.sweet-alert h2{font-size:18px !important;margin:0 0 5px 0 !important;}.sweet-alert button{font-size:15px !important;-webkit-border-radius:0 !important;-moz-border-radius:0 !important;-ms-border-radius:0 !important;border-radius:0 !important;padding:5px 20px !important;}[type="checkbox"]+label{padding-left:26px;height:25px;line-height:21px;font-size:13px;font-weight:normal;}[type="checkbox"]:checked+label:before{top:-4px;left:-2px;width:11px;height:19px;}[type="checkbox"]:checked.chk-col-red+label:before{border-right:2px solid #f44336;border-bottom:2px solid #f44336;}[type="checkbox"]:checked.chk-col-pink+label:before{border-right:2px solid #e91e63;border-bottom:2px solid #e91e63;}[type="checkbox"]:checked.chk-col-purple+label:before{border-right:2px solid #9c27b0;border-bottom:2px solid #9c27b0;}[type="checkbox"]:checked.chk-col-deep-purple+label:before{border-right:2px solid #673ab7;border-bottom:2px solid #673ab7;}[type="checkbox"]:checked.chk-col-indigo+label:before{border-right:2px solid #3f51b5;border-bottom:2px solid #3f51b5;}[type="checkbox"]:checked.chk-col-blue+label:before{border-right:2px solid #2196f3;border-bottom:2px solid #2196f3;}[type="checkbox"]:checked.chk-col-light-blue+label:before{border-right:2px solid #03a9f4;border-bottom:2px solid #03a9f4;}[type="checkbox"]:checked.chk-col-cyan+label:before{border-right:2px solid #00bcd4;border-bottom:2px solid #00bcd4;}[type="checkbox"]:checked.chk-col-teal+label:before{border-right:2px solid #009688;border-bottom:2px solid #009688;}[type="checkbox"]:checked.chk-col-green+label:before{border-right:2px solid #4caf50;border-bottom:2px solid #4caf50;}[type="checkbox"]:checked.chk-col-light-green+label:before{border-right:2px solid #8bc34a;border-bottom:2px solid #8bc34a;}[type="checkbox"]:checked.chk-col-lime+label:before{border-right:2px solid #cddc39;border-bottom:2px solid #cddc39;}[type="checkbox"]:checked.chk-col-yellow+label:before{border-right:2px solid #ffe821;border-bottom:2px solid #ffe821;}[type="checkbox"]:checked.chk-col-amber+label:before{border-right:2px solid #ffc107;border-bottom:2px solid #ffc107;}[type="checkbox"]:checked.chk-col-orange+label:before{border-right:2px solid #ff9800;border-bottom:2px solid #ff9800;}[type="checkbox"]:checked.chk-col-deep-orange+label:before{border-right:2px solid #ff5722;border-bottom:2px solid #ff5722;}[type="checkbox"]:checked.chk-col-brown+label:before{border-right:2px solid #795548;border-bottom:2px solid #795548;}[type="checkbox"]:checked.chk-col-grey+label:before{border-right:2px solid #9e9e9e;border-bottom:2px solid #9e9e9e;}[type="checkbox"]:checked.chk-col-blue-grey+label:before{border-right:2px solid #607d8b;border-bottom:2px solid #607d8b;}[type="checkbox"]:checked.chk-col-black+label:before{border-right:2px solid #000;border-bottom:2px solid #000;}[type="checkbox"]:checked.chk-col-white+label:before{border-right:2px solid #fff;border-bottom:2px solid #fff;}[type="checkbox"].filled-in:checked+label:after{top:0;width:20px;height:20px;border:2px solid #26a69a;background-color:#26a69a;z-index:0;}[type="checkbox"].filled-in:checked+label:before{border-right:2px solid #fff !important;border-bottom:2px solid #fff !important;}[type="checkbox"].filled-in:checked.chk-col-red+label:after{border:2px solid #f44336;background-color:#f44336;}[type="checkbox"].filled-in:checked.chk-col-pink+label:after{border:2px solid #e91e63;background-color:#e91e63;}[type="checkbox"].filled-in:checked.chk-col-purple+label:after{border:2px solid #9c27b0;background-color:#9c27b0;}[type="checkbox"].filled-in:checked.chk-col-deep-purple+label:after{border:2px solid #673ab7;background-color:#673ab7;}[type="checkbox"].filled-in:checked.chk-col-indigo+label:after{border:2px solid #3f51b5;background-color:#3f51b5;}[type="checkbox"].filled-in:checked.chk-col-blue+label:after{border:2px solid #2196f3;background-color:#2196f3;}[type="checkbox"].filled-in:checked.chk-col-light-blue+label:after{border:2px solid #03a9f4;background-color:#03a9f4;}[type="checkbox"].filled-in:checked.chk-col-cyan+label:after{border:2px solid #00bcd4;background-color:#00bcd4;}[type="checkbox"].filled-in:checked.chk-col-teal+label:after{border:2px solid #009688;background-color:#009688;}[type="checkbox"].filled-in:checked.chk-col-green+label:after{border:2px solid #4caf50;background-color:#4caf50;}[type="checkbox"].filled-in:checked.chk-col-light-green+label:after{border:2px solid #8bc34a;background-color:#8bc34a;}[type="checkbox"].filled-in:checked.chk-col-lime+label:after{border:2px solid #cddc39;background-color:#cddc39;}[type="checkbox"].filled-in:checked.chk-col-yellow+label:after{border:2px solid #ffe821;background-color:#ffe821;}[type="checkbox"].filled-in:checked.chk-col-amber+label:after{border:2px solid #ffc107;background-color:#ffc107;}[type="checkbox"].filled-in:checked.chk-col-orange+label:after{border:2px solid #ff9800;background-color:#ff9800;}[type="checkbox"].filled-in:checked.chk-col-deep-orange+label:after{border:2px solid #ff5722;background-color:#ff5722;}[type="checkbox"].filled-in:checked.chk-col-brown+label:after{border:2px solid #795548;background-color:#795548;}[type="checkbox"].filled-in:checked.chk-col-grey+label:after{border:2px solid #9e9e9e;background-color:#9e9e9e;}[type="checkbox"].filled-in:checked.chk-col-blue-grey+label:after{border:2px solid #607d8b;background-color:#607d8b;}[type="checkbox"].filled-in:checked.chk-col-black+label:after{border:2px solid #000;background-color:#000;}[type="checkbox"].filled-in:checked.chk-col-white+label:after{border:2px solid #fff;background-color:#fff;}[type="radio"]:not(:checked)+label{padding-left:26px;height:25px;line-height:25px;font-size:13px;font-weight:normal;}[type="radio"]:checked+label{padding-left:26px;height:25px;line-height:25px;font-size:13px;font-weight:normal;}[type="radio"].radio-col-red:checked+label:after{background-color:#f44336;border-color:#f44336;}[type="radio"].radio-col-pink:checked+label:after{background-color:#e91e63;border-color:#e91e63;}[type="radio"].radio-col-purple:checked+label:after{background-color:#9c27b0;border-color:#9c27b0;}[type="radio"].radio-col-deep-purple:checked+label:after{background-color:#673ab7;border-color:#673ab7;}[type="radio"].radio-col-indigo:checked+label:after{background-color:#3f51b5;border-color:#3f51b5;}[type="radio"].radio-col-blue:checked+label:after{background-color:#2196f3;border-color:#2196f3;}[type="radio"].radio-col-light-blue:checked+label:after{background-color:#03a9f4;border-color:#03a9f4;}[type="radio"].radio-col-cyan:checked+label:after{background-color:#00bcd4;border-color:#00bcd4;}[type="radio"].radio-col-teal:checked+label:after{background-color:#009688;border-color:#009688;}[type="radio"].radio-col-green:checked+label:after{background-color:#4caf50;border-color:#4caf50;}[type="radio"].radio-col-light-green:checked+label:after{background-color:#8bc34a;border-color:#8bc34a;}[type="radio"].radio-col-lime:checked+label:after{background-color:#cddc39;border-color:#cddc39;}[type="radio"].radio-col-yellow:checked+label:after{background-color:#ffe821;border-color:#ffe821;}[type="radio"].radio-col-amber:checked+label:after{background-color:#ffc107;border-color:#ffc107;}[type="radio"].radio-col-orange:checked+label:after{background-color:#ff9800;border-color:#ff9800;}[type="radio"].radio-col-deep-orange:checked+label:after{background-color:#ff5722;border-color:#ff5722;}[type="radio"].radio-col-brown:checked+label:after{background-color:#795548;border-color:#795548;}[type="radio"].radio-col-grey:checked+label:after{background-color:#9e9e9e;border-color:#9e9e9e;}[type="radio"].radio-col-blue-grey:checked+label:after{background-color:#607d8b;border-color:#607d8b;}[type="radio"].radio-col-black:checked+label:after{background-color:#000;border-color:#000;}[type="radio"].radio-col-white:checked+label:after{background-color:#fff;border-color:#fff;}[type="radio"].with-gap.radio-col-red:checked+label:before{border:2px solid #f44336;}[type="radio"].with-gap.radio-col-red:checked+label:after{background-color:#f44336;border:2px solid #f44336;}[type="radio"].with-gap.radio-col-pink:checked+label:before{border:2px solid #e91e63;}[type="radio"].with-gap.radio-col-pink:checked+label:after{background-color:#e91e63;border:2px solid #e91e63;}[type="radio"].with-gap.radio-col-purple:checked+label:before{border:2px solid #9c27b0;}[type="radio"].with-gap.radio-col-purple:checked+label:after{background-color:#9c27b0;border:2px solid #9c27b0;}[type="radio"].with-gap.radio-col-deep-purple:checked+label:before{border:2px solid #673ab7;}[type="radio"].with-gap.radio-col-deep-purple:checked+label:after{background-color:#673ab7;border:2px solid #673ab7;}[type="radio"].with-gap.radio-col-indigo:checked+label:before{border:2px solid #3f51b5;}[type="radio"].with-gap.radio-col-indigo:checked+label:after{background-color:#3f51b5;border:2px solid #3f51b5;}[type="radio"].with-gap.radio-col-blue:checked+label:before{border:2px solid #2196f3;}[type="radio"].with-gap.radio-col-blue:checked+label:after{background-color:#2196f3;border:2px solid #2196f3;}[type="radio"].with-gap.radio-col-light-blue:checked+label:before{border:2px solid #03a9f4;}[type="radio"].with-gap.radio-col-light-blue:checked+label:after{background-color:#03a9f4;border:2px solid #03a9f4;}[type="radio"].with-gap.radio-col-cyan:checked+label:before{border:2px solid #00bcd4;}[type="radio"].with-gap.radio-col-cyan:checked+label:after{background-color:#00bcd4;border:2px solid #00bcd4;}[type="radio"].with-gap.radio-col-teal:checked+label:before{border:2px solid #009688;}[type="radio"].with-gap.radio-col-teal:checked+label:after{background-color:#009688;border:2px solid #009688;}[type="radio"].with-gap.radio-col-green:checked+label:before{border:2px solid #4caf50;}[type="radio"].with-gap.radio-col-green:checked+label:after{background-color:#4caf50;border:2px solid #4caf50;}[type="radio"].with-gap.radio-col-light-green:checked+label:before{border:2px solid #8bc34a;}[type="radio"].with-gap.radio-col-light-green:checked+label:after{background-color:#8bc34a;border:2px solid #8bc34a;}[type="radio"].with-gap.radio-col-lime:checked+label:before{border:2px solid #cddc39;}[type="radio"].with-gap.radio-col-lime:checked+label:after{background-color:#cddc39;border:2px solid #cddc39;}[type="radio"].with-gap.radio-col-yellow:checked+label:before{border:2px solid #ffe821;}[type="radio"].with-gap.radio-col-yellow:checked+label:after{background-color:#ffe821;border:2px solid #ffe821;}[type="radio"].with-gap.radio-col-amber:checked+label:before{border:2px solid #ffc107;}[type="radio"].with-gap.radio-col-amber:checked+label:after{background-color:#ffc107;border:2px solid #ffc107;}[type="radio"].with-gap.radio-col-orange:checked+label:before{border:2px solid #ff9800;}[type="radio"].with-gap.radio-col-orange:checked+label:after{background-color:#ff9800;border:2px solid #ff9800;}[type="radio"].with-gap.radio-col-deep-orange:checked+label:before{border:2px solid #ff5722;}[type="radio"].with-gap.radio-col-deep-orange:checked+label:after{background-color:#ff5722;border:2px solid #ff5722;}[type="radio"].with-gap.radio-col-brown:checked+label:before{border:2px solid #795548;}[type="radio"].with-gap.radio-col-brown:checked+label:after{background-color:#795548;border:2px solid #795548;}[type="radio"].with-gap.radio-col-grey:checked+label:before{border:2px solid #9e9e9e;}[type="radio"].with-gap.radio-col-grey:checked+label:after{background-color:#9e9e9e;border:2px solid #9e9e9e;}[type="radio"].with-gap.radio-col-blue-grey:checked+label:before{border:2px solid #607d8b;}[type="radio"].with-gap.radio-col-blue-grey:checked+label:after{background-color:#607d8b;border:2px solid #607d8b;}[type="radio"].with-gap.radio-col-black:checked+label:before{border:2px solid #000;}[type="radio"].with-gap.radio-col-black:checked+label:after{background-color:#000;border:2px solid #000;}[type="radio"].with-gap.radio-col-white:checked+label:before{border:2px solid #fff;}[type="radio"].with-gap.radio-col-white:checked+label:after{background-color:#fff;border:2px solid #fff;}.switch label{font-weight:normal;font-size:13px;}.switch label .lever{margin:0 14px;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-red:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(244,67,54,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-red{background-color:rgba(244,67,54,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-red:after{background-color:#f44336;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-pink:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(233,30,99,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-pink{background-color:rgba(233,30,99,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-pink:after{background-color:#e91e63;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-purple:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(156,39,176,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-purple{background-color:rgba(156,39,176,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-purple:after{background-color:#9c27b0;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-deep-purple:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(103,58,183,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-deep-purple{background-color:rgba(103,58,183,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-deep-purple:after{background-color:#673ab7;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-indigo:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(63,81,181,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-indigo{background-color:rgba(63,81,181,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-indigo:after{background-color:#3f51b5;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-blue:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(33,150,243,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-blue{background-color:rgba(33,150,243,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-blue:after{background-color:#2196f3;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-light-blue:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(3,169,244,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-light-blue{background-color:rgba(3,169,244,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-light-blue:after{background-color:#03a9f4;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-cyan:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(0,188,212,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-cyan{background-color:rgba(0,188,212,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-cyan:after{background-color:#00bcd4;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-teal:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(0,150,136,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-teal{background-color:rgba(0,150,136,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-teal:after{background-color:#009688;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-green:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(76,175,80,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-green{background-color:rgba(76,175,80,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-green:after{background-color:#4caf50;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-light-green:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(139,195,74,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-light-green{background-color:rgba(139,195,74,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-light-green:after{background-color:#8bc34a;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-lime:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(205,220,57,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-lime{background-color:rgba(205,220,57,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-lime:after{background-color:#cddc39;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-yellow:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(255,232,33,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-yellow{background-color:rgba(255,232,33,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-yellow:after{background-color:#ffe821;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-amber:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(255,193,7,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-amber{background-color:rgba(255,193,7,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-amber:after{background-color:#ffc107;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-orange:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(255,152,0,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-orange{background-color:rgba(255,152,0,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-orange:after{background-color:#ff9800;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-deep-orange:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(255,87,34,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-deep-orange{background-color:rgba(255,87,34,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-deep-orange:after{background-color:#ff5722;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-brown:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(121,85,72,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-brown{background-color:rgba(121,85,72,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-brown:after{background-color:#795548;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-grey:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(158,158,158,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-grey{background-color:rgba(158,158,158,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-grey:after{background-color:#9e9e9e;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-blue-grey:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(96,125,139,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-blue-grey{background-color:rgba(96,125,139,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-blue-grey:after{background-color:#607d8b;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-black:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(0,0,0,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-black{background-color:rgba(0,0,0,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-black:after{background-color:#000;}.switch label input[type=checkbox]:checked:not(:disabled)~.lever.switch-col-white:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,.4),0 0 0 15px rgba(255,255,255,.1);}.switch label input[type=checkbox]:checked+.lever.switch-col-white{background-color:rgba(255,255,255,.5);}.switch label input[type=checkbox]:checked+.lever.switch-col-white:after{background-color:#fff;}.dtp div.dtp-date,.dtp div.dtp-time{background:#007d72;}.dtp>.dtp-content>.dtp-date-view>header.dtp-header{background:#009688;}.dtp .dtp-buttons .dtp-btn-ok{margin-left:10px;}.dtp .dtp-buttons .dtp-btn-clear{margin-right:10px !important;}.dtp .p10>a{color:#fff;}.dtp div.dtp-actual-year{font-size:1.5em;color:#fff;}.dtp table.dtp-picker-days tr td a.selected{background:#007d72;color:#fff;}.bootstrap-select{box-shadow:none !important;border-bottom:1px solid #ddd !important;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.bootstrap-select .dropdown-toggle:focus,.bootstrap-select .dropdown-toggle:active{outline:none !important;}.bootstrap-select .bs-searchbox,.bootstrap-select .bs-actionsbox,.bootstrap-select .bs-donebutton{padding:0 0 5px 0;border-bottom:1px solid #e9e9e9;}.bootstrap-select .bs-searchbox .form-control,.bootstrap-select .bs-actionsbox .form-control,.bootstrap-select .bs-donebutton .form-control{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;-webkit-box-shadow:none !important;-moz-box-shadow:none !important;-ms-box-shadow:none !important;box-shadow:none !important;border:none;margin-left:30px;}.bootstrap-select .bs-searchbox{position:relative;}.bootstrap-select .bs-searchbox:after{content:'';font-family:'Material Icons';position:absolute;top:0;left:10px;font-size:25px;}.bootstrap-select ul.dropdown-menu{margin-top:0 !important;}.bootstrap-select .dropdown-menu li.selected a{background-color:#eee !important;color:#555 !important;}.bootstrap-select .dropdown-menu .active a{background-color:transparent;color:#333 !important;}.bootstrap-select .dropdown-menu .notify{background-color:#f44336 !important;color:#fff !important;border:none !important;}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark{margin-top:9px;}.tooltip{font-size:13px;}.tooltip .tooltip-inner{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.popover{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;border:1px solid rgba(0,0,0,.08);}.popover .popover-title{font-weight:bold;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;background-color:#e9e9e9;border-bottom:1px solid #ddd;}.popover .popover-content{font-size:13px;color:#777;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.nav-tabs{border-bottom:2px solid #eee;}.nav-tabs>li{position:relative;top:3px;left:-2px;}.nav-tabs>li>a{border:none !important;color:#999 !important;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.nav-tabs>li>a:hover,.nav-tabs>li>a:active,.nav-tabs>li>a:focus{background-color:transparent !important;}.nav-tabs>li>a:before{content:'';position:absolute;left:0;width:100%;height:0;border-bottom:2px solid #2196f3;bottom:2px;-moz-transform:scaleX(0);-ms-transform:scaleX(0);-o-transform:scaleX(0);-webkit-transform:scaleX(0);transform:scaleX(0);-moz-transition:.1s ease-in;-o-transition:.1s ease-in;-webkit-transition:.1s ease-in;transition:.1s ease-in;}.nav-tabs>li>a .material-icons{position:relative;top:7px;margin-bottom:8px;}.nav-tabs li.active a{color:#222 !important;}.nav-tabs li.active a:hover,.nav-tabs li.active a:active,.nav-tabs li.active a:focus{background-color:transparent !important;}.nav-tabs li.active a:before{-moz-transform:scaleX(1);-ms-transform:scaleX(1);-o-transform:scaleX(1);-webkit-transform:scaleX(1);transform:scaleX(1);}.nav-tabs+.tab-content{padding:15px 0;}.nav-tabs.tab-col-red>li>a:before{border-bottom:2px solid #f44336;}.nav-tabs.tab-col-pink>li>a:before{border-bottom:2px solid #e91e63;}.nav-tabs.tab-col-purple>li>a:before{border-bottom:2px solid #9c27b0;}.nav-tabs.tab-col-deep-purple>li>a:before{border-bottom:2px solid #673ab7;}.nav-tabs.tab-col-indigo>li>a:before{border-bottom:2px solid #3f51b5;}.nav-tabs.tab-col-blue>li>a:before{border-bottom:2px solid #2196f3;}.nav-tabs.tab-col-light-blue>li>a:before{border-bottom:2px solid #03a9f4;}.nav-tabs.tab-col-cyan>li>a:before{border-bottom:2px solid #00bcd4;}.nav-tabs.tab-col-teal>li>a:before{border-bottom:2px solid #009688;}.nav-tabs.tab-col-green>li>a:before{border-bottom:2px solid #4caf50;}.nav-tabs.tab-col-light-green>li>a:before{border-bottom:2px solid #8bc34a;}.nav-tabs.tab-col-lime>li>a:before{border-bottom:2px solid #cddc39;}.nav-tabs.tab-col-yellow>li>a:before{border-bottom:2px solid #ffe821;}.nav-tabs.tab-col-amber>li>a:before{border-bottom:2px solid #ffc107;}.nav-tabs.tab-col-orange>li>a:before{border-bottom:2px solid #ff9800;}.nav-tabs.tab-col-deep-orange>li>a:before{border-bottom:2px solid #ff5722;}.nav-tabs.tab-col-brown>li>a:before{border-bottom:2px solid #795548;}.nav-tabs.tab-col-grey>li>a:before{border-bottom:2px solid #9e9e9e;}.nav-tabs.tab-col-blue-grey>li>a:before{border-bottom:2px solid #607d8b;}.nav-tabs.tab-col-black>li>a:before{border-bottom:2px solid #000;}.nav-tabs.tab-col-white>li>a:before{border-bottom:2px solid #fff;}.thumbnail{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.thumbnail p:not(button){color:#999;font-size:14px;}.thumbnail h3{font-weight:bold;font-size:17px;}.modal .modal-header{border:none;padding:25px 25px 5px 25px;}.modal .modal-header .modal-title{font-weight:bold;font-size:16px;}.modal .modal-content{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;box-shadow:0 5px 20px rgba(0,0,0,.31) !important;border:none;}.modal .modal-content .modal-body{color:#777;padding:15px 25px;}.modal .modal-footer{border:none;}.modal-col-red{background-color:#f44336;}.modal-col-red .modal-body,.modal-col-red .modal-title{color:#fff !important;}.modal-col-red .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-red .modal-footer .btn-link{color:#fff !important;}.modal-col-red .modal-footer .btn-link:hover,.modal-col-red .modal-footer .btn-link:active,.modal-col-red .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-pink{background-color:#e91e63;}.modal-col-pink .modal-body,.modal-col-pink .modal-title{color:#fff !important;}.modal-col-pink .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-pink .modal-footer .btn-link{color:#fff !important;}.modal-col-pink .modal-footer .btn-link:hover,.modal-col-pink .modal-footer .btn-link:active,.modal-col-pink .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-purple{background-color:#9c27b0;}.modal-col-purple .modal-body,.modal-col-purple .modal-title{color:#fff !important;}.modal-col-purple .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-purple .modal-footer .btn-link{color:#fff !important;}.modal-col-purple .modal-footer .btn-link:hover,.modal-col-purple .modal-footer .btn-link:active,.modal-col-purple .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-deep-purple{background-color:#673ab7;}.modal-col-deep-purple .modal-body,.modal-col-deep-purple .modal-title{color:#fff !important;}.modal-col-deep-purple .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-deep-purple .modal-footer .btn-link{color:#fff !important;}.modal-col-deep-purple .modal-footer .btn-link:hover,.modal-col-deep-purple .modal-footer .btn-link:active,.modal-col-deep-purple .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-indigo{background-color:#3f51b5;}.modal-col-indigo .modal-body,.modal-col-indigo .modal-title{color:#fff !important;}.modal-col-indigo .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-indigo .modal-footer .btn-link{color:#fff !important;}.modal-col-indigo .modal-footer .btn-link:hover,.modal-col-indigo .modal-footer .btn-link:active,.modal-col-indigo .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-blue{background-color:#2196f3;}.modal-col-blue .modal-body,.modal-col-blue .modal-title{color:#fff !important;}.modal-col-blue .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-blue .modal-footer .btn-link{color:#fff !important;}.modal-col-blue .modal-footer .btn-link:hover,.modal-col-blue .modal-footer .btn-link:active,.modal-col-blue .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-light-blue{background-color:#03a9f4;}.modal-col-light-blue .modal-body,.modal-col-light-blue .modal-title{color:#fff !important;}.modal-col-light-blue .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-light-blue .modal-footer .btn-link{color:#fff !important;}.modal-col-light-blue .modal-footer .btn-link:hover,.modal-col-light-blue .modal-footer .btn-link:active,.modal-col-light-blue .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-cyan{background-color:#00bcd4;}.modal-col-cyan .modal-body,.modal-col-cyan .modal-title{color:#fff !important;}.modal-col-cyan .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-cyan .modal-footer .btn-link{color:#fff !important;}.modal-col-cyan .modal-footer .btn-link:hover,.modal-col-cyan .modal-footer .btn-link:active,.modal-col-cyan .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-teal{background-color:#009688;}.modal-col-teal .modal-body,.modal-col-teal .modal-title{color:#fff !important;}.modal-col-teal .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-teal .modal-footer .btn-link{color:#fff !important;}.modal-col-teal .modal-footer .btn-link:hover,.modal-col-teal .modal-footer .btn-link:active,.modal-col-teal .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-green{background-color:#4caf50;}.modal-col-green .modal-body,.modal-col-green .modal-title{color:#fff !important;}.modal-col-green .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-green .modal-footer .btn-link{color:#fff !important;}.modal-col-green .modal-footer .btn-link:hover,.modal-col-green .modal-footer .btn-link:active,.modal-col-green .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-light-green{background-color:#8bc34a;}.modal-col-light-green .modal-body,.modal-col-light-green .modal-title{color:#fff !important;}.modal-col-light-green .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-light-green .modal-footer .btn-link{color:#fff !important;}.modal-col-light-green .modal-footer .btn-link:hover,.modal-col-light-green .modal-footer .btn-link:active,.modal-col-light-green .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-lime{background-color:#cddc39;}.modal-col-lime .modal-body,.modal-col-lime .modal-title{color:#fff !important;}.modal-col-lime .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-lime .modal-footer .btn-link{color:#fff !important;}.modal-col-lime .modal-footer .btn-link:hover,.modal-col-lime .modal-footer .btn-link:active,.modal-col-lime .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-yellow{background-color:#ffe821;}.modal-col-yellow .modal-body,.modal-col-yellow .modal-title{color:#fff !important;}.modal-col-yellow .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-yellow .modal-footer .btn-link{color:#fff !important;}.modal-col-yellow .modal-footer .btn-link:hover,.modal-col-yellow .modal-footer .btn-link:active,.modal-col-yellow .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-amber{background-color:#ffc107;}.modal-col-amber .modal-body,.modal-col-amber .modal-title{color:#fff !important;}.modal-col-amber .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-amber .modal-footer .btn-link{color:#fff !important;}.modal-col-amber .modal-footer .btn-link:hover,.modal-col-amber .modal-footer .btn-link:active,.modal-col-amber .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-orange{background-color:#ff9800;}.modal-col-orange .modal-body,.modal-col-orange .modal-title{color:#fff !important;}.modal-col-orange .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-orange .modal-footer .btn-link{color:#fff !important;}.modal-col-orange .modal-footer .btn-link:hover,.modal-col-orange .modal-footer .btn-link:active,.modal-col-orange .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-deep-orange{background-color:#ff5722;}.modal-col-deep-orange .modal-body,.modal-col-deep-orange .modal-title{color:#fff !important;}.modal-col-deep-orange .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-deep-orange .modal-footer .btn-link{color:#fff !important;}.modal-col-deep-orange .modal-footer .btn-link:hover,.modal-col-deep-orange .modal-footer .btn-link:active,.modal-col-deep-orange .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-brown{background-color:#795548;}.modal-col-brown .modal-body,.modal-col-brown .modal-title{color:#fff !important;}.modal-col-brown .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-brown .modal-footer .btn-link{color:#fff !important;}.modal-col-brown .modal-footer .btn-link:hover,.modal-col-brown .modal-footer .btn-link:active,.modal-col-brown .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-grey{background-color:#9e9e9e;}.modal-col-grey .modal-body,.modal-col-grey .modal-title{color:#fff !important;}.modal-col-grey .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-grey .modal-footer .btn-link{color:#fff !important;}.modal-col-grey .modal-footer .btn-link:hover,.modal-col-grey .modal-footer .btn-link:active,.modal-col-grey .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-blue-grey{background-color:#607d8b;}.modal-col-blue-grey .modal-body,.modal-col-blue-grey .modal-title{color:#fff !important;}.modal-col-blue-grey .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-blue-grey .modal-footer .btn-link{color:#fff !important;}.modal-col-blue-grey .modal-footer .btn-link:hover,.modal-col-blue-grey .modal-footer .btn-link:active,.modal-col-blue-grey .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-black{background-color:#000;}.modal-col-black .modal-body,.modal-col-black .modal-title{color:#fff !important;}.modal-col-black .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-black .modal-footer .btn-link{color:#fff !important;}.modal-col-black .modal-footer .btn-link:hover,.modal-col-black .modal-footer .btn-link:active,.modal-col-black .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.modal-col-white{background-color:#fff;}.modal-col-white .modal-body,.modal-col-white .modal-title{color:#fff !important;}.modal-col-white .modal-footer{background-color:rgba(0,0,0,.12);}.modal-col-white .modal-footer .btn-link{color:#fff !important;}.modal-col-white .modal-footer .btn-link:hover,.modal-col-white .modal-footer .btn-link:active,.modal-col-white .modal-footer .btn-link:focus{background-color:rgba(0,0,0,.12);}.label{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.label-primary{background-color:#1f91f3;}.label-success{background-color:#2b982b;}.label-info{background-color:#00b0e4;}.label-warning{background-color:#ff9600;}.label-danger{background-color:#fb483a;}.collapse .well,.collapse.in .well,.collapsing .well{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;margin-bottom:0;}.table tbody tr td,.table tbody tr th{padding:10px;border-top:1px solid #eee;border-bottom:1px solid #eee;}.table tbody tr.primary td,.table tbody tr.primary th{background-color:#1f91f3;color:#fff;}.table tbody tr.success td,.table tbody tr.success th{background-color:#2b982b;color:#fff;}.table tbody tr.info td,.table tbody tr.info th{background-color:#00b0e4;color:#fff;}.table tbody tr.warning td,.table tbody tr.warning th{background-color:#ff9600;color:#fff;}.table tbody tr.danger td,.table tbody tr.danger th{background-color:#fb483a;color:#fff;}.table thead tr th{padding:10px;border-bottom:1px solid #eee;}.table-bordered{border-top:1px solid #eee;}.table-bordered tbody tr td,.table-bordered tbody tr th{padding:10px;border:1px solid #eee;}.table-bordered thead tr th{padding:10px;border:1px solid #eee;}.panel-group .panel-col-red{border:1px solid #f44336;}.panel-group .panel-col-red .panel-title{background-color:#f44336 !important;color:#fff;}.panel-group .panel-col-red .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-pink{border:1px solid #e91e63;}.panel-group .panel-col-pink .panel-title{background-color:#e91e63 !important;color:#fff;}.panel-group .panel-col-pink .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-purple{border:1px solid #9c27b0;}.panel-group .panel-col-purple .panel-title{background-color:#9c27b0 !important;color:#fff;}.panel-group .panel-col-purple .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-deep-purple{border:1px solid #673ab7;}.panel-group .panel-col-deep-purple .panel-title{background-color:#673ab7 !important;color:#fff;}.panel-group .panel-col-deep-purple .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-indigo{border:1px solid #3f51b5;}.panel-group .panel-col-indigo .panel-title{background-color:#3f51b5 !important;color:#fff;}.panel-group .panel-col-indigo .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-blue{border:1px solid #2196f3;}.panel-group .panel-col-blue .panel-title{background-color:#2196f3 !important;color:#fff;}.panel-group .panel-col-blue .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-light-blue{border:1px solid #03a9f4;}.panel-group .panel-col-light-blue .panel-title{background-color:#03a9f4 !important;color:#fff;}.panel-group .panel-col-light-blue .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-cyan{border:1px solid #00bcd4;}.panel-group .panel-col-cyan .panel-title{background-color:#00bcd4 !important;color:#fff;}.panel-group .panel-col-cyan .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-teal{border:1px solid #009688;}.panel-group .panel-col-teal .panel-title{background-color:#009688 !important;color:#fff;}.panel-group .panel-col-teal .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-green{border:1px solid #4caf50;}.panel-group .panel-col-green .panel-title{background-color:#4caf50 !important;color:#fff;}.panel-group .panel-col-green .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-light-green{border:1px solid #8bc34a;}.panel-group .panel-col-light-green .panel-title{background-color:#8bc34a !important;color:#fff;}.panel-group .panel-col-light-green .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-lime{border:1px solid #cddc39;}.panel-group .panel-col-lime .panel-title{background-color:#cddc39 !important;color:#fff;}.panel-group .panel-col-lime .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-yellow{border:1px solid #ffe821;}.panel-group .panel-col-yellow .panel-title{background-color:#ffe821 !important;color:#fff;}.panel-group .panel-col-yellow .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-amber{border:1px solid #ffc107;}.panel-group .panel-col-amber .panel-title{background-color:#ffc107 !important;color:#fff;}.panel-group .panel-col-amber .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-orange{border:1px solid #ff9800;}.panel-group .panel-col-orange .panel-title{background-color:#ff9800 !important;color:#fff;}.panel-group .panel-col-orange .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-deep-orange{border:1px solid #ff5722;}.panel-group .panel-col-deep-orange .panel-title{background-color:#ff5722 !important;color:#fff;}.panel-group .panel-col-deep-orange .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-brown{border:1px solid #795548;}.panel-group .panel-col-brown .panel-title{background-color:#795548 !important;color:#fff;}.panel-group .panel-col-brown .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-grey{border:1px solid #9e9e9e;}.panel-group .panel-col-grey .panel-title{background-color:#9e9e9e !important;color:#fff;}.panel-group .panel-col-grey .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-blue-grey{border:1px solid #607d8b;}.panel-group .panel-col-blue-grey .panel-title{background-color:#607d8b !important;color:#fff;}.panel-group .panel-col-blue-grey .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-black{border:1px solid #000;}.panel-group .panel-col-black .panel-title{background-color:#000 !important;color:#fff;}.panel-group .panel-col-black .panel-body{border-top-color:transparent !important;}.panel-group .panel-col-white{border:1px solid #fff;}.panel-group .panel-col-white .panel-title{background-color:#fff !important;color:#fff;}.panel-group .panel-col-white .panel-body{border-top-color:transparent !important;}.panel-group .panel{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.panel-group .panel .panel-title .material-icons{float:left;line-height:16px;margin-right:8px;}.panel-group .panel .panel-heading{padding:0;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.panel-group .panel .panel-heading a{display:block;padding:10px 15px;}.panel-group .panel .panel-heading a:hover,.panel-group .panel .panel-heading a:focus,.panel-group .panel .panel-heading a:active{text-decoration:none;}.panel-group .panel .panel-body{color:#555;}.panel-group .panel-primary{border:1px solid #1f91f3;}.panel-group .panel-primary .panel-title{background-color:#1f91f3;}.panel-group .panel-success{border:1px solid #2b982b;}.panel-group .panel-success .panel-title{background-color:#2b982b;color:#fff;}.panel-group .panel-warning{border:1px solid #ff9600;}.panel-group .panel-warning .panel-title{background-color:#ff9600;color:#fff;}.panel-group .panel-danger{border:1px solid #fb483a;}.panel-group .panel-danger .panel-title{background-color:#fb483a;color:#fff;}.full-body .panel-col-red .panel-body{border-top-color:#fff !important;background-color:#f44336;color:#fff;}.full-body .panel-col-pink .panel-body{border-top-color:#fff !important;background-color:#e91e63;color:#fff;}.full-body .panel-col-purple .panel-body{border-top-color:#fff !important;background-color:#9c27b0;color:#fff;}.full-body .panel-col-deep-purple .panel-body{border-top-color:#fff !important;background-color:#673ab7;color:#fff;}.full-body .panel-col-indigo .panel-body{border-top-color:#fff !important;background-color:#3f51b5;color:#fff;}.full-body .panel-col-blue .panel-body{border-top-color:#fff !important;background-color:#2196f3;color:#fff;}.full-body .panel-col-light-blue .panel-body{border-top-color:#fff !important;background-color:#03a9f4;color:#fff;}.full-body .panel-col-cyan .panel-body{border-top-color:#fff !important;background-color:#00bcd4;color:#fff;}.full-body .panel-col-teal .panel-body{border-top-color:#fff !important;background-color:#009688;color:#fff;}.full-body .panel-col-green .panel-body{border-top-color:#fff !important;background-color:#4caf50;color:#fff;}.full-body .panel-col-light-green .panel-body{border-top-color:#fff !important;background-color:#8bc34a;color:#fff;}.full-body .panel-col-lime .panel-body{border-top-color:#fff !important;background-color:#cddc39;color:#fff;}.full-body .panel-col-yellow .panel-body{border-top-color:#fff !important;background-color:#ffe821;color:#fff;}.full-body .panel-col-amber .panel-body{border-top-color:#fff !important;background-color:#ffc107;color:#fff;}.full-body .panel-col-orange .panel-body{border-top-color:#fff !important;background-color:#ff9800;color:#fff;}.full-body .panel-col-deep-orange .panel-body{border-top-color:#fff !important;background-color:#ff5722;color:#fff;}.full-body .panel-col-brown .panel-body{border-top-color:#fff !important;background-color:#795548;color:#fff;}.full-body .panel-col-grey .panel-body{border-top-color:#fff !important;background-color:#9e9e9e;color:#fff;}.full-body .panel-col-blue-grey .panel-body{border-top-color:#fff !important;background-color:#607d8b;color:#fff;}.full-body .panel-col-black .panel-body{border-top-color:#fff !important;background-color:#000;color:#fff;}.full-body .panel-col-white .panel-body{border-top-color:#fff !important;background-color:#fff;color:#fff;}.full-body .panel-primary .panel-body{border-top-color:#fff !important;background-color:#1f91f3;color:#fff;}.full-body .panel-success .panel-body{border-top-color:#fff !important;background-color:#2b982b;color:#fff;}.full-body .panel-warning .panel-body{border-top-color:#fff !important;background-color:#ff9600;color:#fff;}.full-body .panel-danger .panel-body{border-top-color:#fff !important;background-color:#fb483a;color:#fff;}.progress{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;height:22px;}.progress .progress-bar{line-height:23px;background-color:#1f91f3;}.progress .progress-bar-success{background-color:#2b982b;}.progress .progress-bar-info{background-color:#00b0e4;}.progress .progress-bar-warning{background-color:#ff9600;}.progress .progress-bar-danger{background-color:#fb483a;}.irs .irs-min,.irs .irs-max,.irs .irs-from,.irs .irs-to,.irs .irs-single{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.input-group{width:100%;margin-bottom:20px;}.input-group .form-line{display:inline-block;width:100%;border-bottom:1px solid #ddd;position:relative;}.input-group .form-line:after{content:'';position:absolute;left:0;width:100%;bottom:-2px;-moz-transform:scaleX(0);-ms-transform:scaleX(0);-o-transform:scaleX(0);-webkit-transform:scaleX(0);transform:scaleX(0);-moz-transition:.25s ease-in;-o-transition:.25s ease-in;-webkit-transition:.25s ease-in;transition:.25s ease-in;border-bottom:2px solid #1f91f3;}.input-group .form-line+.input-group-addon{padding-right:0;padding-left:10px;}.input-group .help-info{float:right;font-size:12px;margin-top:5px;color:#999;}.input-group label.error{font-size:12px;display:block;margin-top:5px;font-weight:normal;color:#f44336;}.input-group .form-line.error:after{border-bottom:2px solid #f44336;}.input-group .form-line.success:after{border-bottom:2px solid #4caf50;}.input-group .form-line.warning:after{border-bottom:2px solid #ffc107;}.input-group .form-line.focused:after{-moz-transform:scaleX(1);-ms-transform:scaleX(1);-o-transform:scaleX(1);-webkit-transform:scaleX(1);transform:scaleX(1);}.input-group .form-line.focused .form-label{bottom:25px;left:0;font-size:12px;}.input-group .input-group-addon{border:none;background-color:transparent;padding-left:0;font-weight:bold;}.input-group .input-group-addon .material-icons{font-size:18px;color:#555;}.input-group input[type="text"],.input-group .form-control{border:none;box-shadow:none;padding-left:0;}.input-group .form-control:focus{-webkit-box-shadow:none !important;-moz-box-shadow:none !important;-ms-box-shadow:none !important;box-shadow:none !important;}.input-group.input-group-sm .input-group-addon i{font-size:14px;}.input-group.input-group-sm .form-control{font-size:12px;}.input-group.input-group-lg .input-group-addon i{font-size:26px;}.input-group.input-group-lg .form-control{font-size:18px;}.form-control-label{text-align:right;}.form-control-label label{margin-top:8px;}.form-horizontal .form-group{margin-bottom:0;}.form-group{width:100%;margin-bottom:25px;}.form-group .form-control{width:100%;border:none;box-shadow:none;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;padding-left:0;}.form-group .help-info{float:right;font-size:12px;margin-top:5px;color:#999;}.form-group label.error{font-size:12px;display:block;margin-top:5px;font-weight:normal;color:#f44336;}.form-group .form-line{width:100%;position:relative;border-bottom:1px solid #ddd;}.form-group .form-line:after{content:'';position:absolute;left:0;width:100%;height:0;bottom:-1px;-moz-transform:scaleX(0);-ms-transform:scaleX(0);-o-transform:scaleX(0);-webkit-transform:scaleX(0);transform:scaleX(0);-moz-transition:.25s ease-in;-o-transition:.25s ease-in;-webkit-transition:.25s ease-in;transition:.25s ease-in;border-bottom:2px solid #1f91f3;}.form-group .form-line .form-label{font-weight:normal;color:#aaa;position:absolute;top:10px;left:0;cursor:text;-moz-transition:.2s;-o-transition:.2s;-webkit-transition:.2s;transition:.2s;}.form-group .form-line.error:after{border-bottom:2px solid #f44336;}.form-group .form-line.success:after{border-bottom:2px solid #4caf50;}.form-group .form-line.warning:after{border-bottom:2px solid #ffc107;}.form-group .form-line.focused:after{-moz-transform:scaleX(1);-ms-transform:scaleX(1);-o-transform:scaleX(1);-webkit-transform:scaleX(1);transform:scaleX(1);}.form-group .form-line.focused .form-label{top:-10px;left:0;font-size:12px;}.form-group-sm .form-label{font-size:12px;}.form-group-sm .form-line.focused .form-label{bottom:20px;font-size:10px;}.form-group-lg .form-label{font-size:18px;}.form-group-lg .form-line.focused .form-label{bottom:35px;font-size:12px;}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:transparent;}.colorpicker{z-index:1;}.colorpicker:before,.colorpicker:after{display:none !important;}.dropzone{border:2px solid transparent !important;background-color:#eee !important;}.dropzone .dz-message .drag-icon-cph .material-icons{font-size:80px;color:#777;}.dz-drag-hover{border:2px dashed #888 !important;}.breadcrumb{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;background-color:transparent;font-size:13px;margin-bottom:10px;}.breadcrumb li a{color:#444;text-decoration:none;}.breadcrumb li a .material-icons{font-size:18px;position:relative;top:4px;}.breadcrumb li .material-icons{font-size:18px;position:relative;top:4px;}.breadcrumb>li+li:before{content:'> ';}.breadcrumb-col-red li a{color:#f44336 !important;font-weight:bold;}.breadcrumb-bg-red{background-color:#f44336 !important;}.breadcrumb-bg-red li{color:#fff !important;}.breadcrumb-bg-red li a{color:#fff;font-weight:bold;}.breadcrumb-bg-red li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-red li+li:before{color:#fff;}.breadcrumb-col-pink li a{color:#e91e63 !important;font-weight:bold;}.breadcrumb-bg-pink{background-color:#e91e63 !important;}.breadcrumb-bg-pink li{color:#fff !important;}.breadcrumb-bg-pink li a{color:#fff;font-weight:bold;}.breadcrumb-bg-pink li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-pink li+li:before{color:#fff;}.breadcrumb-col-purple li a{color:#9c27b0 !important;font-weight:bold;}.breadcrumb-bg-purple{background-color:#9c27b0 !important;}.breadcrumb-bg-purple li{color:#fff !important;}.breadcrumb-bg-purple li a{color:#fff;font-weight:bold;}.breadcrumb-bg-purple li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-purple li+li:before{color:#fff;}.breadcrumb-col-deep-purple li a{color:#673ab7 !important;font-weight:bold;}.breadcrumb-bg-deep-purple{background-color:#673ab7 !important;}.breadcrumb-bg-deep-purple li{color:#fff !important;}.breadcrumb-bg-deep-purple li a{color:#fff;font-weight:bold;}.breadcrumb-bg-deep-purple li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-deep-purple li+li:before{color:#fff;}.breadcrumb-col-indigo li a{color:#3f51b5 !important;font-weight:bold;}.breadcrumb-bg-indigo{background-color:#3f51b5 !important;}.breadcrumb-bg-indigo li{color:#fff !important;}.breadcrumb-bg-indigo li a{color:#fff;font-weight:bold;}.breadcrumb-bg-indigo li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-indigo li+li:before{color:#fff;}.breadcrumb-col-blue li a{color:#2196f3 !important;font-weight:bold;}.breadcrumb-bg-blue{background-color:#2196f3 !important;}.breadcrumb-bg-blue li{color:#fff !important;}.breadcrumb-bg-blue li a{color:#fff;font-weight:bold;}.breadcrumb-bg-blue li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-blue li+li:before{color:#fff;}.breadcrumb-col-light-blue li a{color:#03a9f4 !important;font-weight:bold;}.breadcrumb-bg-light-blue{background-color:#03a9f4 !important;}.breadcrumb-bg-light-blue li{color:#fff !important;}.breadcrumb-bg-light-blue li a{color:#fff;font-weight:bold;}.breadcrumb-bg-light-blue li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-light-blue li+li:before{color:#fff;}.breadcrumb-col-cyan li a{color:#00bcd4 !important;font-weight:bold;}.breadcrumb-bg-cyan{background-color:#00bcd4 !important;}.breadcrumb-bg-cyan li{color:#fff !important;}.breadcrumb-bg-cyan li a{color:#fff;font-weight:bold;}.breadcrumb-bg-cyan li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-cyan li+li:before{color:#fff;}.breadcrumb-col-teal li a{color:#009688 !important;font-weight:bold;}.breadcrumb-bg-teal{background-color:#009688 !important;}.breadcrumb-bg-teal li{color:#fff !important;}.breadcrumb-bg-teal li a{color:#fff;font-weight:bold;}.breadcrumb-bg-teal li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-teal li+li:before{color:#fff;}.breadcrumb-col-green li a{color:#4caf50 !important;font-weight:bold;}.breadcrumb-bg-green{background-color:#4caf50 !important;}.breadcrumb-bg-green li{color:#fff !important;}.breadcrumb-bg-green li a{color:#fff;font-weight:bold;}.breadcrumb-bg-green li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-green li+li:before{color:#fff;}.breadcrumb-col-light-green li a{color:#8bc34a !important;font-weight:bold;}.breadcrumb-bg-light-green{background-color:#8bc34a !important;}.breadcrumb-bg-light-green li{color:#fff !important;}.breadcrumb-bg-light-green li a{color:#fff;font-weight:bold;}.breadcrumb-bg-light-green li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-light-green li+li:before{color:#fff;}.breadcrumb-col-lime li a{color:#cddc39 !important;font-weight:bold;}.breadcrumb-bg-lime{background-color:#cddc39 !important;}.breadcrumb-bg-lime li{color:#fff !important;}.breadcrumb-bg-lime li a{color:#fff;font-weight:bold;}.breadcrumb-bg-lime li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-lime li+li:before{color:#fff;}.breadcrumb-col-yellow li a{color:#ffe821 !important;font-weight:bold;}.breadcrumb-bg-yellow{background-color:#ffe821 !important;}.breadcrumb-bg-yellow li{color:#fff !important;}.breadcrumb-bg-yellow li a{color:#fff;font-weight:bold;}.breadcrumb-bg-yellow li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-yellow li+li:before{color:#fff;}.breadcrumb-col-amber li a{color:#ffc107 !important;font-weight:bold;}.breadcrumb-bg-amber{background-color:#ffc107 !important;}.breadcrumb-bg-amber li{color:#fff !important;}.breadcrumb-bg-amber li a{color:#fff;font-weight:bold;}.breadcrumb-bg-amber li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-amber li+li:before{color:#fff;}.breadcrumb-col-orange li a{color:#ff9800 !important;font-weight:bold;}.breadcrumb-bg-orange{background-color:#ff9800 !important;}.breadcrumb-bg-orange li{color:#fff !important;}.breadcrumb-bg-orange li a{color:#fff;font-weight:bold;}.breadcrumb-bg-orange li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-orange li+li:before{color:#fff;}.breadcrumb-col-deep-orange li a{color:#ff5722 !important;font-weight:bold;}.breadcrumb-bg-deep-orange{background-color:#ff5722 !important;}.breadcrumb-bg-deep-orange li{color:#fff !important;}.breadcrumb-bg-deep-orange li a{color:#fff;font-weight:bold;}.breadcrumb-bg-deep-orange li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-deep-orange li+li:before{color:#fff;}.breadcrumb-col-brown li a{color:#795548 !important;font-weight:bold;}.breadcrumb-bg-brown{background-color:#795548 !important;}.breadcrumb-bg-brown li{color:#fff !important;}.breadcrumb-bg-brown li a{color:#fff;font-weight:bold;}.breadcrumb-bg-brown li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-brown li+li:before{color:#fff;}.breadcrumb-col-grey li a{color:#9e9e9e !important;font-weight:bold;}.breadcrumb-bg-grey{background-color:#9e9e9e !important;}.breadcrumb-bg-grey li{color:#fff !important;}.breadcrumb-bg-grey li a{color:#fff;font-weight:bold;}.breadcrumb-bg-grey li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-grey li+li:before{color:#fff;}.breadcrumb-col-blue-grey li a{color:#607d8b !important;font-weight:bold;}.breadcrumb-bg-blue-grey{background-color:#607d8b !important;}.breadcrumb-bg-blue-grey li{color:#fff !important;}.breadcrumb-bg-blue-grey li a{color:#fff;font-weight:bold;}.breadcrumb-bg-blue-grey li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-blue-grey li+li:before{color:#fff;}.breadcrumb-col-black li a{color:#000 !important;font-weight:bold;}.breadcrumb-bg-black{background-color:#000 !important;}.breadcrumb-bg-black li{color:#fff !important;}.breadcrumb-bg-black li a{color:#fff;font-weight:bold;}.breadcrumb-bg-black li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-black li+li:before{color:#fff;}.breadcrumb-col-white li a{color:#fff !important;font-weight:bold;}.breadcrumb-bg-white{background-color:#fff !important;}.breadcrumb-bg-white li{color:#fff !important;}.breadcrumb-bg-white li a{color:#fff;font-weight:bold;}.breadcrumb-bg-white li a .material-icons{padding-bottom:8px;}.breadcrumb-bg-white li+li:before{color:#fff;}.badge{-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;border-radius:2px;}.list-group-item{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;-moz-transition:.5s;-o-transition:.5s;-webkit-transition:.5s;transition:.5s;}.list-group .active{background-color:#2196f3;border-color:#2196f3;}.list-group .active:hover,.list-group .active:focus,.list-group .active:active{background-color:#2196f3;border-color:#2196f3;}.list-group .active .list-group-item-text{color:#dfe9f1;font-size:13px;}.list-group .active .list-group-item-text:hover,.list-group .active .list-group-item-text:active,.list-group .active .list-group-item-text:focus{color:#dfe9f1;}.list-group .list-group-item.active:hover .list-group-item-text,.list-group .list-group-item.active:focus .list-group-item-text,.list-group .list-group-item.active:active .list-group-item-text{color:#dfe9f1;}.list-group .list-group-item:first-child,.list-group .list-group-item:last-child{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.list-group .list-group-item .list-group-item-heading{font-weight:bold;font-size:17px;}.list-group .list-group-item-success{background-color:#2b982b;border:none;color:#fff;}.list-group .list-group-item-success:hover,.list-group .list-group-item-success:focus{background-color:#2b982b;color:#fff;opacity:.8;}.list-group .list-group-item-info{background-color:#00b0e4;border:none;color:#fff;}.list-group .list-group-item-info:hover,.list-group .list-group-item-info:focus{background-color:#00b0e4;color:#fff;opacity:.8;}.list-group .list-group-item-warning{background-color:#ff9600;border:none;color:#fff;}.list-group .list-group-item-warning:hover,.list-group .list-group-item-warning:focus{background-color:#ff9600;color:#fff;opacity:.8;}.list-group .list-group-item-danger{background-color:#fb483a;border:none;color:#fff;}.list-group .list-group-item-danger:hover,.list-group .list-group-item-danger:focus{background-color:#fb483a;color:#fff;opacity:.8;}.list-group .pl-red{stroke:#f44336;}.list-group .list-group-bg-red{background-color:#f44336;border:none;color:#fff;}.list-group .list-group-bg-red:hover,.list-group .list-group-bg-red:focus{background-color:#f44336;color:#fff;opacity:.8;}.list-group .pl-pink{stroke:#e91e63;}.list-group .list-group-bg-pink{background-color:#e91e63;border:none;color:#fff;}.list-group .list-group-bg-pink:hover,.list-group .list-group-bg-pink:focus{background-color:#e91e63;color:#fff;opacity:.8;}.list-group .pl-purple{stroke:#9c27b0;}.list-group .list-group-bg-purple{background-color:#9c27b0;border:none;color:#fff;}.list-group .list-group-bg-purple:hover,.list-group .list-group-bg-purple:focus{background-color:#9c27b0;color:#fff;opacity:.8;}.list-group .pl-deep-purple{stroke:#673ab7;}.list-group .list-group-bg-deep-purple{background-color:#673ab7;border:none;color:#fff;}.list-group .list-group-bg-deep-purple:hover,.list-group .list-group-bg-deep-purple:focus{background-color:#673ab7;color:#fff;opacity:.8;}.list-group .pl-indigo{stroke:#3f51b5;}.list-group .list-group-bg-indigo{background-color:#3f51b5;border:none;color:#fff;}.list-group .list-group-bg-indigo:hover,.list-group .list-group-bg-indigo:focus{background-color:#3f51b5;color:#fff;opacity:.8;}.list-group .pl-blue{stroke:#2196f3;}.list-group .list-group-bg-blue{background-color:#2196f3;border:none;color:#fff;}.list-group .list-group-bg-blue:hover,.list-group .list-group-bg-blue:focus{background-color:#2196f3;color:#fff;opacity:.8;}.list-group .pl-light-blue{stroke:#03a9f4;}.list-group .list-group-bg-light-blue{background-color:#03a9f4;border:none;color:#fff;}.list-group .list-group-bg-light-blue:hover,.list-group .list-group-bg-light-blue:focus{background-color:#03a9f4;color:#fff;opacity:.8;}.list-group .pl-cyan{stroke:#00bcd4;}.list-group .list-group-bg-cyan{background-color:#00bcd4;border:none;color:#fff;}.list-group .list-group-bg-cyan:hover,.list-group .list-group-bg-cyan:focus{background-color:#00bcd4;color:#fff;opacity:.8;}.list-group .pl-teal{stroke:#009688;}.list-group .list-group-bg-teal{background-color:#009688;border:none;color:#fff;}.list-group .list-group-bg-teal:hover,.list-group .list-group-bg-teal:focus{background-color:#009688;color:#fff;opacity:.8;}.list-group .pl-green{stroke:#4caf50;}.list-group .list-group-bg-green{background-color:#4caf50;border:none;color:#fff;}.list-group .list-group-bg-green:hover,.list-group .list-group-bg-green:focus{background-color:#4caf50;color:#fff;opacity:.8;}.list-group .pl-light-green{stroke:#8bc34a;}.list-group .list-group-bg-light-green{background-color:#8bc34a;border:none;color:#fff;}.list-group .list-group-bg-light-green:hover,.list-group .list-group-bg-light-green:focus{background-color:#8bc34a;color:#fff;opacity:.8;}.list-group .pl-lime{stroke:#cddc39;}.list-group .list-group-bg-lime{background-color:#cddc39;border:none;color:#fff;}.list-group .list-group-bg-lime:hover,.list-group .list-group-bg-lime:focus{background-color:#cddc39;color:#fff;opacity:.8;}.list-group .pl-yellow{stroke:#ffe821;}.list-group .list-group-bg-yellow{background-color:#ffe821;border:none;color:#fff;}.list-group .list-group-bg-yellow:hover,.list-group .list-group-bg-yellow:focus{background-color:#ffe821;color:#fff;opacity:.8;}.list-group .pl-amber{stroke:#ffc107;}.list-group .list-group-bg-amber{background-color:#ffc107;border:none;color:#fff;}.list-group .list-group-bg-amber:hover,.list-group .list-group-bg-amber:focus{background-color:#ffc107;color:#fff;opacity:.8;}.list-group .pl-orange{stroke:#ff9800;}.list-group .list-group-bg-orange{background-color:#ff9800;border:none;color:#fff;}.list-group .list-group-bg-orange:hover,.list-group .list-group-bg-orange:focus{background-color:#ff9800;color:#fff;opacity:.8;}.list-group .pl-deep-orange{stroke:#ff5722;}.list-group .list-group-bg-deep-orange{background-color:#ff5722;border:none;color:#fff;}.list-group .list-group-bg-deep-orange:hover,.list-group .list-group-bg-deep-orange:focus{background-color:#ff5722;color:#fff;opacity:.8;}.list-group .pl-brown{stroke:#795548;}.list-group .list-group-bg-brown{background-color:#795548;border:none;color:#fff;}.list-group .list-group-bg-brown:hover,.list-group .list-group-bg-brown:focus{background-color:#795548;color:#fff;opacity:.8;}.list-group .pl-grey{stroke:#9e9e9e;}.list-group .list-group-bg-grey{background-color:#9e9e9e;border:none;color:#fff;}.list-group .list-group-bg-grey:hover,.list-group .list-group-bg-grey:focus{background-color:#9e9e9e;color:#fff;opacity:.8;}.list-group .pl-blue-grey{stroke:#607d8b;}.list-group .list-group-bg-blue-grey{background-color:#607d8b;border:none;color:#fff;}.list-group .list-group-bg-blue-grey:hover,.list-group .list-group-bg-blue-grey:focus{background-color:#607d8b;color:#fff;opacity:.8;}.list-group .pl-black{stroke:#000;}.list-group .list-group-bg-black{background-color:#000;border:none;color:#fff;}.list-group .list-group-bg-black:hover,.list-group .list-group-bg-black:focus{background-color:#000;color:#fff;opacity:.8;}.list-group .pl-white{stroke:#fff;}.list-group .list-group-bg-white{background-color:#fff;border:none;color:#fff;}.list-group .list-group-bg-white:hover,.list-group .list-group-bg-white:focus{background-color:#fff;color:#fff;opacity:.8;}.pager li>a{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;border:none;background-color:transparent;color:#222;font-weight:bold;}.pager li a:focus,.pager li a:active{background-color:transparent;}.pagination .disabled a,.pagination .disabled a:hover,.pagination .disabled a:focus,.pagination .disabled a:active{color:#bbb;}.pagination li.active a{background-color:#2196f3;}.pagination li{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.pagination li a:focus,.pagination li a:active{background-color:transparent;color:#555;}.pagination>li>a{border:none;font-weight:bold;color:#555;}.pagination>li:first-child>a,.pagination>li:last-child>a{width:auto;height:32px;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.pagination>li:first-child>a .material-icons,.pagination>li:last-child>a .material-icons{position:relative;bottom:2px;}.pagination-sm>li:first-child>a,.pagination-sm>li:last-child>a{width:28px;height:28px;}.pagination-sm>li:first-child>a .material-icons,.pagination-sm>li:last-child>a .material-icons{position:relative;top:-1px;left:-6px;font-size:20px;}.pagination-lg>li:first-child>a,.pagination-lg>li:last-child>a{width:44px;height:44px;}.pagination-lg>li:first-child>a .material-icons,.pagination-lg>li:last-child>a .material-icons{font-size:30px;position:relative;top:-3px;left:-10px;}.media{margin-bottom:25px;}.media .media-body{color:#777;font-size:13px;}.media .media-body .media-heading{font-size:16px;font-weight:bold;color:#333;}.wizard,.tabcontrol{display:block;width:100%;overflow:hidden;}.wizard a,.tabcontrol a{outline:0;}.wizard ul,.tabcontrol ul{list-style:none !important;padding:0;margin:0;}.wizard ul>li,.tabcontrol ul>li{display:block;padding:0;}.wizard>.steps .current-info,.tabcontrol>.steps .current-info,.wizard>.content>.title,.tabcontrol>.content>.title{position:absolute;left:-999em;}.wizard>.steps{position:relative;display:block;width:100%;}.wizard.vertical>.steps{float:left;width:30%;}.wizard.vertical>.steps>ul>li{float:none;width:100%;}.wizard.vertical>.content{float:left;margin:0 0 .5em 0;width:70%;}.wizard.vertical>.actions{float:right;width:100%;}.wizard.vertical>.actions>ul>li{margin:0 0 0 1em;}.wizard>.steps .number{font-size:1.429em;}.wizard>.steps>ul>li{width:25%;float:left;}.wizard>.actions>ul>li{float:left;}.wizard>.steps a{display:block;width:auto;margin:0 .5em .5em;padding:1em 1em;text-decoration:none;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}.wizard>.steps a:hover,.wizard>.steps a:active{display:block;width:auto;margin:0 .5em .5em;padding:1em 1em;text-decoration:none;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}.wizard>.steps .disabled a{background:#eee;color:#aaa;cursor:default;}.wizard>.steps .disabled a:hover,.wizard>.steps .disabled a:active{background:#eee;color:#aaa;cursor:default;}.wizard>.steps .current a{background:#2184be;color:#fff;cursor:default;}.wizard>.steps .current a:hover,.wizard>.steps .current a:active{background:#2184be;color:#fff;cursor:default;}.wizard>.steps .done a{background:#9dc8e2;color:#fff;}.wizard>.steps .done a:hover,.wizard>.steps .done a:active{background:#9dc8e2;color:#fff;}.wizard>.steps .error a{background:#ff3111;color:#fff;}.wizard>.steps .error a:hover,.wizard>.steps .error a:active{background:#ff3111;color:#fff;}.wizard>.content{border:1px solid #ddd;display:block;margin:.5em;min-height:35em;overflow:hidden;position:relative;width:auto;}.wizard>.actions{position:relative;display:block;text-align:right;width:100%;}.wizard>.actions>ul{display:inline-block;text-align:right;}.wizard>.actions>ul>li{margin:0 .5em;}.wizard>.actions a{background:#009688;color:#fff;display:block;padding:.5em 1em;text-decoration:none;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.wizard>.actions a:hover,.wizard>.actions a:active{background:#009688;color:#fff;display:block;padding:.5em 1em;text-decoration:none;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.wizard>.actions .disabled a{background:#eee;color:#aaa;}.wizard>.actions .disabled a:hover,.wizard>.actions .disabled a:active{background:#eee;color:#aaa;}.tabcontrol>.steps{position:relative;display:block;width:100%;}.tabcontrol>.steps>ul{position:relative;margin:6px 0 0 0;top:1px;z-index:1;}.tabcontrol>.steps>ul>li{float:left;margin:5px 2px 0 0;padding:1px;-webkit-border-top-left-radius:5px;-webkit-border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px;border-top-left-radius:5px;border-top-right-radius:5px;}.tabcontrol>.steps>ul>li:hover{background:#edecec;border:1px solid #bbb;padding:0;}.tabcontrol>.steps>ul>li.current{background:#fff;border:1px solid #bbb;border-bottom:0 none;padding:0 0 1px 0;margin-top:0;}.tabcontrol>.steps>ul>li.current>a{padding:15px 30px 10px 30px;}.tabcontrol>.steps>ul>li>a{color:#5f5f5f;display:inline-block;border:0 none;margin:0;padding:10px 30px;text-decoration:none;}.tabcontrol>.steps>ul>li>a:hover{text-decoration:none;}.tabcontrol>.content{position:relative;display:inline-block;width:100%;height:35em;overflow:hidden;border-top:1px solid #bbb;padding-top:20px;}.tabcontrol>.content>.body{float:left;position:absolute;width:95%;height:95%;padding:2.5%;}.tabcontrol>.content>.body ul{list-style:disc !important;}.tabcontrol>.content>.body ul>li{display:list-item;}.wizard .content{min-height:245px;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;overflow-y:auto;}.wizard .content .body{padding:15px;}.wizard .steps a{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;-moz-transition:.5s;-o-transition:.5s;-webkit-transition:.5s;transition:.5s;}.wizard .steps a:active,.wizard .steps a:focus,.wizard .steps a:hover{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.wizard .steps .done a{background-color:rgba(0,150,136,.6);}.wizard .steps .done a:hover,.wizard .steps .done a:active,.wizard .steps .done a:focus{background-color:rgba(0,150,136,.5);}.wizard .steps .error a{background-color:#f44336 !important;}.wizard .steps .current a{background-color:#009688;}.wizard .steps .current a:active,.wizard .steps .current a:focus,.wizard .steps .current a:hover{background-color:#009688;}.waves-effect.waves-red .waves-ripple{background:rgba(244,67,54,.5);}.waves-effect.waves-pink .waves-ripple{background:rgba(233,30,99,.5);}.waves-effect.waves-purple .waves-ripple{background:rgba(156,39,176,.5);}.waves-effect.waves-deep-purple .waves-ripple{background:rgba(103,58,183,.5);}.waves-effect.waves-indigo .waves-ripple{background:rgba(63,81,181,.5);}.waves-effect.waves-blue .waves-ripple{background:rgba(33,150,243,.5);}.waves-effect.waves-light-blue .waves-ripple{background:rgba(3,169,244,.5);}.waves-effect.waves-cyan .waves-ripple{background:rgba(0,188,212,.5);}.waves-effect.waves-teal .waves-ripple{background:rgba(0,150,136,.5);}.waves-effect.waves-green .waves-ripple{background:rgba(76,175,80,.5);}.waves-effect.waves-light-green .waves-ripple{background:rgba(139,195,74,.5);}.waves-effect.waves-lime .waves-ripple{background:rgba(205,220,57,.5);}.waves-effect.waves-yellow .waves-ripple{background:rgba(255,232,33,.5);}.waves-effect.waves-amber .waves-ripple{background:rgba(255,193,7,.5);}.waves-effect.waves-orange .waves-ripple{background:rgba(255,152,0,.5);}.waves-effect.waves-deep-orange .waves-ripple{background:rgba(255,87,34,.5);}.waves-effect.waves-brown .waves-ripple{background:rgba(121,85,72,.5);}.waves-effect.waves-grey .waves-ripple{background:rgba(158,158,158,.5);}.waves-effect.waves-blue-grey .waves-ripple{background:rgba(96,125,139,.5);}.waves-effect.waves-black .waves-ripple{background:rgba(0,0,0,.5);}.waves-effect.waves-white .waves-ripple{background:rgba(255,255,255,.5);}.page-loader-wrapper{z-index:99999999;position:fixed;top:0;left:0;bottom:0;right:0;width:100%;height:100%;background:#eee;overflow:hidden;text-align:center;}.page-loader-wrapper p{font-size:13px;margin-top:10px;font-weight:bold;color:#444;}.page-loader-wrapper .loader{position:relative;top:calc(50% - 30px);}.md-preloader .pl-red{stroke:#f44336;}.md-preloader .pl-pink{stroke:#e91e63;}.md-preloader .pl-purple{stroke:#9c27b0;}.md-preloader .pl-deep-purple{stroke:#673ab7;}.md-preloader .pl-indigo{stroke:#3f51b5;}.md-preloader .pl-blue{stroke:#2196f3;}.md-preloader .pl-light-blue{stroke:#03a9f4;}.md-preloader .pl-cyan{stroke:#00bcd4;}.md-preloader .pl-teal{stroke:#009688;}.md-preloader .pl-green{stroke:#4caf50;}.md-preloader .pl-light-green{stroke:#8bc34a;}.md-preloader .pl-lime{stroke:#cddc39;}.md-preloader .pl-yellow{stroke:#ffe821;}.md-preloader .pl-amber{stroke:#ffc107;}.md-preloader .pl-orange{stroke:#ff9800;}.md-preloader .pl-deep-orange{stroke:#ff5722;}.md-preloader .pl-brown{stroke:#795548;}.md-preloader .pl-grey{stroke:#9e9e9e;}.md-preloader .pl-blue-grey{stroke:#607d8b;}.md-preloader .pl-black{stroke:#000;}.md-preloader .pl-white{stroke:#fff;}.preloader{display:inline-block;position:relative;width:50px;height:50px;-webkit-animation:container-rotate 1568ms linear infinite;-moz-animation:container-rotate 1568ms linear infinite;-o-animation:container-rotate 1568ms linear infinite;animation:container-rotate 1568ms linear infinite;}.preloader.pl-size-xl{width:75px;height:75px;}.preloader.pl-size-l{width:60px;height:60px;}.preloader.pl-size-md{width:50px;height:50px;}.preloader.pl-size-sm{width:40px;height:40px;}.preloader.pl-size-xs{width:25px;height:25px;}.spinner-layer{position:absolute;width:100%;height:100%;border-color:#f44336;-ms-opacity:1;opacity:1;-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both;-moz-animation:fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both;-o-animation:fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(.4,0,.2,1) infinite both;}.spinner-layer.pl-red{border-color:#f44336;}.spinner-layer.pl-pink{border-color:#e91e63;}.spinner-layer.pl-purple{border-color:#9c27b0;}.spinner-layer.pl-deep-purple{border-color:#673ab7;}.spinner-layer.pl-indigo{border-color:#3f51b5;}.spinner-layer.pl-blue{border-color:#2196f3;}.spinner-layer.pl-light-blue{border-color:#03a9f4;}.spinner-layer.pl-cyan{border-color:#00bcd4;}.spinner-layer.pl-teal{border-color:#009688;}.spinner-layer.pl-green{border-color:#4caf50;}.spinner-layer.pl-light-green{border-color:#8bc34a;}.spinner-layer.pl-lime{border-color:#cddc39;}.spinner-layer.pl-yellow{border-color:#ffe821;}.spinner-layer.pl-amber{border-color:#ffc107;}.spinner-layer.pl-orange{border-color:#ff9800;}.spinner-layer.pl-deep-orange{border-color:#ff5722;}.spinner-layer.pl-brown{border-color:#795548;}.spinner-layer.pl-grey{border-color:#9e9e9e;}.spinner-layer.pl-blue-grey{border-color:#607d8b;}.spinner-layer.pl-black{border-color:#000;}.spinner-layer.pl-white{border-color:#fff;}.right{float:right !important;}.gap-patch{position:absolute;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit;}.gap-patch.circle{width:1000%;left:-450%;}.circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit;}.circle-clipper .circle{width:200%;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent !important;-ms-border-radius:50%;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0;}.circle-clipper.left .circle{left:0;border-right-color:transparent !important;-webkit-transform:rotate(129deg);-moz-transform:rotate(129deg);-ms-transform:rotate(129deg);-o-transform:rotate(129deg);transform:rotate(129deg);-webkit-animation:left-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;-moz-animation:left-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;-o-animation:left-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;animation:left-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;}.circle-clipper.right .circle{left:-100%;border-left-color:transparent !important;-webkit-transform:rotate(-129deg);-moz-transform:rotate(-129deg);-ms-transform:rotate(-129deg);-o-transform:rotate(-129deg);transform:rotate(-129deg);-webkit-animation:right-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;-moz-animation:right-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;-o-animation:right-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;animation:right-spin 1333ms cubic-bezier(.4,0,.2,1) infinite both;}@-webkit-keyframes container-rotate{to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg);}}@keyframes container-rotate{to{-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);-webkit-transform:rotate(360deg);transform:rotate(360deg);}}@-webkit-keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg);}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg);}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg);}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg);}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg);}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg);}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg);}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg);}}@keyframes fill-unfill-rotate{12.5%{transform:rotate(135deg);}25%{transform:rotate(270deg);}37.5%{transform:rotate(405deg);}50%{transform:rotate(540deg);}62.5%{transform:rotate(675deg);}75%{transform:rotate(810deg);}87.5%{transform:rotate(945deg);}to{transform:rotate(1080deg);}}@-webkit-keyframes left-spin{from{-webkit-transform:rotate(130deg);-moz-transform:rotate(130deg);-ms-transform:rotate(130deg);-o-transform:rotate(130deg);transform:rotate(130deg);}50%{-webkit-transform:rotate(-5deg);-moz-transform:rotate(-5deg);-ms-transform:rotate(-5deg);-o-transform:rotate(-5deg);transform:rotate(-5deg);}to{-webkit-transform:rotate(130deg);-moz-transform:rotate(130deg);-ms-transform:rotate(130deg);-o-transform:rotate(130deg);transform:rotate(130deg);}}@keyframes left-spin{from{-moz-transform:rotate(130deg);-ms-transform:rotate(130deg);-o-transform:rotate(130deg);-webkit-transform:rotate(130deg);transform:rotate(130deg);}50%{-moz-transform:rotate(-5deg);-ms-transform:rotate(-5deg);-o-transform:rotate(-5deg);-webkit-transform:rotate(-5deg);transform:rotate(-5deg);}to{-moz-transform:rotate(130deg);-ms-transform:rotate(130deg);-o-transform:rotate(130deg);-webkit-transform:rotate(130deg);transform:rotate(130deg);}}@-webkit-keyframes right-spin{from{-webkit-transform:rotate(-130deg);-moz-transform:rotate(-130deg);-ms-transform:rotate(-130deg);-o-transform:rotate(-130deg);transform:rotate(-130deg);}50%{-webkit-transform:rotate(5deg);-moz-transform:rotate(5deg);-ms-transform:rotate(5deg);-o-transform:rotate(5deg);transform:rotate(5deg);}to{-webkit-transform:rotate(-130deg);-moz-transform:rotate(-130deg);-ms-transform:rotate(-130deg);-o-transform:rotate(-130deg);transform:rotate(-130deg);}}@-moz-keyframes right-spin{from{-moz-transform:rotate(-130deg);-ms-transform:rotate(-130deg);-o-transform:rotate(-130deg);-webkit-transform:rotate(-130deg);transform:rotate(-130deg);}50%{-moz-transform:rotate(5deg);-ms-transform:rotate(5deg);-o-transform:rotate(5deg);-webkit-transform:rotate(5deg);transform:rotate(5deg);}to{-moz-transform:rotate(-130deg);-ms-transform:rotate(-130deg);-o-transform:rotate(-130deg);-webkit-transform:rotate(-130deg);transform:rotate(-130deg);}}@keyframes right-spin{from{-moz-transform:rotate(-130deg);-ms-transform:rotate(-130deg);-o-transform:rotate(-130deg);-webkit-transform:rotate(-130deg);transform:rotate(-130deg);}50%{-moz-transform:rotate(5deg);-ms-transform:rotate(5deg);-o-transform:rotate(5deg);-webkit-transform:rotate(5deg);transform:rotate(5deg);}to{-moz-transform:rotate(-130deg);-ms-transform:rotate(-130deg);-o-transform:rotate(-130deg);-webkit-transform:rotate(-130deg);transform:rotate(-130deg);}}.navbar{font-family:"Roboto",sans-serif;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;-webkit-box-shadow:0 1px 5px rgba(0,0,0,.3);-moz-box-shadow:0 1px 5px rgba(0,0,0,.3);-ms-box-shadow:0 1px 5px rgba(0,0,0,.3);box-shadow:0 1px 5px rgba(0,0,0,.3);border:none;position:fixed;top:0;left:0;z-index:12;width:100%;}.navbar .navbar-brand{white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;}.navbar .navbar-custom-right-menu{float:right;}.navbar .navbar-toggle{text-decoration:none;color:#fff;width:20px;height:20px;margin-top:-4px;margin-right:17px;}.navbar .navbar-toggle:before{content:'';font-family:'Material Icons';font-size:26px;}.navbar .navbar-collapse.in{overflow:visible;}.ls-closed .sidebar{margin-left:-300px;}.ls-closed section.content{margin-left:15px;}.ls-closed .bars:after,.ls-closed .bars:before{font-family:'Material Icons';font-size:24px;position:absolute;top:18px;left:20px;margin-right:10px;-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);-webkit-transform:scale(0);transform:scale(0);-moz-transition:all .3s;-o-transition:all .3s;-webkit-transition:all .3s;transition:all .3s;}.ls-closed .bars:before{content:'';-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);}.ls-closed .bars:after{content:'';-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);-webkit-transform:scale(0);transform:scale(0);}.ls-closed .navbar-brand{margin-left:30px;}.overlay-open .bars:before{-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);-webkit-transform:scale(0);transform:scale(0);}.overlay-open .bars:after{-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);}.navbar-header{padding:10px 7px;}.navbar-header .bars{float:left;text-decoration:none;}.navbar-nav>li>a{padding:7px 7px 2px 7px;margin-top:17px;margin-left:5px;}.navbar-nav .dropdown-menu{margin-top:-40px !important;}.label-count{position:absolute;top:2px;right:6px;font-size:10px;line-height:15px;background-color:#000;padding:0 4px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;}.col-red .navbar .navbar-brand,.col-red .navbar .navbar-brand:hover,.col-red .navbar .navbar-brand:active,.col-red .navbar .navbar-brand:focus{color:#fff;}.col-red .navbar .nav>li>a:hover,.col-red .navbar .nav>li>a:focus,.col-red .navbar .nav .open>a,.col-red .navbar .nav .open>a:hover,.col-red .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-red .navbar .nav>li>a{color:#fff;}.col-red .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-red .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-pink .navbar .navbar-brand,.col-pink .navbar .navbar-brand:hover,.col-pink .navbar .navbar-brand:active,.col-pink .navbar .navbar-brand:focus{color:#fff;}.col-pink .navbar .nav>li>a:hover,.col-pink .navbar .nav>li>a:focus,.col-pink .navbar .nav .open>a,.col-pink .navbar .nav .open>a:hover,.col-pink .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-pink .navbar .nav>li>a{color:#fff;}.col-pink .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-pink .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-purple .navbar .navbar-brand,.col-purple .navbar .navbar-brand:hover,.col-purple .navbar .navbar-brand:active,.col-purple .navbar .navbar-brand:focus{color:#fff;}.col-purple .navbar .nav>li>a:hover,.col-purple .navbar .nav>li>a:focus,.col-purple .navbar .nav .open>a,.col-purple .navbar .nav .open>a:hover,.col-purple .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-purple .navbar .nav>li>a{color:#fff;}.col-purple .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-purple .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-deep-purple .navbar .navbar-brand,.col-deep-purple .navbar .navbar-brand:hover,.col-deep-purple .navbar .navbar-brand:active,.col-deep-purple .navbar .navbar-brand:focus{color:#fff;}.col-deep-purple .navbar .nav>li>a:hover,.col-deep-purple .navbar .nav>li>a:focus,.col-deep-purple .navbar .nav .open>a,.col-deep-purple .navbar .nav .open>a:hover,.col-deep-purple .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-deep-purple .navbar .nav>li>a{color:#fff;}.col-deep-purple .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-deep-purple .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-indigo .navbar .navbar-brand,.col-indigo .navbar .navbar-brand:hover,.col-indigo .navbar .navbar-brand:active,.col-indigo .navbar .navbar-brand:focus{color:#fff;}.col-indigo .navbar .nav>li>a:hover,.col-indigo .navbar .nav>li>a:focus,.col-indigo .navbar .nav .open>a,.col-indigo .navbar .nav .open>a:hover,.col-indigo .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-indigo .navbar .nav>li>a{color:#fff;}.col-indigo .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-indigo .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-blue .navbar .navbar-brand,.col-blue .navbar .navbar-brand:hover,.col-blue .navbar .navbar-brand:active,.col-blue .navbar .navbar-brand:focus{color:#fff;}.col-blue .navbar .nav>li>a:hover,.col-blue .navbar .nav>li>a:focus,.col-blue .navbar .nav .open>a,.col-blue .navbar .nav .open>a:hover,.col-blue .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-blue .navbar .nav>li>a{color:#fff;}.col-blue .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-blue .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-light-blue .navbar .navbar-brand,.col-light-blue .navbar .navbar-brand:hover,.col-light-blue .navbar .navbar-brand:active,.col-light-blue .navbar .navbar-brand:focus{color:#fff;}.col-light-blue .navbar .nav>li>a:hover,.col-light-blue .navbar .nav>li>a:focus,.col-light-blue .navbar .nav .open>a,.col-light-blue .navbar .nav .open>a:hover,.col-light-blue .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-light-blue .navbar .nav>li>a{color:#fff;}.col-light-blue .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-light-blue .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-cyan .navbar .navbar-brand,.col-cyan .navbar .navbar-brand:hover,.col-cyan .navbar .navbar-brand:active,.col-cyan .navbar .navbar-brand:focus{color:#fff;}.col-cyan .navbar .nav>li>a:hover,.col-cyan .navbar .nav>li>a:focus,.col-cyan .navbar .nav .open>a,.col-cyan .navbar .nav .open>a:hover,.col-cyan .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-cyan .navbar .nav>li>a{color:#fff;}.col-cyan .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-cyan .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-teal .navbar .navbar-brand,.col-teal .navbar .navbar-brand:hover,.col-teal .navbar .navbar-brand:active,.col-teal .navbar .navbar-brand:focus{color:#fff;}.col-teal .navbar .nav>li>a:hover,.col-teal .navbar .nav>li>a:focus,.col-teal .navbar .nav .open>a,.col-teal .navbar .nav .open>a:hover,.col-teal .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-teal .navbar .nav>li>a{color:#fff;}.col-teal .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-teal .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-green .navbar .navbar-brand,.col-green .navbar .navbar-brand:hover,.col-green .navbar .navbar-brand:active,.col-green .navbar .navbar-brand:focus{color:#fff;}.col-green .navbar .nav>li>a:hover,.col-green .navbar .nav>li>a:focus,.col-green .navbar .nav .open>a,.col-green .navbar .nav .open>a:hover,.col-green .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-green .navbar .nav>li>a{color:#fff;}.col-green .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-green .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-light-green .navbar .navbar-brand,.col-light-green .navbar .navbar-brand:hover,.col-light-green .navbar .navbar-brand:active,.col-light-green .navbar .navbar-brand:focus{color:#fff;}.col-light-green .navbar .nav>li>a:hover,.col-light-green .navbar .nav>li>a:focus,.col-light-green .navbar .nav .open>a,.col-light-green .navbar .nav .open>a:hover,.col-light-green .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-light-green .navbar .nav>li>a{color:#fff;}.col-light-green .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-light-green .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-lime .navbar .navbar-brand,.col-lime .navbar .navbar-brand:hover,.col-lime .navbar .navbar-brand:active,.col-lime .navbar .navbar-brand:focus{color:#fff;}.col-lime .navbar .nav>li>a:hover,.col-lime .navbar .nav>li>a:focus,.col-lime .navbar .nav .open>a,.col-lime .navbar .nav .open>a:hover,.col-lime .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-lime .navbar .nav>li>a{color:#fff;}.col-lime .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-lime .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-yellow .navbar .navbar-brand,.col-yellow .navbar .navbar-brand:hover,.col-yellow .navbar .navbar-brand:active,.col-yellow .navbar .navbar-brand:focus{color:#fff;}.col-yellow .navbar .nav>li>a:hover,.col-yellow .navbar .nav>li>a:focus,.col-yellow .navbar .nav .open>a,.col-yellow .navbar .nav .open>a:hover,.col-yellow .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-yellow .navbar .nav>li>a{color:#fff;}.col-yellow .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-yellow .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-amber .navbar .navbar-brand,.col-amber .navbar .navbar-brand:hover,.col-amber .navbar .navbar-brand:active,.col-amber .navbar .navbar-brand:focus{color:#fff;}.col-amber .navbar .nav>li>a:hover,.col-amber .navbar .nav>li>a:focus,.col-amber .navbar .nav .open>a,.col-amber .navbar .nav .open>a:hover,.col-amber .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-amber .navbar .nav>li>a{color:#fff;}.col-amber .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-amber .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-orange .navbar .navbar-brand,.col-orange .navbar .navbar-brand:hover,.col-orange .navbar .navbar-brand:active,.col-orange .navbar .navbar-brand:focus{color:#fff;}.col-orange .navbar .nav>li>a:hover,.col-orange .navbar .nav>li>a:focus,.col-orange .navbar .nav .open>a,.col-orange .navbar .nav .open>a:hover,.col-orange .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-orange .navbar .nav>li>a{color:#fff;}.col-orange .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-orange .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-deep-orange .navbar .navbar-brand,.col-deep-orange .navbar .navbar-brand:hover,.col-deep-orange .navbar .navbar-brand:active,.col-deep-orange .navbar .navbar-brand:focus{color:#fff;}.col-deep-orange .navbar .nav>li>a:hover,.col-deep-orange .navbar .nav>li>a:focus,.col-deep-orange .navbar .nav .open>a,.col-deep-orange .navbar .nav .open>a:hover,.col-deep-orange .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-deep-orange .navbar .nav>li>a{color:#fff;}.col-deep-orange .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-deep-orange .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-brown .navbar .navbar-brand,.col-brown .navbar .navbar-brand:hover,.col-brown .navbar .navbar-brand:active,.col-brown .navbar .navbar-brand:focus{color:#fff;}.col-brown .navbar .nav>li>a:hover,.col-brown .navbar .nav>li>a:focus,.col-brown .navbar .nav .open>a,.col-brown .navbar .nav .open>a:hover,.col-brown .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-brown .navbar .nav>li>a{color:#fff;}.col-brown .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-brown .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-grey .navbar .navbar-brand,.col-grey .navbar .navbar-brand:hover,.col-grey .navbar .navbar-brand:active,.col-grey .navbar .navbar-brand:focus{color:#fff;}.col-grey .navbar .nav>li>a:hover,.col-grey .navbar .nav>li>a:focus,.col-grey .navbar .nav .open>a,.col-grey .navbar .nav .open>a:hover,.col-grey .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-grey .navbar .nav>li>a{color:#fff;}.col-grey .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-grey .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-blue-grey .navbar .navbar-brand,.col-blue-grey .navbar .navbar-brand:hover,.col-blue-grey .navbar .navbar-brand:active,.col-blue-grey .navbar .navbar-brand:focus{color:#fff;}.col-blue-grey .navbar .nav>li>a:hover,.col-blue-grey .navbar .nav>li>a:focus,.col-blue-grey .navbar .nav .open>a,.col-blue-grey .navbar .nav .open>a:hover,.col-blue-grey .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-blue-grey .navbar .nav>li>a{color:#fff;}.col-blue-grey .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-blue-grey .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-black .navbar .navbar-brand,.col-black .navbar .navbar-brand:hover,.col-black .navbar .navbar-brand:active,.col-black .navbar .navbar-brand:focus{color:#fff;}.col-black .navbar .nav>li>a:hover,.col-black .navbar .nav>li>a:focus,.col-black .navbar .nav .open>a,.col-black .navbar .nav .open>a:hover,.col-black .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-black .navbar .nav>li>a{color:#fff;}.col-black .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-black .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.col-white .navbar .navbar-brand,.col-white .navbar .navbar-brand:hover,.col-white .navbar .navbar-brand:active,.col-white .navbar .navbar-brand:focus{color:#fff;}.col-white .navbar .nav>li>a:hover,.col-white .navbar .nav>li>a:focus,.col-white .navbar .nav .open>a,.col-white .navbar .nav .open>a:hover,.col-white .navbar .nav .open>a:focus{background-color:rgba(0,0,0,.05);}.col-white .navbar .nav>li>a{color:#fff;}.col-white .navbar .bars{float:left;padding:10px 20px;font-size:22px;color:#fff;margin-right:10px;margin-left:-10px;margin-top:4px;}.col-white .navbar .bars:hover{background-color:rgba(0,0,0,.08);}.dropdown-menu{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;margin-top:-35px !important;box-shadow:0 2px 10px rgba(0,0,0,.2);border:none;}.dropdown-menu .divider{margin:5px 0;}.dropdown-menu .header{font-size:13px;font-weight:bold;min-width:270px;border-bottom:1px solid #eee;text-align:center;padding:4px 0 6px 0;}.dropdown-menu ul.menu{padding-left:0;}.dropdown-menu ul.menu.tasks h4{color:#333;font-size:13px;margin:0 0 8px 0;}.dropdown-menu ul.menu.tasks h4 small{float:right;margin-top:6px;}.dropdown-menu ul.menu.tasks .progress{height:7px;margin-bottom:7px;}.dropdown-menu ul.menu .icon-circle{width:36px;height:36px;-webkit-border-radius:50%;-moz-border-radius:50%;-ms-border-radius:50%;border-radius:50%;color:#fff;text-align:center;display:inline-block;}.dropdown-menu ul.menu .icon-circle i{font-size:18px;line-height:36px;}.dropdown-menu ul.menu li{border-bottom:1px solid #eee;}.dropdown-menu ul.menu li:last-child{border-bottom:none;}.dropdown-menu ul.menu li a{padding:7px 11px;text-decoration:none;-moz-transition:.5s;-o-transition:.5s;-webkit-transition:.5s;transition:.5s;}.dropdown-menu ul.menu li a:hover{background-color:#e9e9e9;}.dropdown-menu ul.menu .menu-info{display:inline-block;position:relative;top:3px;left:5px;}.dropdown-menu ul.menu .menu-info h4{margin:0;font-size:13px;color:#333;}.dropdown-menu ul.menu .menu-info p{margin:0;font-size:11px;color:#aaa;}.dropdown-menu ul.menu .menu-info p .material-icons{font-size:13px;color:#aaa;position:relative;top:2px;}.dropdown-menu .footer a{text-align:center;border-top:1px solid #eee;padding:5px 0 5px 0;font-size:12px;margin-bottom:-5px;}.dropdown-menu .footer a:hover{background-color:transparent;}.dropdown-menu>li>a{padding:7px 18px;color:#666;-moz-transition:all .5s;-o-transition:all .5s;-webkit-transition:all .5s;transition:all .5s;font-size:14px;line-height:25px;}.dropdown-menu>li>a:hover{background-color:rgba(0,0,0,.075);}.dropdown-menu>li>a i.material-icons{float:left;margin-right:7px;margin-top:2px;font-size:20px;}.dropdown-animated{-webkit-animation-duration:.3s !important;-moz-animation-duration:.3s !important;-o-animation-duration:.3s !important;animation-duration:.3s !important;}.overlay{position:fixed;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.5);display:none;z-index:10;}.overlay-open .sidebar{margin-left:0;z-index:99999999;}.sidebar{-moz-transition:all .5s;-o-transition:all .5s;-webkit-transition:all .5s;transition:all .5s;font-family:"Roboto",sans-serif;background:#fdfdfd;width:300px;overflow:hidden;display:inline-block;height:calc(100vh - 70px);position:fixed;top:70px;left:0;-webkit-box-shadow:2px 2px 5px rgba(0,0,0,.1);-moz-box-shadow:2px 2px 5px rgba(0,0,0,.1);-ms-box-shadow:2px 2px 5px rgba(0,0,0,.1);box-shadow:2px 2px 5px rgba(0,0,0,.1);z-index:11 !important;}.sidebar .legal{position:absolute;bottom:0;width:100%;border-top:1px solid #eee;padding:15px;overflow:hidden;}.sidebar .legal .copyright{font-size:13px;white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;}.sidebar .legal .copyright a{font-weight:bold;text-decoration:none;}.sidebar .legal .version{white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;margin-top:5px;font-size:13px;}.sidebar .user-info{padding:13px 15px 12px 15px;white-space:nowrap;position:relative;border-bottom:1px solid #e9e9e9;background:url("../images/user-img-background.jpg") no-repeat no-repeat;height:135px;}.sidebar .user-info .image{margin-right:12px;display:inline-block;}.sidebar .user-info .image img{-webkit-border-radius:50%;-moz-border-radius:50%;-ms-border-radius:50%;border-radius:50%;vertical-align:bottom !important;}.sidebar .user-info .info-container{cursor:default;display:block;position:relative;top:25px;}.sidebar .user-info .info-container .name{white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;font-size:14px;max-width:200px;color:#fff;}.sidebar .user-info .info-container .email{white-space:nowrap;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;font-size:12px;max-width:200px;color:#fff;}.sidebar .user-info .info-container .user-helper-dropdown{position:absolute;right:-3px;bottom:-12px;-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;box-shadow:none;cursor:pointer;color:#fff;}.sidebar .menu{position:relative;overflow-y:auto;height:90vh;}.sidebar .menu .list{list-style:none;padding-left:0;}.sidebar .menu .list li.active>:first-child span{font-weight:bold;}.sidebar .menu .list .header{background:#eee;font-size:12px;font-weight:600;padding:8px 16px;}.sidebar .menu .list i.material-icons{margin-top:4px;}.sidebar .menu .list .menu-toggle:after,.sidebar .menu .list .menu-toggle:before{position:absolute;top:calc(50% - 14px);right:17px;font-size:19px;-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);-webkit-transform:scale(0);transform:scale(0);-moz-transition:all .3s;-o-transition:all .3s;-webkit-transition:all .3s;transition:all .3s;}.sidebar .menu .list .menu-toggle:before{content:'+';-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);}.sidebar .menu .list .menu-toggle:after{content:'–';-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);-webkit-transform:scale(0);transform:scale(0);}.sidebar .menu .list .menu-toggle.toggled:before{-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);-webkit-transform:scale(0);transform:scale(0);}.sidebar .menu .list .menu-toggle.toggled:after{-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);}.sidebar .menu .list a{color:#747474;position:relative;display:inline-flex;vertical-align:middle;width:100%;padding:10px 13px;}.sidebar .menu .list a:hover,.sidebar .menu .list a:active,.sidebar .menu .list a:focus{text-decoration:none !important;}.sidebar .menu .list a small{position:absolute;top:calc(50% - 7.5px);right:15px;}.sidebar .menu .list a span{margin:7px 0 7px 12px;color:#333;font-weight:bold;font-size:14px;overflow:hidden;}.sidebar .menu .list .ml-menu{list-style:none;display:none;padding-left:0;}.sidebar .menu .list .ml-menu span{font-weight:normal;font-size:14px;margin:3px 0 1px 6px;}.sidebar .menu .list .ml-menu li a{padding-left:55px;padding-top:7px;padding-bottom:7px;}.sidebar .menu .list .ml-menu li.active a.toggled:not(.menu-toggle){font-weight:600;margin-left:5px;}.sidebar .menu .list .ml-menu li.active a.toggled:not(.menu-toggle):before{content:'';font-family:'Material Icons';position:relative;font-size:21px;height:20px;top:-5px;right:0;}.sidebar .menu .list .ml-menu li .ml-menu li a{padding-left:80px;}.sidebar .menu .list .ml-menu li .ml-menu .ml-menu li a{padding-left:95px;}.right-sidebar{width:280px;height:calc(100vh - 70px);position:fixed;right:-300px;top:70px;background:#fdfdfd;z-index:11 !important;-webkit-box-shadow:-2px 2px 5px rgba(0,0,0,.1);-moz-box-shadow:-2px 2px 5px rgba(0,0,0,.1);-ms-box-shadow:-2px 2px 5px rgba(0,0,0,.1);box-shadow:-2px 2px 5px rgba(0,0,0,.1);overflow:hidden;-moz-transition:.5s;-o-transition:.5s;-webkit-transition:.5s;transition:.5s;}.right-sidebar.open{right:0;}.right-sidebar .nav-tabs{font-weight:600;font-size:13px;width:100%;margin-left:2px;}.right-sidebar .nav-tabs li{text-align:center;}.right-sidebar .nav-tabs li>a{margin-right:0;}.right-sidebar .nav-tabs li:first-child{width:45%;}.right-sidebar .nav-tabs li:last-child{width:55%;}.bootstrap-notify-container{max-width:320px;text-align:center;}.dd-handle{background-color:#f9f9f9 !important;}.dd-handle:hover{color:#2196f3;}.nestable-dark-theme .dd-handle{background:#ccc !important;border:1px solid #999 !important;}.dd3-handle{background:#999 !important;}.dd3-content:hover{color:#2196f3;}.login-page{background-color:#00bcd4;padding-left:0;max-width:360px;margin:5% auto;overflow-x:hidden;}.login-page .login-box .msg{color:#555;margin-bottom:30px;text-align:center;}.login-page .login-box a{font-size:14px;text-decoration:none;color:#00bcd4;}.login-page .login-box .logo{margin-bottom:20px;}.login-page .login-box .logo a{font-size:36px;display:block;width:100%;text-align:center;color:#fff;}.login-page .login-box .logo small{display:block;width:100%;text-align:center;color:#fff;margin-top:-5px;}.signup-page{background-color:#00bcd4;padding-left:0;max-width:360px;margin:5% auto;overflow-x:hidden;}.signup-page .signup-box .msg{color:#555;margin-bottom:30px;text-align:center;}.signup-page .signup-box a{font-size:14px;text-decoration:none;color:#00bcd4;}.signup-page .signup-box .logo{margin-bottom:20px;}.signup-page .signup-box .logo a{font-size:36px;display:block;width:100%;text-align:center;color:#fff;}.signup-page .signup-box .logo small{display:block;width:100%;text-align:center;color:#fff;margin-top:-5px;}.fp-page{background-color:#00bcd4;padding-left:0;max-width:360px;margin:5% auto;overflow-x:hidden;}.fp-page .fp-box .msg{color:#555;margin-bottom:30px;text-align:center;}.fp-page .fp-box a{font-size:14px;text-decoration:none;color:#00bcd4;}.fp-page .fp-box .logo{margin-bottom:20px;}.fp-page .fp-box .logo a{font-size:36px;display:block;width:100%;text-align:center;color:#fff;}.fp-page .fp-box .logo small{display:block;width:100%;text-align:center;color:#fff;margin-top:-5px;}.four-zero-four{width:100%;text-align:center;margin:5% auto;}.four-zero-four .four-zero-four-container .error-code{font-size:160px;}.four-zero-four .four-zero-four-container .error-message{font-size:26px;color:#333;font-weight:bold;margin-top:-40px;}.four-zero-four .four-zero-four-container .button-place{margin-top:32px;}.five-zero-zero{width:100%;text-align:center;margin:5% auto;}.five-zero-zero .five-zero-zero-container .error-code{font-size:160px;}.five-zero-zero .five-zero-zero-container .error-message{font-size:27px;color:#333;font-weight:bold;margin-top:-40px;}.five-zero-zero .five-zero-zero-container .button-place{margin-top:32px;}.gmap{width:100%;height:400px;}.jvector-map{width:100%;height:600px;}.morris-hover.morris-default-style{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}.flot-chart{width:100%;height:320px;}.panel-switch-btn{position:relative;right:20px;z-index:9;}.panel-switch-btn label{font-weight:bold !important;}.legendLabel{width:85px !important;position:relative;left:3px;}#multiple_axis_chart .legendLabel{width:160px !important;}.sparkline{text-align:center;}.search-bar{position:fixed;top:-100px;left:0;z-index:9999999;width:100%;-moz-transition:.25s;-o-transition:.25s;-webkit-transition:.25s;transition:.25s;}.search-bar.open{top:0;}.search-bar .search-icon{position:absolute;top:20px;left:14px;}.search-bar .search-icon .material-icons{font-size:32px;color:#999;}.search-bar .close-search{position:absolute;cursor:pointer;font-size:30px;top:16px;right:18px;}.search-bar .close-search .material-icons{color:#999;opacity:1;-moz-transition:.5s;-o-transition:.5s;-webkit-transition:.5s;transition:.5s;}.search-bar .close-search .material-icons:hover{opacity:.5;}.search-bar input[type="text"]{width:100%;font-size:16px;padding:25px 60px 23px 56px;border:none;}.dataTables_wrapper{position:relative;}.dataTables_wrapper select{border:none;border-bottom:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;box-shadow:none;}.dataTables_wrapper select:active,.dataTables_wrapper select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;box-shadow:none;}.dataTables_wrapper input[type="search"]{-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;box-shadow:none;border:none;font-size:12px;border-bottom:1px solid #ddd;}.dataTables_wrapper input[type="search"]:focus,.dataTables_wrapper input[type="search"]:active{border-bottom:2px solid #1f91f3;}.dataTables_wrapper .dt-buttons{float:left;}.dataTables_wrapper .dt-buttons a.dt-button{background-color:#607d8b;color:#fff;padding:7px 12px;margin-right:5px;text-decoration:none;box-shadow:0 2px 5px rgba(0,0,0,.16),0 2px 10px rgba(0,0,0,.12);-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;border-radius:2px;border:none;font-size:13px;outline:none;}.dataTables_wrapper .dt-buttons a.dt-button:active{opacity:.8;}.dt-button-info{position:fixed;top:50%;left:50%;min-width:400px;text-align:center;background-color:#fff;border:2px solid #999;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;margin-top:-100px;margin-left:-200px;z-index:21;}.dt-button-info h2{color:#777;}.dt-button-info div{color:#777;margin-bottom:20px;}.lg-outer .lg-thumb-item,.lg-outer .lg-toogle-thumb{-webkit-border-radius:0 !important;-moz-border-radius:0 !important;-ms-border-radius:0 !important;border-radius:0 !important;}html.ie10 .sidebar .menu .list li{line-height:30px;}html.ie10 .sidebar .menu .list .ml-menu li.active a:not(.menu-toggle).toggled:before{top:6px !important;line-height:20px !important;}html.ie10 .sidebar .user-info .info-container{top:15px;}html.ie10 .search-bar input[type="text"]{padding:26px 60px 26px 56px;}html.ie10 .dropdown-menu ul.menu li a{margin-top:-22px;}html.ie10 .bs-searchbox .form-control{width:90%;}html.ie11 .sidebar .menu .list .ml-menu li.active a:not(.menu-toggle).toggled:before{top:6px !important;line-height:20px !important;}html.ie11 .sidebar .user-info .info-container{top:15px;}html.ie11 .search-bar input[type="text"]{padding:26px 60px 26px 56px;}html.ie11 .dropdown-menu ul.menu li a{margin-top:-22px;}html.ie11 .bs-searchbox .form-control{width:90%;} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/css/themes/all-themes.css b/Plan/common/src/main/resources/assets/plan/web/css/themes/all-themes.css deleted file mode 100644 index cca9450cc..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/css/themes/all-themes.css +++ /dev/null @@ -1,900 +0,0 @@ -.theme-red .navbar { - background-color: #F44336; } - -.theme-red .navbar-brand { - color: #fff; } - .theme-red .navbar-brand:hover { - color: #fff; } - .theme-red .navbar-brand:active { - color: #fff; } - .theme-red .navbar-brand:focus { - color: #fff; } - -.theme-red .nav > li > a { - color: #fff; } - .theme-red .nav > li > a:hover { - background-color: transparent; } - .theme-red .nav > li > a:focus { - background-color: transparent; } - -.theme-red .nav .open > a { - background-color: transparent; } - .theme-red .nav .open > a:hover { - background-color: transparent; } - .theme-red .nav .open > a:focus { - background-color: transparent; } - -.theme-red .bars { - color: #fff; } - -.theme-red .sidebar .menu .list li.active { - background-color: transparent; } - .theme-red .sidebar .menu .list li.active > :first-child i, .theme-red .sidebar .menu .list li.active > :first-child span { - color: #F44336; } - -.theme-red .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-red .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-red .sidebar .legal { - background-color: #fff; } - .theme-red .sidebar .legal .copyright a { - color: #F44336 !important; } - -.theme-pink .navbar { - background-color: #E91E63; } - -.theme-pink .navbar-brand { - color: #fff; } - .theme-pink .navbar-brand:hover { - color: #fff; } - .theme-pink .navbar-brand:active { - color: #fff; } - .theme-pink .navbar-brand:focus { - color: #fff; } - -.theme-pink .nav > li > a { - color: #fff; } - .theme-pink .nav > li > a:hover { - background-color: transparent; } - .theme-pink .nav > li > a:focus { - background-color: transparent; } - -.theme-pink .nav .open > a { - background-color: transparent; } - .theme-pink .nav .open > a:hover { - background-color: transparent; } - .theme-pink .nav .open > a:focus { - background-color: transparent; } - -.theme-pink .bars { - color: #fff; } - -.theme-pink .sidebar .menu .list li.active { - background-color: transparent; } - .theme-pink .sidebar .menu .list li.active > :first-child i, .theme-pink .sidebar .menu .list li.active > :first-child span { - color: #E91E63; } - -.theme-pink .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-pink .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-pink .sidebar .legal { - background-color: #fff; } - .theme-pink .sidebar .legal .copyright a { - color: #E91E63 !important; } - -.theme-purple .navbar { - background-color: #9C27B0; } - -.theme-purple .navbar-brand { - color: #fff; } - .theme-purple .navbar-brand:hover { - color: #fff; } - .theme-purple .navbar-brand:active { - color: #fff; } - .theme-purple .navbar-brand:focus { - color: #fff; } - -.theme-purple .nav > li > a { - color: #fff; } - .theme-purple .nav > li > a:hover { - background-color: transparent; } - .theme-purple .nav > li > a:focus { - background-color: transparent; } - -.theme-purple .nav .open > a { - background-color: transparent; } - .theme-purple .nav .open > a:hover { - background-color: transparent; } - .theme-purple .nav .open > a:focus { - background-color: transparent; } - -.theme-purple .bars { - color: #fff; } - -.theme-purple .sidebar .menu .list li.active { - background-color: transparent; } - .theme-purple .sidebar .menu .list li.active > :first-child i, .theme-purple .sidebar .menu .list li.active > :first-child span { - color: #9C27B0; } - -.theme-purple .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-purple .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-purple .sidebar .legal { - background-color: #fff; } - .theme-purple .sidebar .legal .copyright a { - color: #9C27B0 !important; } - -.theme-deep-purple .navbar { - background-color: #673AB7; } - -.theme-deep-purple .navbar-brand { - color: #fff; } - .theme-deep-purple .navbar-brand:hover { - color: #fff; } - .theme-deep-purple .navbar-brand:active { - color: #fff; } - .theme-deep-purple .navbar-brand:focus { - color: #fff; } - -.theme-deep-purple .nav > li > a { - color: #fff; } - .theme-deep-purple .nav > li > a:hover { - background-color: transparent; } - .theme-deep-purple .nav > li > a:focus { - background-color: transparent; } - -.theme-deep-purple .nav .open > a { - background-color: transparent; } - .theme-deep-purple .nav .open > a:hover { - background-color: transparent; } - .theme-deep-purple .nav .open > a:focus { - background-color: transparent; } - -.theme-deep-purple .bars { - color: #fff; } - -.theme-deep-purple .sidebar .menu .list li.active { - background-color: transparent; } - .theme-deep-purple .sidebar .menu .list li.active > :first-child i, .theme-deep-purple .sidebar .menu .list li.active > :first-child span { - color: #673AB7; } - -.theme-deep-purple .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-deep-purple .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-deep-purple .sidebar .legal { - background-color: #fff; } - .theme-deep-purple .sidebar .legal .copyright a { - color: #673AB7 !important; } - -.theme-indigo .navbar { - background-color: #3F51B5; } - -.theme-indigo .navbar-brand { - color: #fff; } - .theme-indigo .navbar-brand:hover { - color: #fff; } - .theme-indigo .navbar-brand:active { - color: #fff; } - .theme-indigo .navbar-brand:focus { - color: #fff; } - -.theme-indigo .nav > li > a { - color: #fff; } - .theme-indigo .nav > li > a:hover { - background-color: transparent; } - .theme-indigo .nav > li > a:focus { - background-color: transparent; } - -.theme-indigo .nav .open > a { - background-color: transparent; } - .theme-indigo .nav .open > a:hover { - background-color: transparent; } - .theme-indigo .nav .open > a:focus { - background-color: transparent; } - -.theme-indigo .bars { - color: #fff; } - -.theme-indigo .sidebar .menu .list li.active { - background-color: transparent; } - .theme-indigo .sidebar .menu .list li.active > :first-child i, .theme-indigo .sidebar .menu .list li.active > :first-child span { - color: #3F51B5; } - -.theme-indigo .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-indigo .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-indigo .sidebar .legal { - background-color: #fff; } - .theme-indigo .sidebar .legal .copyright a { - color: #3F51B5 !important; } - -.theme-blue .navbar { - background-color: #2196F3; } - -.theme-blue .navbar-brand { - color: #fff; } - .theme-blue .navbar-brand:hover { - color: #fff; } - .theme-blue .navbar-brand:active { - color: #fff; } - .theme-blue .navbar-brand:focus { - color: #fff; } - -.theme-blue .nav > li > a { - color: #fff; } - .theme-blue .nav > li > a:hover { - background-color: transparent; } - .theme-blue .nav > li > a:focus { - background-color: transparent; } - -.theme-blue .nav .open > a { - background-color: transparent; } - .theme-blue .nav .open > a:hover { - background-color: transparent; } - .theme-blue .nav .open > a:focus { - background-color: transparent; } - -.theme-blue .bars { - color: #fff; } - -.theme-blue .sidebar .menu .list li.active { - background-color: transparent; } - .theme-blue .sidebar .menu .list li.active > :first-child i, .theme-blue .sidebar .menu .list li.active > :first-child span { - color: #2196F3; } - -.theme-blue .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-blue .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-blue .sidebar .legal { - background-color: #fff; } - .theme-blue .sidebar .legal .copyright a { - color: #2196F3 !important; } - -.theme-light-blue .navbar { - background-color: #03A9F4; } - -.theme-light-blue .navbar-brand { - color: #fff; } - .theme-light-blue .navbar-brand:hover { - color: #fff; } - .theme-light-blue .navbar-brand:active { - color: #fff; } - .theme-light-blue .navbar-brand:focus { - color: #fff; } - -.theme-light-blue .nav > li > a { - color: #fff; } - .theme-light-blue .nav > li > a:hover { - background-color: transparent; } - .theme-light-blue .nav > li > a:focus { - background-color: transparent; } - -.theme-light-blue .nav .open > a { - background-color: transparent; } - .theme-light-blue .nav .open > a:hover { - background-color: transparent; } - .theme-light-blue .nav .open > a:focus { - background-color: transparent; } - -.theme-light-blue .bars { - color: #fff; } - -.theme-light-blue .sidebar .menu .list li.active { - background-color: transparent; } - .theme-light-blue .sidebar .menu .list li.active > :first-child i, .theme-light-blue .sidebar .menu .list li.active > :first-child span { - color: #03A9F4; } - -.theme-light-blue .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-light-blue .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-light-blue .sidebar .legal { - background-color: #fff; } - .theme-light-blue .sidebar .legal .copyright a { - color: #03A9F4 !important; } - -.theme-cyan .navbar { - background-color: #00BCD4; } - -.theme-cyan .navbar-brand { - color: #fff; } - .theme-cyan .navbar-brand:hover { - color: #fff; } - .theme-cyan .navbar-brand:active { - color: #fff; } - .theme-cyan .navbar-brand:focus { - color: #fff; } - -.theme-cyan .nav > li > a { - color: #fff; } - .theme-cyan .nav > li > a:hover { - background-color: transparent; } - .theme-cyan .nav > li > a:focus { - background-color: transparent; } - -.theme-cyan .nav .open > a { - background-color: transparent; } - .theme-cyan .nav .open > a:hover { - background-color: transparent; } - .theme-cyan .nav .open > a:focus { - background-color: transparent; } - -.theme-cyan .bars { - color: #fff; } - -.theme-cyan .sidebar .menu .list li.active { - background-color: transparent; } - .theme-cyan .sidebar .menu .list li.active > :first-child i, .theme-cyan .sidebar .menu .list li.active > :first-child span { - color: #00BCD4; } - -.theme-cyan .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-cyan .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-cyan .sidebar .legal { - background-color: #fff; } - .theme-cyan .sidebar .legal .copyright a { - color: #00BCD4 !important; } - -.theme-teal .navbar { - background-color: #009688; } - -.theme-teal .navbar-brand { - color: #fff; } - .theme-teal .navbar-brand:hover { - color: #fff; } - .theme-teal .navbar-brand:active { - color: #fff; } - .theme-teal .navbar-brand:focus { - color: #fff; } - -.theme-teal .nav > li > a { - color: #fff; } - .theme-teal .nav > li > a:hover { - background-color: transparent; } - .theme-teal .nav > li > a:focus { - background-color: transparent; } - -.theme-teal .nav .open > a { - background-color: transparent; } - .theme-teal .nav .open > a:hover { - background-color: transparent; } - .theme-teal .nav .open > a:focus { - background-color: transparent; } - -.theme-teal .bars { - color: #fff; } - -.theme-teal .sidebar .menu .list li.active { - background-color: transparent; } - .theme-teal .sidebar .menu .list li.active > :first-child i, .theme-teal .sidebar .menu .list li.active > :first-child span { - color: #009688; } - -.theme-teal .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-teal .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-teal .sidebar .legal { - background-color: #fff; } - .theme-teal .sidebar .legal .copyright a { - color: #009688 !important; } - -.theme-green .navbar { - background-color: #4CAF50; } - -.theme-green .navbar-brand { - color: #fff; } - .theme-green .navbar-brand:hover { - color: #fff; } - .theme-green .navbar-brand:active { - color: #fff; } - .theme-green .navbar-brand:focus { - color: #fff; } - -.theme-green .nav > li > a { - color: #fff; } - .theme-green .nav > li > a:hover { - background-color: transparent; } - .theme-green .nav > li > a:focus { - background-color: transparent; } - -.theme-green .nav .open > a { - background-color: transparent; } - .theme-green .nav .open > a:hover { - background-color: transparent; } - .theme-green .nav .open > a:focus { - background-color: transparent; } - -.theme-green .bars { - color: #fff; } - -.theme-green .sidebar .menu .list li.active { - background-color: transparent; } - .theme-green .sidebar .menu .list li.active > :first-child i, .theme-green .sidebar .menu .list li.active > :first-child span { - color: #4CAF50; } - -.theme-green .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-green .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-green .sidebar .legal { - background-color: #fff; } - .theme-green .sidebar .legal .copyright a { - color: #4CAF50 !important; } - -.theme-light-green .navbar { - background-color: #8BC34A; } - -.theme-light-green .navbar-brand { - color: #fff; } - .theme-light-green .navbar-brand:hover { - color: #fff; } - .theme-light-green .navbar-brand:active { - color: #fff; } - .theme-light-green .navbar-brand:focus { - color: #fff; } - -.theme-light-green .nav > li > a { - color: #fff; } - .theme-light-green .nav > li > a:hover { - background-color: transparent; } - .theme-light-green .nav > li > a:focus { - background-color: transparent; } - -.theme-light-green .nav .open > a { - background-color: transparent; } - .theme-light-green .nav .open > a:hover { - background-color: transparent; } - .theme-light-green .nav .open > a:focus { - background-color: transparent; } - -.theme-light-green .bars { - color: #fff; } - -.theme-light-green .sidebar .menu .list li.active { - background-color: transparent; } - .theme-light-green .sidebar .menu .list li.active > :first-child i, .theme-light-green .sidebar .menu .list li.active > :first-child span { - color: #8BC34A; } - -.theme-light-green .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-light-green .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-light-green .sidebar .legal { - background-color: #fff; } - .theme-light-green .sidebar .legal .copyright a { - color: #8BC34A !important; } - -.theme-lime .navbar { - background-color: #CDDC39; } - -.theme-lime .navbar-brand { - color: #fff; } - .theme-lime .navbar-brand:hover { - color: #fff; } - .theme-lime .navbar-brand:active { - color: #fff; } - .theme-lime .navbar-brand:focus { - color: #fff; } - -.theme-lime .nav > li > a { - color: #fff; } - .theme-lime .nav > li > a:hover { - background-color: transparent; } - .theme-lime .nav > li > a:focus { - background-color: transparent; } - -.theme-lime .nav .open > a { - background-color: transparent; } - .theme-lime .nav .open > a:hover { - background-color: transparent; } - .theme-lime .nav .open > a:focus { - background-color: transparent; } - -.theme-lime .bars { - color: #fff; } - -.theme-lime .sidebar .menu .list li.active { - background-color: transparent; } - .theme-lime .sidebar .menu .list li.active > :first-child i, .theme-lime .sidebar .menu .list li.active > :first-child span { - color: #CDDC39; } - -.theme-lime .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-lime .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-lime .sidebar .legal { - background-color: #fff; } - .theme-lime .sidebar .legal .copyright a { - color: #CDDC39 !important; } - -.theme-yellow .navbar { - background-color: #FFEB3B; } - -.theme-yellow .navbar-brand { - color: #fff; } - .theme-yellow .navbar-brand:hover { - color: #fff; } - .theme-yellow .navbar-brand:active { - color: #fff; } - .theme-yellow .navbar-brand:focus { - color: #fff; } - -.theme-yellow .nav > li > a { - color: #fff; } - .theme-yellow .nav > li > a:hover { - background-color: transparent; } - .theme-yellow .nav > li > a:focus { - background-color: transparent; } - -.theme-yellow .nav .open > a { - background-color: transparent; } - .theme-yellow .nav .open > a:hover { - background-color: transparent; } - .theme-yellow .nav .open > a:focus { - background-color: transparent; } - -.theme-yellow .bars { - color: #fff; } - -.theme-yellow .sidebar .menu .list li.active { - background-color: transparent; } - .theme-yellow .sidebar .menu .list li.active > :first-child i, .theme-yellow .sidebar .menu .list li.active > :first-child span { - color: #FFEB3B; } - -.theme-yellow .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-yellow .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-yellow .sidebar .legal { - background-color: #fff; } - .theme-yellow .sidebar .legal .copyright a { - color: #FFEB3B !important; } - -.theme-amber .navbar { - background-color: #FFC107; } - -.theme-amber .navbar-brand { - color: #fff; } - .theme-amber .navbar-brand:hover { - color: #fff; } - .theme-amber .navbar-brand:active { - color: #fff; } - .theme-amber .navbar-brand:focus { - color: #fff; } - -.theme-amber .nav > li > a { - color: #fff; } - .theme-amber .nav > li > a:hover { - background-color: transparent; } - .theme-amber .nav > li > a:focus { - background-color: transparent; } - -.theme-amber .nav .open > a { - background-color: transparent; } - .theme-amber .nav .open > a:hover { - background-color: transparent; } - .theme-amber .nav .open > a:focus { - background-color: transparent; } - -.theme-amber .bars { - color: #fff; } - -.theme-amber .sidebar .menu .list li.active { - background-color: transparent; } - .theme-amber .sidebar .menu .list li.active > :first-child i, .theme-amber .sidebar .menu .list li.active > :first-child span { - color: #FFC107; } - -.theme-amber .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-amber .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-amber .sidebar .legal { - background-color: #fff; } - .theme-amber .sidebar .legal .copyright a { - color: #FFC107 !important; } - -.theme-orange .navbar { - background-color: #FF9800; } - -.theme-orange .navbar-brand { - color: #fff; } - .theme-orange .navbar-brand:hover { - color: #fff; } - .theme-orange .navbar-brand:active { - color: #fff; } - .theme-orange .navbar-brand:focus { - color: #fff; } - -.theme-orange .nav > li > a { - color: #fff; } - .theme-orange .nav > li > a:hover { - background-color: transparent; } - .theme-orange .nav > li > a:focus { - background-color: transparent; } - -.theme-orange .nav .open > a { - background-color: transparent; } - .theme-orange .nav .open > a:hover { - background-color: transparent; } - .theme-orange .nav .open > a:focus { - background-color: transparent; } - -.theme-orange .bars { - color: #fff; } - -.theme-orange .sidebar .menu .list li.active { - background-color: transparent; } - .theme-orange .sidebar .menu .list li.active > :first-child i, .theme-orange .sidebar .menu .list li.active > :first-child span { - color: #FF9800; } - -.theme-orange .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-orange .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-orange .sidebar .legal { - background-color: #fff; } - .theme-orange .sidebar .legal .copyright a { - color: #FF9800 !important; } - -.theme-deep-orange .navbar { - background-color: #FF5722; } - -.theme-deep-orange .navbar-brand { - color: #fff; } - .theme-deep-orange .navbar-brand:hover { - color: #fff; } - .theme-deep-orange .navbar-brand:active { - color: #fff; } - .theme-deep-orange .navbar-brand:focus { - color: #fff; } - -.theme-deep-orange .nav > li > a { - color: #fff; } - .theme-deep-orange .nav > li > a:hover { - background-color: transparent; } - .theme-deep-orange .nav > li > a:focus { - background-color: transparent; } - -.theme-deep-orange .nav .open > a { - background-color: transparent; } - .theme-deep-orange .nav .open > a:hover { - background-color: transparent; } - .theme-deep-orange .nav .open > a:focus { - background-color: transparent; } - -.theme-deep-orange .bars { - color: #fff; } - -.theme-deep-orange .sidebar .menu .list li.active { - background-color: transparent; } - .theme-deep-orange .sidebar .menu .list li.active > :first-child i, .theme-deep-orange .sidebar .menu .list li.active > :first-child span { - color: #FF5722; } - -.theme-deep-orange .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-deep-orange .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-deep-orange .sidebar .legal { - background-color: #fff; } - .theme-deep-orange .sidebar .legal .copyright a { - color: #FF5722 !important; } - -.theme-brown .navbar { - background-color: #795548; } - -.theme-brown .navbar-brand { - color: #fff; } - .theme-brown .navbar-brand:hover { - color: #fff; } - .theme-brown .navbar-brand:active { - color: #fff; } - .theme-brown .navbar-brand:focus { - color: #fff; } - -.theme-brown .nav > li > a { - color: #fff; } - .theme-brown .nav > li > a:hover { - background-color: transparent; } - .theme-brown .nav > li > a:focus { - background-color: transparent; } - -.theme-brown .nav .open > a { - background-color: transparent; } - .theme-brown .nav .open > a:hover { - background-color: transparent; } - .theme-brown .nav .open > a:focus { - background-color: transparent; } - -.theme-brown .bars { - color: #fff; } - -.theme-brown .sidebar .menu .list li.active { - background-color: transparent; } - .theme-brown .sidebar .menu .list li.active > :first-child i, .theme-brown .sidebar .menu .list li.active > :first-child span { - color: #795548; } - -.theme-brown .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-brown .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-brown .sidebar .legal { - background-color: #fff; } - .theme-brown .sidebar .legal .copyright a { - color: #795548 !important; } - -.theme-grey .navbar { - background-color: #9E9E9E; } - -.theme-grey .navbar-brand { - color: #fff; } - .theme-grey .navbar-brand:hover { - color: #fff; } - .theme-grey .navbar-brand:active { - color: #fff; } - .theme-grey .navbar-brand:focus { - color: #fff; } - -.theme-grey .nav > li > a { - color: #fff; } - .theme-grey .nav > li > a:hover { - background-color: transparent; } - .theme-grey .nav > li > a:focus { - background-color: transparent; } - -.theme-grey .nav .open > a { - background-color: transparent; } - .theme-grey .nav .open > a:hover { - background-color: transparent; } - .theme-grey .nav .open > a:focus { - background-color: transparent; } - -.theme-grey .bars { - color: #fff; } - -.theme-grey .sidebar .menu .list li.active { - background-color: transparent; } - .theme-grey .sidebar .menu .list li.active > :first-child i, .theme-grey .sidebar .menu .list li.active > :first-child span { - color: #9E9E9E; } - -.theme-grey .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-grey .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-grey .sidebar .legal { - background-color: #fff; } - .theme-grey .sidebar .legal .copyright a { - color: #9E9E9E !important; } - -.theme-blue-grey .navbar { - background-color: #607D8B; } - -.theme-blue-grey .navbar-brand { - color: #fff; } - .theme-blue-grey .navbar-brand:hover { - color: #fff; } - .theme-blue-grey .navbar-brand:active { - color: #fff; } - .theme-blue-grey .navbar-brand:focus { - color: #fff; } - -.theme-blue-grey .nav > li > a { - color: #fff; } - .theme-blue-grey .nav > li > a:hover { - background-color: transparent; } - .theme-blue-grey .nav > li > a:focus { - background-color: transparent; } - -.theme-blue-grey .nav .open > a { - background-color: transparent; } - .theme-blue-grey .nav .open > a:hover { - background-color: transparent; } - .theme-blue-grey .nav .open > a:focus { - background-color: transparent; } - -.theme-blue-grey .bars { - color: #fff; } - -.theme-blue-grey .sidebar .menu .list li.active { - background-color: transparent; } - .theme-blue-grey .sidebar .menu .list li.active > :first-child i, .theme-blue-grey .sidebar .menu .list li.active > :first-child span { - color: #607D8B; } - -.theme-blue-grey .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-blue-grey .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-blue-grey .sidebar .legal { - background-color: #fff; } - .theme-blue-grey .sidebar .legal .copyright a { - color: #607D8B !important; } - -.theme-black .navbar { - background-color: #000; } - -.theme-black .navbar-brand { - color: #fff; } - .theme-black .navbar-brand:hover { - color: #fff; } - .theme-black .navbar-brand:active { - color: #fff; } - .theme-black .navbar-brand:focus { - color: #fff; } - -.theme-black .nav > li > a { - color: #fff; } - .theme-black .nav > li > a:hover { - background-color: transparent; } - .theme-black .nav > li > a:focus { - background-color: transparent; } - -.theme-black .nav .open > a { - background-color: transparent; } - .theme-black .nav .open > a:hover { - background-color: transparent; } - .theme-black .nav .open > a:focus { - background-color: transparent; } - -.theme-black .bars { - color: #fff; } - -.theme-black .sidebar .menu .list li.active { - background-color: transparent; } - .theme-black .sidebar .menu .list li.active > :first-child i, .theme-black .sidebar .menu .list li.active > :first-child span { - color: #000; } - -.theme-black .sidebar .menu .list .toggled { - background-color: transparent; } - -.theme-black .sidebar .menu .list .ml-menu { - background-color: transparent; } - -.theme-black .sidebar .legal { - background-color: #fff; } - .theme-black .sidebar .legal .copyright a { - color: #000 !important; } - diff --git a/Plan/common/src/main/resources/assets/plan/web/css/themes/all-themes.min.css b/Plan/common/src/main/resources/assets/plan/web/css/themes/all-themes.min.css deleted file mode 100644 index ecb402362..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/css/themes/all-themes.min.css +++ /dev/null @@ -1 +0,0 @@ -.theme-red .navbar{background-color:#f44336;}.theme-red .navbar-brand{color:#fff;}.theme-red .navbar-brand:hover{color:#fff;}.theme-red .navbar-brand:active{color:#fff;}.theme-red .navbar-brand:focus{color:#fff;}.theme-red .nav>li>a{color:#fff;}.theme-red .nav>li>a:hover{background-color:transparent;}.theme-red .nav>li>a:focus{background-color:transparent;}.theme-red .nav .open>a{background-color:transparent;}.theme-red .nav .open>a:hover{background-color:transparent;}.theme-red .nav .open>a:focus{background-color:transparent;}.theme-red .bars{color:#fff;}.theme-red .sidebar .menu .list li.active{background-color:transparent;}.theme-red .sidebar .menu .list li.active>:first-child i,.theme-red .sidebar .menu .list li.active>:first-child span{color:#f44336;}.theme-red .sidebar .menu .list .toggled{background-color:transparent;}.theme-red .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-red .sidebar .legal{background-color:#fff;}.theme-red .sidebar .legal .copyright a{color:#f44336 !important;}.theme-pink .navbar{background-color:#e91e63;}.theme-pink .navbar-brand{color:#fff;}.theme-pink .navbar-brand:hover{color:#fff;}.theme-pink .navbar-brand:active{color:#fff;}.theme-pink .navbar-brand:focus{color:#fff;}.theme-pink .nav>li>a{color:#fff;}.theme-pink .nav>li>a:hover{background-color:transparent;}.theme-pink .nav>li>a:focus{background-color:transparent;}.theme-pink .nav .open>a{background-color:transparent;}.theme-pink .nav .open>a:hover{background-color:transparent;}.theme-pink .nav .open>a:focus{background-color:transparent;}.theme-pink .bars{color:#fff;}.theme-pink .sidebar .menu .list li.active{background-color:transparent;}.theme-pink .sidebar .menu .list li.active>:first-child i,.theme-pink .sidebar .menu .list li.active>:first-child span{color:#e91e63;}.theme-pink .sidebar .menu .list .toggled{background-color:transparent;}.theme-pink .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-pink .sidebar .legal{background-color:#fff;}.theme-pink .sidebar .legal .copyright a{color:#e91e63 !important;}.theme-purple .navbar{background-color:#9c27b0;}.theme-purple .navbar-brand{color:#fff;}.theme-purple .navbar-brand:hover{color:#fff;}.theme-purple .navbar-brand:active{color:#fff;}.theme-purple .navbar-brand:focus{color:#fff;}.theme-purple .nav>li>a{color:#fff;}.theme-purple .nav>li>a:hover{background-color:transparent;}.theme-purple .nav>li>a:focus{background-color:transparent;}.theme-purple .nav .open>a{background-color:transparent;}.theme-purple .nav .open>a:hover{background-color:transparent;}.theme-purple .nav .open>a:focus{background-color:transparent;}.theme-purple .bars{color:#fff;}.theme-purple .sidebar .menu .list li.active{background-color:transparent;}.theme-purple .sidebar .menu .list li.active>:first-child i,.theme-purple .sidebar .menu .list li.active>:first-child span{color:#9c27b0;}.theme-purple .sidebar .menu .list .toggled{background-color:transparent;}.theme-purple .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-purple .sidebar .legal{background-color:#fff;}.theme-purple .sidebar .legal .copyright a{color:#9c27b0 !important;}.theme-deep-purple .navbar{background-color:#673ab7;}.theme-deep-purple .navbar-brand{color:#fff;}.theme-deep-purple .navbar-brand:hover{color:#fff;}.theme-deep-purple .navbar-brand:active{color:#fff;}.theme-deep-purple .navbar-brand:focus{color:#fff;}.theme-deep-purple .nav>li>a{color:#fff;}.theme-deep-purple .nav>li>a:hover{background-color:transparent;}.theme-deep-purple .nav>li>a:focus{background-color:transparent;}.theme-deep-purple .nav .open>a{background-color:transparent;}.theme-deep-purple .nav .open>a:hover{background-color:transparent;}.theme-deep-purple .nav .open>a:focus{background-color:transparent;}.theme-deep-purple .bars{color:#fff;}.theme-deep-purple .sidebar .menu .list li.active{background-color:transparent;}.theme-deep-purple .sidebar .menu .list li.active>:first-child i,.theme-deep-purple .sidebar .menu .list li.active>:first-child span{color:#673ab7;}.theme-deep-purple .sidebar .menu .list .toggled{background-color:transparent;}.theme-deep-purple .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-deep-purple .sidebar .legal{background-color:#fff;}.theme-deep-purple .sidebar .legal .copyright a{color:#673ab7 !important;}.theme-indigo .navbar{background-color:#3f51b5;}.theme-indigo .navbar-brand{color:#fff;}.theme-indigo .navbar-brand:hover{color:#fff;}.theme-indigo .navbar-brand:active{color:#fff;}.theme-indigo .navbar-brand:focus{color:#fff;}.theme-indigo .nav>li>a{color:#fff;}.theme-indigo .nav>li>a:hover{background-color:transparent;}.theme-indigo .nav>li>a:focus{background-color:transparent;}.theme-indigo .nav .open>a{background-color:transparent;}.theme-indigo .nav .open>a:hover{background-color:transparent;}.theme-indigo .nav .open>a:focus{background-color:transparent;}.theme-indigo .bars{color:#fff;}.theme-indigo .sidebar .menu .list li.active{background-color:transparent;}.theme-indigo .sidebar .menu .list li.active>:first-child i,.theme-indigo .sidebar .menu .list li.active>:first-child span{color:#3f51b5;}.theme-indigo .sidebar .menu .list .toggled{background-color:transparent;}.theme-indigo .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-indigo .sidebar .legal{background-color:#fff;}.theme-indigo .sidebar .legal .copyright a{color:#3f51b5 !important;}.theme-blue .navbar{background-color:#2196f3;}.theme-blue .navbar-brand{color:#fff;}.theme-blue .navbar-brand:hover{color:#fff;}.theme-blue .navbar-brand:active{color:#fff;}.theme-blue .navbar-brand:focus{color:#fff;}.theme-blue .nav>li>a{color:#fff;}.theme-blue .nav>li>a:hover{background-color:transparent;}.theme-blue .nav>li>a:focus{background-color:transparent;}.theme-blue .nav .open>a{background-color:transparent;}.theme-blue .nav .open>a:hover{background-color:transparent;}.theme-blue .nav .open>a:focus{background-color:transparent;}.theme-blue .bars{color:#fff;}.theme-blue .sidebar .menu .list li.active{background-color:transparent;}.theme-blue .sidebar .menu .list li.active>:first-child i,.theme-blue .sidebar .menu .list li.active>:first-child span{color:#2196f3;}.theme-blue .sidebar .menu .list .toggled{background-color:transparent;}.theme-blue .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-blue .sidebar .legal{background-color:#fff;}.theme-blue .sidebar .legal .copyright a{color:#2196f3 !important;}.theme-light-blue .navbar{background-color:#03a9f4;}.theme-light-blue .navbar-brand{color:#fff;}.theme-light-blue .navbar-brand:hover{color:#fff;}.theme-light-blue .navbar-brand:active{color:#fff;}.theme-light-blue .navbar-brand:focus{color:#fff;}.theme-light-blue .nav>li>a{color:#fff;}.theme-light-blue .nav>li>a:hover{background-color:transparent;}.theme-light-blue .nav>li>a:focus{background-color:transparent;}.theme-light-blue .nav .open>a{background-color:transparent;}.theme-light-blue .nav .open>a:hover{background-color:transparent;}.theme-light-blue .nav .open>a:focus{background-color:transparent;}.theme-light-blue .bars{color:#fff;}.theme-light-blue .sidebar .menu .list li.active{background-color:transparent;}.theme-light-blue .sidebar .menu .list li.active>:first-child i,.theme-light-blue .sidebar .menu .list li.active>:first-child span{color:#03a9f4;}.theme-light-blue .sidebar .menu .list .toggled{background-color:transparent;}.theme-light-blue .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-light-blue .sidebar .legal{background-color:#fff;}.theme-light-blue .sidebar .legal .copyright a{color:#03a9f4 !important;}.theme-cyan .navbar{background-color:#00bcd4;}.theme-cyan .navbar-brand{color:#fff;}.theme-cyan .navbar-brand:hover{color:#fff;}.theme-cyan .navbar-brand:active{color:#fff;}.theme-cyan .navbar-brand:focus{color:#fff;}.theme-cyan .nav>li>a{color:#fff;}.theme-cyan .nav>li>a:hover{background-color:transparent;}.theme-cyan .nav>li>a:focus{background-color:transparent;}.theme-cyan .nav .open>a{background-color:transparent;}.theme-cyan .nav .open>a:hover{background-color:transparent;}.theme-cyan .nav .open>a:focus{background-color:transparent;}.theme-cyan .bars{color:#fff;}.theme-cyan .sidebar .menu .list li.active{background-color:transparent;}.theme-cyan .sidebar .menu .list li.active>:first-child i,.theme-cyan .sidebar .menu .list li.active>:first-child span{color:#00bcd4;}.theme-cyan .sidebar .menu .list .toggled{background-color:transparent;}.theme-cyan .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-cyan .sidebar .legal{background-color:#fff;}.theme-cyan .sidebar .legal .copyright a{color:#00bcd4 !important;}.theme-teal .navbar{background-color:#009688;}.theme-teal .navbar-brand{color:#fff;}.theme-teal .navbar-brand:hover{color:#fff;}.theme-teal .navbar-brand:active{color:#fff;}.theme-teal .navbar-brand:focus{color:#fff;}.theme-teal .nav>li>a{color:#fff;}.theme-teal .nav>li>a:hover{background-color:transparent;}.theme-teal .nav>li>a:focus{background-color:transparent;}.theme-teal .nav .open>a{background-color:transparent;}.theme-teal .nav .open>a:hover{background-color:transparent;}.theme-teal .nav .open>a:focus{background-color:transparent;}.theme-teal .bars{color:#fff;}.theme-teal .sidebar .menu .list li.active{background-color:transparent;}.theme-teal .sidebar .menu .list li.active>:first-child i,.theme-teal .sidebar .menu .list li.active>:first-child span{color:#009688;}.theme-teal .sidebar .menu .list .toggled{background-color:transparent;}.theme-teal .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-teal .sidebar .legal{background-color:#fff;}.theme-teal .sidebar .legal .copyright a{color:#009688 !important;}.theme-green .navbar{background-color:#4caf50;}.theme-green .navbar-brand{color:#fff;}.theme-green .navbar-brand:hover{color:#fff;}.theme-green .navbar-brand:active{color:#fff;}.theme-green .navbar-brand:focus{color:#fff;}.theme-green .nav>li>a{color:#fff;}.theme-green .nav>li>a:hover{background-color:transparent;}.theme-green .nav>li>a:focus{background-color:transparent;}.theme-green .nav .open>a{background-color:transparent;}.theme-green .nav .open>a:hover{background-color:transparent;}.theme-green .nav .open>a:focus{background-color:transparent;}.theme-green .bars{color:#fff;}.theme-green .sidebar .menu .list li.active{background-color:transparent;}.theme-green .sidebar .menu .list li.active>:first-child i,.theme-green .sidebar .menu .list li.active>:first-child span{color:#4caf50;}.theme-green .sidebar .menu .list .toggled{background-color:transparent;}.theme-green .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-green .sidebar .legal{background-color:#fff;}.theme-green .sidebar .legal .copyright a{color:#4caf50 !important;}.theme-light-green .navbar{background-color:#8bc34a;}.theme-light-green .navbar-brand{color:#fff;}.theme-light-green .navbar-brand:hover{color:#fff;}.theme-light-green .navbar-brand:active{color:#fff;}.theme-light-green .navbar-brand:focus{color:#fff;}.theme-light-green .nav>li>a{color:#fff;}.theme-light-green .nav>li>a:hover{background-color:transparent;}.theme-light-green .nav>li>a:focus{background-color:transparent;}.theme-light-green .nav .open>a{background-color:transparent;}.theme-light-green .nav .open>a:hover{background-color:transparent;}.theme-light-green .nav .open>a:focus{background-color:transparent;}.theme-light-green .bars{color:#fff;}.theme-light-green .sidebar .menu .list li.active{background-color:transparent;}.theme-light-green .sidebar .menu .list li.active>:first-child i,.theme-light-green .sidebar .menu .list li.active>:first-child span{color:#8bc34a;}.theme-light-green .sidebar .menu .list .toggled{background-color:transparent;}.theme-light-green .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-light-green .sidebar .legal{background-color:#fff;}.theme-light-green .sidebar .legal .copyright a{color:#8bc34a !important;}.theme-lime .navbar{background-color:#cddc39;}.theme-lime .navbar-brand{color:#fff;}.theme-lime .navbar-brand:hover{color:#fff;}.theme-lime .navbar-brand:active{color:#fff;}.theme-lime .navbar-brand:focus{color:#fff;}.theme-lime .nav>li>a{color:#fff;}.theme-lime .nav>li>a:hover{background-color:transparent;}.theme-lime .nav>li>a:focus{background-color:transparent;}.theme-lime .nav .open>a{background-color:transparent;}.theme-lime .nav .open>a:hover{background-color:transparent;}.theme-lime .nav .open>a:focus{background-color:transparent;}.theme-lime .bars{color:#fff;}.theme-lime .sidebar .menu .list li.active{background-color:transparent;}.theme-lime .sidebar .menu .list li.active>:first-child i,.theme-lime .sidebar .menu .list li.active>:first-child span{color:#cddc39;}.theme-lime .sidebar .menu .list .toggled{background-color:transparent;}.theme-lime .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-lime .sidebar .legal{background-color:#fff;}.theme-lime .sidebar .legal .copyright a{color:#cddc39 !important;}.theme-yellow .navbar{background-color:#ffeb3b;}.theme-yellow .navbar-brand{color:#fff;}.theme-yellow .navbar-brand:hover{color:#fff;}.theme-yellow .navbar-brand:active{color:#fff;}.theme-yellow .navbar-brand:focus{color:#fff;}.theme-yellow .nav>li>a{color:#fff;}.theme-yellow .nav>li>a:hover{background-color:transparent;}.theme-yellow .nav>li>a:focus{background-color:transparent;}.theme-yellow .nav .open>a{background-color:transparent;}.theme-yellow .nav .open>a:hover{background-color:transparent;}.theme-yellow .nav .open>a:focus{background-color:transparent;}.theme-yellow .bars{color:#fff;}.theme-yellow .sidebar .menu .list li.active{background-color:transparent;}.theme-yellow .sidebar .menu .list li.active>:first-child i,.theme-yellow .sidebar .menu .list li.active>:first-child span{color:#ffeb3b;}.theme-yellow .sidebar .menu .list .toggled{background-color:transparent;}.theme-yellow .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-yellow .sidebar .legal{background-color:#fff;}.theme-yellow .sidebar .legal .copyright a{color:#ffeb3b !important;}.theme-amber .navbar{background-color:#ffc107;}.theme-amber .navbar-brand{color:#fff;}.theme-amber .navbar-brand:hover{color:#fff;}.theme-amber .navbar-brand:active{color:#fff;}.theme-amber .navbar-brand:focus{color:#fff;}.theme-amber .nav>li>a{color:#fff;}.theme-amber .nav>li>a:hover{background-color:transparent;}.theme-amber .nav>li>a:focus{background-color:transparent;}.theme-amber .nav .open>a{background-color:transparent;}.theme-amber .nav .open>a:hover{background-color:transparent;}.theme-amber .nav .open>a:focus{background-color:transparent;}.theme-amber .bars{color:#fff;}.theme-amber .sidebar .menu .list li.active{background-color:transparent;}.theme-amber .sidebar .menu .list li.active>:first-child i,.theme-amber .sidebar .menu .list li.active>:first-child span{color:#ffc107;}.theme-amber .sidebar .menu .list .toggled{background-color:transparent;}.theme-amber .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-amber .sidebar .legal{background-color:#fff;}.theme-amber .sidebar .legal .copyright a{color:#ffc107 !important;}.theme-orange .navbar{background-color:#ff9800;}.theme-orange .navbar-brand{color:#fff;}.theme-orange .navbar-brand:hover{color:#fff;}.theme-orange .navbar-brand:active{color:#fff;}.theme-orange .navbar-brand:focus{color:#fff;}.theme-orange .nav>li>a{color:#fff;}.theme-orange .nav>li>a:hover{background-color:transparent;}.theme-orange .nav>li>a:focus{background-color:transparent;}.theme-orange .nav .open>a{background-color:transparent;}.theme-orange .nav .open>a:hover{background-color:transparent;}.theme-orange .nav .open>a:focus{background-color:transparent;}.theme-orange .bars{color:#fff;}.theme-orange .sidebar .menu .list li.active{background-color:transparent;}.theme-orange .sidebar .menu .list li.active>:first-child i,.theme-orange .sidebar .menu .list li.active>:first-child span{color:#ff9800;}.theme-orange .sidebar .menu .list .toggled{background-color:transparent;}.theme-orange .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-orange .sidebar .legal{background-color:#fff;}.theme-orange .sidebar .legal .copyright a{color:#ff9800 !important;}.theme-deep-orange .navbar{background-color:#ff5722;}.theme-deep-orange .navbar-brand{color:#fff;}.theme-deep-orange .navbar-brand:hover{color:#fff;}.theme-deep-orange .navbar-brand:active{color:#fff;}.theme-deep-orange .navbar-brand:focus{color:#fff;}.theme-deep-orange .nav>li>a{color:#fff;}.theme-deep-orange .nav>li>a:hover{background-color:transparent;}.theme-deep-orange .nav>li>a:focus{background-color:transparent;}.theme-deep-orange .nav .open>a{background-color:transparent;}.theme-deep-orange .nav .open>a:hover{background-color:transparent;}.theme-deep-orange .nav .open>a:focus{background-color:transparent;}.theme-deep-orange .bars{color:#fff;}.theme-deep-orange .sidebar .menu .list li.active{background-color:transparent;}.theme-deep-orange .sidebar .menu .list li.active>:first-child i,.theme-deep-orange .sidebar .menu .list li.active>:first-child span{color:#ff5722;}.theme-deep-orange .sidebar .menu .list .toggled{background-color:transparent;}.theme-deep-orange .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-deep-orange .sidebar .legal{background-color:#fff;}.theme-deep-orange .sidebar .legal .copyright a{color:#ff5722 !important;}.theme-brown .navbar{background-color:#795548;}.theme-brown .navbar-brand{color:#fff;}.theme-brown .navbar-brand:hover{color:#fff;}.theme-brown .navbar-brand:active{color:#fff;}.theme-brown .navbar-brand:focus{color:#fff;}.theme-brown .nav>li>a{color:#fff;}.theme-brown .nav>li>a:hover{background-color:transparent;}.theme-brown .nav>li>a:focus{background-color:transparent;}.theme-brown .nav .open>a{background-color:transparent;}.theme-brown .nav .open>a:hover{background-color:transparent;}.theme-brown .nav .open>a:focus{background-color:transparent;}.theme-brown .bars{color:#fff;}.theme-brown .sidebar .menu .list li.active{background-color:transparent;}.theme-brown .sidebar .menu .list li.active>:first-child i,.theme-brown .sidebar .menu .list li.active>:first-child span{color:#795548;}.theme-brown .sidebar .menu .list .toggled{background-color:transparent;}.theme-brown .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-brown .sidebar .legal{background-color:#fff;}.theme-brown .sidebar .legal .copyright a{color:#795548 !important;}.theme-grey .navbar{background-color:#9e9e9e;}.theme-grey .navbar-brand{color:#fff;}.theme-grey .navbar-brand:hover{color:#fff;}.theme-grey .navbar-brand:active{color:#fff;}.theme-grey .navbar-brand:focus{color:#fff;}.theme-grey .nav>li>a{color:#fff;}.theme-grey .nav>li>a:hover{background-color:transparent;}.theme-grey .nav>li>a:focus{background-color:transparent;}.theme-grey .nav .open>a{background-color:transparent;}.theme-grey .nav .open>a:hover{background-color:transparent;}.theme-grey .nav .open>a:focus{background-color:transparent;}.theme-grey .bars{color:#fff;}.theme-grey .sidebar .menu .list li.active{background-color:transparent;}.theme-grey .sidebar .menu .list li.active>:first-child i,.theme-grey .sidebar .menu .list li.active>:first-child span{color:#9e9e9e;}.theme-grey .sidebar .menu .list .toggled{background-color:transparent;}.theme-grey .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-grey .sidebar .legal{background-color:#fff;}.theme-grey .sidebar .legal .copyright a{color:#9e9e9e !important;}.theme-blue-grey .navbar{background-color:#607d8b;}.theme-blue-grey .navbar-brand{color:#fff;}.theme-blue-grey .navbar-brand:hover{color:#fff;}.theme-blue-grey .navbar-brand:active{color:#fff;}.theme-blue-grey .navbar-brand:focus{color:#fff;}.theme-blue-grey .nav>li>a{color:#fff;}.theme-blue-grey .nav>li>a:hover{background-color:transparent;}.theme-blue-grey .nav>li>a:focus{background-color:transparent;}.theme-blue-grey .nav .open>a{background-color:transparent;}.theme-blue-grey .nav .open>a:hover{background-color:transparent;}.theme-blue-grey .nav .open>a:focus{background-color:transparent;}.theme-blue-grey .bars{color:#fff;}.theme-blue-grey .sidebar .menu .list li.active{background-color:transparent;}.theme-blue-grey .sidebar .menu .list li.active>:first-child i,.theme-blue-grey .sidebar .menu .list li.active>:first-child span{color:#607d8b;}.theme-blue-grey .sidebar .menu .list .toggled{background-color:transparent;}.theme-blue-grey .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-blue-grey .sidebar .legal{background-color:#fff;}.theme-blue-grey .sidebar .legal .copyright a{color:#607d8b !important;}.theme-black .navbar{background-color:#000;}.theme-black .navbar-brand{color:#fff;}.theme-black .navbar-brand:hover{color:#fff;}.theme-black .navbar-brand:active{color:#fff;}.theme-black .navbar-brand:focus{color:#fff;}.theme-black .nav>li>a{color:#fff;}.theme-black .nav>li>a:hover{background-color:transparent;}.theme-black .nav>li>a:focus{background-color:transparent;}.theme-black .nav .open>a{background-color:transparent;}.theme-black .nav .open>a:hover{background-color:transparent;}.theme-black .nav .open>a:focus{background-color:transparent;}.theme-black .bars{color:#fff;}.theme-black .sidebar .menu .list li.active{background-color:transparent;}.theme-black .sidebar .menu .list li.active>:first-child i,.theme-black .sidebar .menu .list li.active>:first-child span{color:#000;}.theme-black .sidebar .menu .list .toggled{background-color:transparent;}.theme-black .sidebar .menu .list .ml-menu{background-color:transparent;}.theme-black .sidebar .legal{background-color:#fff;}.theme-black .sidebar .legal .copyright a{color:#000 !important;} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/error.html b/Plan/common/src/main/resources/assets/plan/web/error.html deleted file mode 100644 index 107462cee..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/error.html +++ /dev/null @@ -1,270 +0,0 @@ - - - - - - - - ${titleText} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Loading Data...

    -
    -
    - - -
    - - - - - - - -
    - - - - - - -
    - -
    - -
    -
    -
    -
    -
    -
    -

    ${title}

    -
    -
    -
    -
    - ${paragraph} -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - diff --git a/Plan/common/src/main/resources/assets/plan/web/favicon.ico b/Plan/common/src/main/resources/assets/plan/web/favicon.ico deleted file mode 100644 index cea02dd443c390502f9d0be4f00f9aaab419d62d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmbu8!41MN3`Kth15`qSE4^{x%uJk_fDKrQWim(br?T`F?6xAV9H-xTzgDFHgFWL2 zThF-ffg^y6rAemDx)s2BS)5+C8s*_}tw~Pq6>-!OPW7pS{rW_FwJ4?hWHe99XRQ0R z9?FwtsHXeKL;Ew`&u24i{l4-#Q_Jh@+%EjExX36cf`7;=c2uzTdEO9ZHf7} Y$2-)+uHC`R+qw4+cn 150) $el.slimscroll({ scrollTo: activeItemOffsetTop + 'px' }); - } - } - }, - checkStatuForResize: function (firstTime) { - var $body = $('body'); - var $openCloseBar = $('.navbar .navbar-header .bars'); - var width = $body.width(); - - if (firstTime) { - $body.find('.content, .sidebar').addClass('no-animate').delay(1000).queue(function () { - $(this).removeClass('no-animate').dequeue(); - }); - } - - if (width < $.AdminBSB.options.leftSideBar.breakpointWidth) { - $body.addClass('ls-closed'); - $openCloseBar.fadeIn(); - } - else { - $body.removeClass('ls-closed'); - $openCloseBar.fadeOut(); - } - }, - isOpen: function () { - return $('body').hasClass('overlay-open'); - } -}; -//========================================================================================================================== - -/* Right Sidebar - Function ================================================================================================ -* You can manage the right sidebar menu options -* -*/ -$.AdminBSB.rightSideBar = { - activate: function () { - var _this = this; - var $sidebar = $('#rightsidebar'); - var $overlay = $('.overlay'); - - //Close sidebar - $(window).click(function (e) { - var $target = $(e.target); - if (e.target.nodeName.toLowerCase() === 'i') { $target = $(e.target).parent(); } - - if (!$target.hasClass('js-right-sidebar') && _this.isOpen() && $target.parents('#rightsidebar').length === 0) { - if (!$target.hasClass('bars')) $overlay.fadeOut(); - $sidebar.removeClass('open'); - } - }); - - $('.js-right-sidebar').on('click', function () { - $sidebar.toggleClass('open'); - if (_this.isOpen()) { $overlay.fadeIn(); } else { $overlay.fadeOut(); } - }); - }, - isOpen: function () { - return $('.right-sidebar').hasClass('open'); - } -}; -//========================================================================================================================== - -/* Searchbar - Function ================================================================================================ -* You can manage the search bar -* -*/ -var $searchBar = $('.search-bar'); -$.AdminBSB.search = { - activate: function () { - var _this = this; - - //Search button click event - $('.js-search').on('click', function () { - _this.showSearchBar(); - }); - - //Close search click event - $searchBar.find('.close-search').on('click', function () { - _this.hideSearchBar(); - }); - - //ESC key on pressed - $searchBar.find('input[type="text"]').on('keyup', function (e) { - if (e.keyCode == 27) { - _this.hideSearchBar(); - } - }); - }, - showSearchBar: function () { - $searchBar.addClass('open'); - $searchBar.find('input[type="text"]').focus(); - }, - hideSearchBar: function () { - $searchBar.removeClass('open'); - $searchBar.find('input[type="text"]').val(''); - } -}; -//========================================================================================================================== - -/* Navbar - Function ======================================================================================================= -* You can manage the navbar -* -*/ -$.AdminBSB.navbar = { - activate: function () { - var $body = $('body'); - var $overlay = $('.overlay'); - - //Open left sidebar panel - $('.bars').on('click', function () { - $body.toggleClass('overlay-open'); - if ($body.hasClass('overlay-open')) { $overlay.fadeIn(); } else { $overlay.fadeOut(); } - }); - - //Close collapse bar on click event - $('.nav [data-close="true"]').on('click', function () { - var isVisible = $('.navbar-toggle').is(':visible'); - var $navbarCollapse = $('.navbar-collapse'); - - if (isVisible) { - $navbarCollapse.slideUp(function () { - $navbarCollapse.removeClass('in').removeAttr('style'); - }); - } - }); - } -}; -//========================================================================================================================== - -/* Input - Function ======================================================================================================== -* You can manage the inputs(also textareas) with name of class 'form-control' -* -*/ -$.AdminBSB.input = { - activate: function () { - //On focus event - $('.form-control').focus(function () { - $(this).parent().addClass('focused'); - }); - - //On focusout event - $('.form-control').focusout(function () { - var $this = $(this); - if ($this.parents('.form-group').hasClass('form-float')) { - if ($this.val() == '') { $this.parents('.form-line').removeClass('focused'); } - } - else { - $this.parents('.form-line').removeClass('focused'); - } - }); - - //On label click - $('body').on('click', '.form-float .form-line .form-label', function () { - $(this).parent().find('input').focus(); - }); - - //Not blank form - $('.form-control').each(function () { - if ($(this).val() !== '') { - $(this).parents('.form-line').addClass('focused'); - } - }); - } -}; -//========================================================================================================================== - -/* Form - Select - Function ================================================================================================ -* You can manage the 'select' of form elements -* -*/ -$.AdminBSB.select = { - activate: function () { - if ($.fn.selectpicker) { $('select:not(.ms)').selectpicker(); } - } -}; -//========================================================================================================================== - -/* DropdownMenu - Function ================================================================================================= -* You can manage the dropdown menu -* -*/ - -$.AdminBSB.dropdownMenu = { - activate: function () { - var _this = this; - - $('.dropdown, .dropup, .btn-group').on({ - "show.bs.dropdown": function () { - var dropdown = _this.dropdownEffect(this); - _this.dropdownEffectStart(dropdown, dropdown.effectIn); - }, - "shown.bs.dropdown": function () { - var dropdown = _this.dropdownEffect(this); - if (dropdown.effectIn && dropdown.effectOut) { - _this.dropdownEffectEnd(dropdown, function () { }); - } - }, - "hide.bs.dropdown": function (e) { - var dropdown = _this.dropdownEffect(this); - if (dropdown.effectOut) { - e.preventDefault(); - _this.dropdownEffectStart(dropdown, dropdown.effectOut); - _this.dropdownEffectEnd(dropdown, function () { - dropdown.dropdown.removeClass('open'); - }); - } - } - }); - - //Set Waves - Waves.attach('.dropdown-menu li a', ['waves-block']); - Waves.init(); - }, - dropdownEffect: function (target) { - var effectIn = $.AdminBSB.options.dropdownMenu.effectIn, effectOut = $.AdminBSB.options.dropdownMenu.effectOut; - var dropdown = $(target), dropdownMenu = $('.dropdown-menu', target); - - if (dropdown.length > 0) { - var udEffectIn = dropdown.data('effect-in'); - var udEffectOut = dropdown.data('effect-out'); - if (udEffectIn !== undefined) { effectIn = udEffectIn; } - if (udEffectOut !== undefined) { effectOut = udEffectOut; } - } - - return { - target: target, - dropdown: dropdown, - dropdownMenu: dropdownMenu, - effectIn: effectIn, - effectOut: effectOut - }; - }, - dropdownEffectStart: function (data, effectToStart) { - if (effectToStart) { - data.dropdown.addClass('dropdown-animating'); - data.dropdownMenu.addClass('animated dropdown-animated'); - data.dropdownMenu.addClass(effectToStart); - } - }, - dropdownEffectEnd: function (data, callback) { - var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend'; - data.dropdown.one(animationEnd, function () { - data.dropdown.removeClass('dropdown-animating'); - data.dropdownMenu.removeClass('animated dropdown-animated'); - data.dropdownMenu.removeClass(data.effectIn); - data.dropdownMenu.removeClass(data.effectOut); - - if (typeof callback == 'function') { - callback(); - } - }); - } -}; -//========================================================================================================================== - -/* Browser - Function ====================================================================================================== -* You can manage browser -* -*/ -var edge = 'Microsoft Edge'; -var ie10 = 'Internet Explorer 10'; -var ie11 = 'Internet Explorer 11'; -var opera = 'Opera'; -var firefox = 'Mozilla Firefox'; -var chrome = 'Google Chrome'; -var safari = 'Safari'; - -$.AdminBSB.browser = { - activate: function () { - var _this = this; - var className = _this.getClassName(); - - if (className !== '') $('html').addClass(_this.getClassName()); - }, - getBrowser: function () { - var userAgent = navigator.userAgent.toLowerCase(); - - if (/edge/i.test(userAgent)) { - return edge; - } else if (/rv:11/i.test(userAgent)) { - return ie11; - } else if (/msie 10/i.test(userAgent)) { - return ie10; - } else if (/opr/i.test(userAgent)) { - return opera; - } else if (/chrome/i.test(userAgent)) { - return chrome; - } else if (/firefox/i.test(userAgent)) { - return firefox; - } else if (!!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/)) { - return safari; - } - - return undefined; - }, - getClassName: function () { - var browser = this.getBrowser(); - - if (browser === edge) { - return 'edge'; - } else if (browser === ie11) { - return 'ie11'; - } else if (browser === ie10) { - return 'ie10'; - } else if (browser === opera) { - return 'opera'; - } else if (browser === chrome) { - return 'chrome'; - } else if (browser === firefox) { - return 'firefox'; - } else if (browser === safari) { - return 'safari'; - } else { - return ''; - } - } -}; -//========================================================================================================================== - -$(function () { - $.AdminBSB.browser.activate(); - $.AdminBSB.leftSideBar.activate(); - $.AdminBSB.rightSideBar.activate(); - $.AdminBSB.navbar.activate(); - $.AdminBSB.dropdownMenu.activate(); - $.AdminBSB.input.activate(); - $.AdminBSB.select.activate(); - $.AdminBSB.search.activate(); - - setTimeout(function () { $('.page-loader-wrapper').fadeOut(); }, 50); -}); - -$(function () { - //Popover (For Help texts) - $('[data-toggle="popover"]').popover(); -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/activityPie.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/activityPie.js deleted file mode 100644 index 42f1682fc..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/activityPie.js +++ /dev/null @@ -1,25 +0,0 @@ -function activityPie(id, activitySeries) { - Highcharts.chart(id, { - chart: { - plotBackgroundColor: null, - plotBorderWidth: null, - plotShadow: false, - type: 'pie' - }, - title: {text: ''}, - tooltip: { - pointFormat: '{series.name}: {point.y}' - }, - plotOptions: { - pie: { - allowPointSelect: true, - cursor: 'pointer', - dataLabels: { - enabled: false - }, - showInLegend: true - } - }, - series: [activitySeries] - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/diskGraph.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/diskGraph.js deleted file mode 100644 index 93a9d27a6..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/diskGraph.js +++ /dev/null @@ -1,41 +0,0 @@ -function diskChart(id, series) { - Highcharts.stockChart(id, { - rangeSelector: { - selected: 2, - buttons: [{ - type: 'hour', - count: 12, - text: '12h' - }, { - type: 'hour', - count: 24, - text: '24h' - }, { - type: 'day', - count: 7, - text: '7d' - }, { - type: 'month', - count: 1, - text: '30d' - }, { - type: 'all', - text: 'All' - }] - }, - yAxis: { - labels: { - formatter: function () { - return this.value + ' Mb'; - } - }, - softMax: 2, - softMin: 0 - }, - title: {text: ''}, - legend: { - enabled: true - }, - series: series - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/healthGauge.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/healthGauge.js deleted file mode 100644 index a060370bf..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/healthGauge.js +++ /dev/null @@ -1,101 +0,0 @@ -function healthGauge(id, healthData) { - var gaugeOptions = { - - chart: { - type: 'solidgauge' - }, - - title: null, - - pane: { - center: ['50%', '85%'], - size: '140%', - startAngle: -90, - endAngle: 90, - background: { - backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || '#EEE', - innerRadius: '60%', - outerRadius: '100%', - shape: 'arc' - } - }, - - tooltip: { - enabled: false - }, - - // the value axis - yAxis: { - stops: [ - [0.1, '#DF5353'], // red - [0.5, '#DDDF0D'], // yellow - [0.9, '#55BF3B'] // green - ], - lineWidth: 0, - minorTickInterval: null, - tickAmount: 2, - title: { - y: -70 - }, - labels: { - y: 16 - } - }, - - plotOptions: { - solidgauge: { - dataLabels: { - y: 5, - borderWidth: 0, - useHTML: true - } - } - } - }; - - var chartSpeed = Highcharts.chart(id, Highcharts.merge(gaugeOptions, { - yAxis: { - min: 0, - max: 100, - title: { - text: 'Server Health' - }, - visible: false - }, - - credits: { - enabled: false - }, - - series: [{ - name: 'health', - data: healthData, - dataLabels: { - formatter: function () { - return '
    ' + (this.y).toFixed(2) + '
    ' + - '' + getLabel(this.y) + '
    '; - } - } - }] - - })); -} - -function getLabel(index) { - if (index >= 80) { - return 'Very Healthy'; - } - if (index >= 60) { - return 'Healthy'; - } - if (index >= 50) { - return 'Good'; - } - if (index >= 30) { - return 'OK'; - } - if (index >= 0) { - return 'Poor'; - } -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/horizontalBarGraph.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/horizontalBarGraph.js deleted file mode 100644 index f4566f3e5..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/horizontalBarGraph.js +++ /dev/null @@ -1,40 +0,0 @@ -function horizontalBarChart(id, categories, series, text) { - Highcharts.chart(id, { - chart: { - type: 'bar' - }, - title: { - text: '' - }, - xAxis: { - categories: categories, - title: { - text: null - } - }, - yAxis: { - min: 0, - title: { - text: text, - align: 'high' - }, - labels: { - overflow: 'justify' - } - }, - legend: { - enabled: false - }, - plotOptions: { - bar: { - dataLabels: { - enabled: true - } - } - }, - credits: { - enabled: true - }, - series: series - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/lineGraph.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/lineGraph.js deleted file mode 100644 index 3dc505205..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/lineGraph.js +++ /dev/null @@ -1,36 +0,0 @@ -function lineChart(id, series) { - Highcharts.stockChart(id, { - rangeSelector: { - selected: 2, - buttons: [{ - type: 'hour', - count: 12, - text: '12h' - }, { - type: 'hour', - count: 24, - text: '24h' - }, { - type: 'day', - count: 7, - text: '7d' - }, { - type: 'month', - count: 1, - text: '30d' - }, { - type: 'all', - text: 'All' - }] - }, - yAxis: { - softMax: 2, - softMin: 0 - }, - title: {text: ''}, - legend: { - enabled: true - }, - series: series - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/onlineActivityCalendar.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/onlineActivityCalendar.js deleted file mode 100644 index 4d3c64074..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/onlineActivityCalendar.js +++ /dev/null @@ -1,28 +0,0 @@ -function onlineActivityCalendar(id, events, firstDay) { - $(id).fullCalendar({ - eventColor: '#2196F3', - firstDay: firstDay, - - eventRender: function (eventObj, $el) { - $el.popover({ - content: eventObj.title, - trigger: 'hover', - placement: 'top', - container: 'body' - }); - }, - - events: events, - - height: 'parent', - header: { - left: 'title', - center: '', - right: 'month prev,next' - } - }); - - setTimeout(function () { - $(id).fullCalendar('render') - }, 1000); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/performanceGraph.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/performanceGraph.js deleted file mode 100644 index 4914a317a..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/performanceGraph.js +++ /dev/null @@ -1,72 +0,0 @@ -function performanceChart(id, playersOnlineSeries, tpsSeries, cpuSeries, ramSeries, entitySeries, chunkSeries) { - Highcharts.stockChart(id, { - rangeSelector: { - selected: 2, - buttons: [{ - type: 'hour', - count: 12, - text: '12h' - }, { - type: 'hour', - count: 24, - text: '24h' - }, { - type: 'day', - count: 7, - text: '7d' - }, { - type: 'month', - count: 1, - text: '30d' - }, { - type: 'all', - text: 'All' - }] - }, - title: {text: ''}, - yAxis: [{ - labels: { - formatter: function () { - return this.value + ' P'; - } - } - }, { - opposite: true, - labels: { - formatter: function () { - return this.value + ' TPS'; - } - } - }, { - opposite: true, - labels: { - formatter: function () { - return this.value + '%'; - } - } - }, { - labels: { - formatter: function () { - return this.value + ' MB'; - } - } - }, { - opposite: true, - labels: { - formatter: function () { - return this.value + ' E'; - } - } - }, { - labels: { - formatter: function () { - return this.value + ' C'; - } - } - }], - legend: { - enabled: true - }, - series: [playersOnlineSeries, tpsSeries, cpuSeries, ramSeries, entitySeries, chunkSeries] - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/playerGraph.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/playerGraph.js deleted file mode 100644 index 13fff8f91..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/playerGraph.js +++ /dev/null @@ -1,38 +0,0 @@ -function playersChart(id, playersOnlineSeries, sel) { - Highcharts.stockChart(id, { - rangeSelector: { - selected: sel, - buttons: [{ - type: 'hour', - count: 12, - text: '12h' - },{ - type: 'hour', - count: 24, - text: '24h' - },{ - type: 'day', - count: 7, - text: '7d' - },{ - type: 'month', - count: 1, - text: '30d' - },{ - type: 'all', - text: 'All' - }] - }, - yAxis: { - softMax: 2, - softMin: 0 - }, - title: {text: ''}, - plotOptions: { - areaspline: { - fillOpacity: 0.4 - } - }, - series: [playersOnlineSeries] - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/playerGraphNoNav.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/playerGraphNoNav.js deleted file mode 100644 index 2b08045d5..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/playerGraphNoNav.js +++ /dev/null @@ -1,41 +0,0 @@ -function playersChartNoNav(id, playersOnlineSeries) { - Highcharts.stockChart(id, { - rangeSelector: { - selected: 3, - buttons: [{ - type: 'hour', - count: 12, - text: '12h' - }, { - type: 'hour', - count: 24, - text: '24h' - }, { - type: 'day', - count: 7, - text: '7d' - }, { - type: 'month', - count: 1, - text: '30d' - }, { - type: 'all', - text: 'All' - }] - }, - navigator: { - enabled: false - }, - yAxis: { - softMax: 2, - softMin: 0 - }, - title: {text: ''}, - plotOptions: { - areaspline: { - fillOpacity: 0.4 - } - }, - series: [playersOnlineSeries] - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/punchCard.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/punchCard.js deleted file mode 100644 index f7c3280f9..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/punchCard.js +++ /dev/null @@ -1,30 +0,0 @@ -function punchCard(id, punchcardSeries) { - Highcharts.chart(id, { - chart: { - defaultSeriesType: 'scatter' - }, - title: {text: ''}, - xAxis: { - type: 'datetime', - dateTimeLabelFormats: { - hour: '%I %P', - day: '%H %P' - }, - tickInterval: 3600000 - }, - time: { - timezoneOffset: 0 - }, - yAxis: { - title: { - text: "Day of the Week" - }, - reversed: true, - categories: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] - }, - tooltip: { - pointFormat: 'Activity: {point.z}' - }, - series: [punchcardSeries] - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/resourceGraph.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/resourceGraph.js deleted file mode 100644 index 723bb00f7..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/resourceGraph.js +++ /dev/null @@ -1,60 +0,0 @@ -function resourceChart(id, cpuSeries, ramSeries, playersOnlineSeries) { - Highcharts.stockChart(id, { - rangeSelector: { - selected: 1, - buttons: [{ - type: 'hour', - count: 12, - text: '12h' - }, { - type: 'hour', - count: 24, - text: '24h' - }, { - type: 'day', - count: 7, - text: '7d' - }, { - type: 'month', - count: 1, - text: '30d' - }, { - type: 'all', - text: 'All' - }] - }, - tooltip: { - split: true - }, - title: {text: ''}, - plotOptions: { - areaspline: { - fillOpacity: 0.4 - } - }, - yAxis: [{ - labels: { - formatter: function () { - return this.value + ' Players'; - } - } - }, { - opposite: true, - labels: { - formatter: function () { - return this.value + '%'; - } - } - }, { - labels: { - formatter: function () { - return this.value + ' Mb'; - } - } - }], - legend: { - enabled: true - }, - series: [cpuSeries, ramSeries, playersOnlineSeries] - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/serverPie.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/serverPie.js deleted file mode 100644 index f438a0c5c..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/serverPie.js +++ /dev/null @@ -1,53 +0,0 @@ -function serverPie(id, serverSeries) { - Highcharts.chart(id, { - chart: { - plotBackgroundColor: null, - plotBorderWidth: null, - plotShadow: false, - type: 'pie' - }, - title: {text: ''}, - plotOptions: { - pie: { - allowPointSelect: true, - cursor: 'pointer', - dataLabels: { - enabled: false - }, - showInLegend: true - } - }, - tooltip: { - formatter: function() { - return ''+this.point.name+': ' + formatTimeAmount(this.y) + ' ('+this.percentage.toFixed(2)+'%)'; - } - }, - series: [serverSeries] - }); -} - -function formatTimeAmount(ms) { - var out = ""; - - var seconds = Math.floor(ms / 1000); - - var dd = Math.floor(seconds / 86400); - seconds -= (dd * 86400); - var dh = Math.floor(seconds / 3600); - seconds -= (dh * 3600); - var dm = Math.floor(seconds / 60); - seconds -= (dm * 60); - seconds = Math.floor(seconds); - if (dd !== 0) { - out += dd.toString() + "d "; - } - if (dh !== 0) { - out += dh.toString() + "h "; - } - if (dm !== 0) { - out += dm.toString() + "m "; - } - out += seconds.toString() + "s "; - - return out; -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/sessionCalendar.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/sessionCalendar.js deleted file mode 100644 index d12c02d97..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/sessionCalendar.js +++ /dev/null @@ -1,30 +0,0 @@ -function sessionCalendar(id, events, firstDay) { - $(id).fullCalendar({ - eventColor: '#009688', - eventLimit: 4, - firstDay: firstDay, - - eventRender: function (eventObj, $el) { - $el.popover({ - content: eventObj.title, - trigger: 'hover', - placement: 'top', - container: 'body' - }); - }, - - events: events, - - navLinks: true, - height: 'parent', - header: { - left: 'title', - center: '', - right: 'month agendaWeek agendaDay today prev,next' - } - }); - - setTimeout(function () { - $(id).fullCalendar('render') - }, 1000); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/stackGraph.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/stackGraph.js deleted file mode 100644 index 23efde59d..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/stackGraph.js +++ /dev/null @@ -1,40 +0,0 @@ -function stackChart(id, categories, series, label) { - Highcharts.chart(id, { - chart: { - type: 'area' - }, - title: { - text: '' - }, - xAxis: { - categories: categories, - tickmarkPlacement: 'on', - title: { - enabled: false - } - }, - yAxis: { - title: { - text: label - }, - labels: { - formatter: function () { - return this.value; - } - }, - softMax: 2, - softMin: 0 - }, - tooltip: { - split: true, - valueSuffix: ' ' + label - }, - plotOptions: { - area: { - stacking: 'normal', - lineWidth: 1 - } - }, - series: series - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/tpsGraph.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/tpsGraph.js deleted file mode 100644 index 5985a1566..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/tpsGraph.js +++ /dev/null @@ -1,54 +0,0 @@ -function tpsChart(id, tpsSeries, playersOnlineSeries) { - Highcharts.stockChart(id, { - rangeSelector: { - selected: 1, - buttons: [{ - type: 'hour', - count: 12, - text: '12h' - }, { - type: 'hour', - count: 24, - text: '24h' - }, { - type: 'day', - count: 7, - text: '7d' - }, { - type: 'month', - count: 1, - text: '30d' - }, { - type: 'all', - text: 'All' - }] - }, - tooltip: { - split: true - }, - title: {text: ''}, - plotOptions: { - areaspline: { - fillOpacity: 0.4 - } - }, - yAxis: [{ - labels: { - formatter: function () { - return this.value + ' Players'; - } - } - }, { - opposite: true, - labels: { - formatter: function () { - return this.value + ' TPS'; - } - } - }], - legend: { - enabled: true - }, - series: [tpsSeries, playersOnlineSeries] - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/worldGraph.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/worldGraph.js deleted file mode 100644 index 32b85cc66..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/worldGraph.js +++ /dev/null @@ -1,60 +0,0 @@ -function worldChart(id, entitySeries, chunkSeries, playersOnlineSeries) { - Highcharts.stockChart(id, { - rangeSelector: { - selected: 1, - buttons: [{ - type: 'hour', - count: 12, - text: '12h' - }, { - type: 'hour', - count: 24, - text: '24h' - }, { - type: 'day', - count: 7, - text: '7d' - }, { - type: 'month', - count: 1, - text: '30d' - }, { - type: 'all', - text: 'All' - }] - }, - tooltip: { - split: true - }, - title: {text: ''}, - plotOptions: { - areaspline: { - fillOpacity: 0.4 - } - }, - yAxis: [{ - labels: { - formatter: function () { - return this.value + ' Players'; - } - } - }, { - opposite: true, - labels: { - formatter: function () { - return this.value + ' Entities'; - } - } - }, { - labels: { - formatter: function () { - return this.value + ' Chunks'; - } - } - }], - legend: { - enabled: true - }, - series: [entitySeries, chunkSeries, playersOnlineSeries] - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/worldMap.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/worldMap.js deleted file mode 100644 index db66ebd4e..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/worldMap.js +++ /dev/null @@ -1,21 +0,0 @@ -function worldMap(id, colorMin, colorMax, mapSeries) { - Highcharts.mapChart(id, { - chart: { - animation: true - }, - title: {text: ''}, - - mapNavigation: { - enabled: true, - enableDoubleClickZoomTo: true - }, - - colorAxis: { - min: 1, - type: 'logarithmic', - minColor: colorMin, - maxColor: colorMax - }, - series: [mapSeries] - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/charts/worldPie.js b/Plan/common/src/main/resources/assets/plan/web/js/charts/worldPie.js deleted file mode 100644 index ccca32c8f..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/charts/worldPie.js +++ /dev/null @@ -1,70 +0,0 @@ -function worldPie(id, worldSeries, gmSeries) { - var defaultTitle = ''; - var defaultSubtitle = 'Click the slices to view used GameMode'; - - var chart = Highcharts.chart(id, { - chart: { - plotBackgroundColor: null, - plotBorderWidth: null, - plotShadow: false, - type: 'pie', - events: { - drilldown: function (e) { - chart.setTitle({text: '' + e.point.name}, {text: ''}); - }, - drillup: function (e) { - chart.setTitle({text: defaultTitle}, {text: defaultSubtitle}); - } - } - }, - title: {text: defaultTitle}, - subtitle: { - text: defaultSubtitle - }, - plotOptions: { - pie: { - allowPointSelect: true, - cursor: 'pointer', - dataLabels: { - enabled: false - }, - showInLegend: true - } - }, - tooltip: { - formatter: function() { - return ''+this.point.name+': ' + formatTimeAmount(this.y) + ' ('+this.percentage.toFixed(2)+'%)'; - } - }, - series: [worldSeries], - drilldown: { - series: gmSeries - } - }); -} - -function formatTimeAmount(ms) { - var out = ""; - - var seconds = Math.floor(ms / 1000); - - var dd = Math.floor(seconds / 86400); - seconds -= (dd * 86400); - var dh = Math.floor(seconds / 3600); - seconds -= (dh * 3600); - var dm = Math.floor(seconds / 60); - seconds -= (dm * 60); - seconds = Math.floor(seconds); - if (dd !== 0) { - out += dd.toString() + "d "; - } - if (dh !== 0) { - out += dh.toString() + "h "; - } - if (dm !== 0) { - out += dm.toString() + "m "; - } - out += seconds.toString() + "s "; - - return out; -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/demo.js b/Plan/common/src/main/resources/assets/plan/web/js/demo.js deleted file mode 100644 index fbe4f062b..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/demo.js +++ /dev/null @@ -1,68 +0,0 @@ -$(function () { - skinChanger(); - - setSkin(); - - setSkinListHeightAndScroll(true); - $(window).resize(function () { - setSkinListHeightAndScroll(false); - }); -}); - -//Skin changer -function skinChanger() { - $('.right-sidebar .demo-choose-skin li').on('click', function () { - var $body = $('body'); - var $this = $(this); - - var existTheme = $('.right-sidebar .demo-choose-skin li.active').data('theme'); - $('.right-sidebar .demo-choose-skin li').removeClass('active'); - $body.removeClass('theme-' + existTheme); - $this.addClass('active'); - - var theme = $this.data('theme'); - $body.addClass('theme-' + theme); - localStorage.setItem("plan_skin", theme.toString()); - }); -} - -function setSkin() { - var theme = localStorage.getItem("plan_skin"); - if (theme === null) { - theme = '${defaultTheme}' - } - var body = document.getElementsByTagName('body')[0]; - - var classes = body.className.split(' '); - var themeClass; - for (i = 0; i < classes.length; i++) { - if (classes[i].startsWith('theme')) { - themeClass = classes[i]; - break; - } - } - - body.classList.remove(themeClass); - body.classList.add('theme-' + theme); - localStorage.setItem("plan_skin", theme); -} - -//Skin tab content set height and show scroll -function setSkinListHeightAndScroll(isFirstTime) { - var height = $(window).height() - ($('.navbar').innerHeight() + $('.right-sidebar .nav-tabs').outerHeight()); - var $el = $('.demo-choose-skin'); - - if (!isFirstTime) { - $el.slimScroll({destroy: true}).height('auto'); - $el.parent().find('.slimScrollBar, .slimScrollRail').remove(); - } - - $el.slimscroll({ - height: height + 'px', - color: 'rgba(0,0,0,0.5)', - size: '6px', - alwaysVisible: false, - borderRadius: '0', - railBorderRadius: '0' - }); -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/helpers.js b/Plan/common/src/main/resources/assets/plan/web/js/helpers.js deleted file mode 100644 index 37e3d3230..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/helpers.js +++ /dev/null @@ -1,13 +0,0 @@ -function hexToRgb(hexCode) { - var patt = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/; - var matches = patt.exec(hexCode); - var rgb = "rgb(" + parseInt(matches[1], 16) + "," + parseInt(matches[2], 16) + "," + parseInt(matches[3], 16) + ")"; - return rgb; -} - -function hexToRgba(hexCode, opacity) { - var patt = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/; - var matches = patt.exec(hexCode); - var rgb = "rgba(" + parseInt(matches[1], 16) + "," + parseInt(matches[2], 16) + "," + parseInt(matches[3], 16) + "," + opacity + ")"; - return rgb; -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/js/script.js b/Plan/common/src/main/resources/assets/plan/web/js/script.js deleted file mode 100644 index 5f282702b..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/js/script.js +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/network.html b/Plan/common/src/main/resources/assets/plan/web/network.html deleted file mode 100644 index b505ffa37..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/network.html +++ /dev/null @@ -1,656 +0,0 @@ - - - - - - - - Plan | Network - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Please wait...

    -
    -
    - - -
    - - - - - - - -
    - - - - - - -
    - -
    -
    -
    -
    -
    -
    -
    -
    -

    Network Online Activity

    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    NETWORK INFORMATION
    -
      -
    • - Total Players - ${playersTotal} -
    • -
    • - Players Online - ${playersOnline} -
    • -
    • -
    • Last Peak: ${lastPeakTime}${playersLastPeak} Players
    • -
    • All Time Peak: ${bestPeakTime}${playersBestPeak} Players
    • -
    -
    -
    -
    -
    -
    PLAYERS
    -
      -
    • - Unique | 24h - ${playersDay} -
    • -
    • - New | 24h - ${playersNewDay} -
    • -
    • -
    • - Unique | 7d - ${playersWeek} -
    • -
    • - New | 7d - ${playersNewWeek} -
    • -
    • -
    • - Unique | 30d - ${playersMonth} -
    • -
    • - New | 30d - ${playersNewMonth} -
    • -
    -
    -
    -
    - -
    - -
    - ${tabContentServers} -
    - -
    -
    - -
    -
    -
    -
    -
    -

    Health Estimate

    -
    - -
    -
    -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -

    Last 30 Days

    -
    - -
    -
    -
    - ${healthNotes} -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -

    Playerbase Development

    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Current Playerbase

    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    -
    -

    Geolocations

    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - - ${tabsPlugins} -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Plan/common/src/main/resources/assets/plan/web/player.html b/Plan/common/src/main/resources/assets/plan/web/player.html deleted file mode 100644 index 49cb5369b..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/player.html +++ /dev/null @@ -1,932 +0,0 @@ - - - - - - - - Plan | ${playerName} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Please wait...

    -
    -
    - - -
    - - - - - - - -
    - - - - - - -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    ${playerName}

    -
    - -
    -
    -
    -
    -
    -
    - ${playerStatus} -

    Times Kicked: ${kickCount} -

    -
    -
    - -
    -
    -

    Player Kills: - ${playerKillCount} -

    -

    Mob Kills: - ${mobKillCount}

    -

    Deaths: ${deathCount}

    -
    -
    -
    -
    -
    -
    -

    Sessions ${sessionCount}

    -

    Total Playtime ${playtimeTotal}

    -

    Total Active ${activeTotal}

    -

    Total AFK ${afkTotal}

    -

    Longest Session ${sessionLengthLongest} -

    -

    Session Median - ${sessionLengthMedian} -

    -
    -
    -

    Activity Index ${activityIndexNumber}

    -

     ${activityIndex} -

    -

      -

    -

    - Favorite Server - ${favoriteServer} -

    -

      -

    -

    - Average Ping - ${avgPing} -

    -

    - Best Ping - ${minPing} -

    -

    - Worst Ping - ${maxPing} -

    -
    -
    -
    -
    -
    -
    - - -
    -
    -
    - person_add -
    -
    -
    REGISTERED
    -
    ${registered}
    -
    -
    -
    -
    -
    -
    - event -
    -
    -
    LAST SEEN
    -
    ${lastSeen}
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Punchcard

    -
    - -
    -
    -
    -
    -
    -
    -
    -
    - -
    - - -
    -
    -
    -
    -
    -

    Seen Nicknames

    -
    -
    -
    -
    - - - - - - - - - - ${tableBodyNicknames} - -
    Nickname Server Last Seen
    -
    -
    -
    - - -
    -
    -
    -
    -
    -

    Connection Information

    -
    - -
    -
    -
    - - - - - - - - - - ${tableBodyIPs} - -
    IP-address Geolocation Last Connected
    -
    -
    -
    - - -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -

    Session Calendar

    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Most Recent Sessions

    -
    - -
    -
    - ${accordionSessions} -
    -
    - -
    - -
    -
    -
    -
    -

    World Playtime

    -
    - -
    -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -

    Server Preference

    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    - - -
    -
    -
    -
    LAST 30 DAYS
    -
      -
    • Sessions ${sessionCountMonth}
    • -
    • Total Playtime ${playtimeMonth}
    • -
    • AFK ${afkMonth}
    • -
    • Longest Session ${sessionLongestMonth} -
    • -
    • Session Median ${sessionMedianMonth} -
    • -
    -
    -
    -
    - - -
    -
    -
    -
    LAST 7 DAYS
    -
      -
    • Sessions ${sessionCountWeek}
    • -
    • Total Playtime ${playtimeWeek}
    • -
    • AFK ${afkWeek}
    • -
    • Longest Session ${sessionLongestWeek} -
    • -
    • Session Median ${sessionMedianWeek} -
    • -
    -
    -
    -
    - - -
    -
    -
    -
    LAST 24 HOURS
    -
      -
    • Sessions ${sessionCountDay}
    • -
    • Total Playtime ${playtimeDay}
    • -
    • AFK ${afkDay}
    • -
    • Longest Session ${sessionLongestDay} -
    • -
    • Session Median ${sessionMedianDay} -
    • -
    -
    -
    -
    - - -
    -
    - -
    -
    -
    -
    -
    -

    Servers

    -
    - -
    -
    - ${accordionServers} -
    -
    - -
    -
    - -
    -
    - - -
    -
    -
    -
    OVERVIEW
    -
      -
    • KDR ${KDR}
    • -
    • Player Kills ${playerKillCount}
    • -
    • Player caused Deaths ${playerDeathCount}
    • -
    • -
    • Mob KDR ${mobKDR}
    • -
    • Mob Kills ${mobKillCount}
    • -
    • Mob caused Deaths ${mobDeathCount}
    • -
    • -
    • Deaths ${deathCount}
    • -
    -
    -
    -
    - - -
    -
    -
    -
    LAST 30 DAYS
    -
      -
    • KDR ${KDRMonth}
    • -
    • Player Kills ${playerKillCountMonth}
    • -
    • Player caused Deaths ${playerDeathCountMonth}
    • -
    • -
    • Mob KDR ${mobKDRMonth}
    • -
    • Mob Kills ${mobKillCountMonth}
    • -
    • Mob caused Deaths ${mobDeathCountMonth}
    • -
    • -
    • Deaths ${deathCountMonth}
    • -
    -
    -
    -
    - - -
    -
    -
    -
    LAST 7 DAYS
    -
      -
    • KDR ${KDRWeek}
    • -
    • Player Kills ${playerKillCountWeek}
    • -
    • Player caused Deaths ${playerDeathCountWeek}
    • -
    • -
    • Mob KDR ${mobKDRWeek}
    • -
    • Mob Kills ${mobKillCountWeek}
    • -
    • Mob caused Deaths ${mobDeathCountWeek}
    • -
    • -
    • Deaths ${deathCountWeek}
    • -
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    -
    -
    -

    Player Kills

    -
    -
    -
    -
    - ${tablePlayerKills} -
    -
    -
    - - -
    -
    -
    -
    -
    -

    Player caused Deaths

    -
    - -
    -
    -
    - ${tablePlayerDeaths} -
    -
    -
    - - -
    -
    - - ${pluginsTabs} - -
    -
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Plan/common/src/main/resources/assets/plan/web/players.html b/Plan/common/src/main/resources/assets/plan/web/players.html deleted file mode 100644 index a6d631e45..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/players.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - - - - Plan | Players - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Please wait...

    -
    -
    - - -
    - - - - - - - -
    - - - - - - -
    - -
    -
    -
    -
    - -
    -
    -
    -
    -
    -

    Player List

    -
    - -
    -
    -
    - ${playersTable} -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/animate-css/animate.css b/Plan/common/src/main/resources/assets/plan/web/plugins/animate-css/animate.css deleted file mode 100644 index 188e78f66..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/animate-css/animate.css +++ /dev/null @@ -1,3340 +0,0 @@ -@charset "UTF-8"; - -/*! - * animate.css -http://daneden.me/animate - * Version - 3.5.0 - * Licensed under the MIT license - http://opensource.org/licenses/MIT - * - * Copyright (c) 2016 Daniel Eden - */ - -.animated { - -webkit-animation-duration: 1s; - animation-duration: 1s; - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} - -.animated.infinite { - -webkit-animation-iteration-count: infinite; - animation-iteration-count: infinite; -} - -.animated.hinge { - -webkit-animation-duration: 2s; - animation-duration: 2s; -} - -.animated.flipOutX, -.animated.flipOutY, -.animated.bounceIn, -.animated.bounceOut { - -webkit-animation-duration: .75s; - animation-duration: .75s; -} - -@-webkit-keyframes bounce { - from, 20%, 53%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - -webkit-transform: translate3d(0,0,0); - transform: translate3d(0,0,0); - } - - 40%, 43% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -30px, 0); - transform: translate3d(0, -30px, 0); - } - - 70% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -15px, 0); - transform: translate3d(0, -15px, 0); - } - - 90% { - -webkit-transform: translate3d(0,-4px,0); - transform: translate3d(0,-4px,0); - } -} - -@keyframes bounce { - from, 20%, 53%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - -webkit-transform: translate3d(0,0,0); - transform: translate3d(0,0,0); - } - - 40%, 43% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -30px, 0); - transform: translate3d(0, -30px, 0); - } - - 70% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -15px, 0); - transform: translate3d(0, -15px, 0); - } - - 90% { - -webkit-transform: translate3d(0,-4px,0); - transform: translate3d(0,-4px,0); - } -} - -.bounce { - -webkit-animation-name: bounce; - animation-name: bounce; - -webkit-transform-origin: center bottom; - transform-origin: center bottom; -} - -@-webkit-keyframes flash { - from, 50%, to { - opacity: 1; - } - - 25%, 75% { - opacity: 0; - } -} - -@keyframes flash { - from, 50%, to { - opacity: 1; - } - - 25%, 75% { - opacity: 0; - } -} - -.flash { - -webkit-animation-name: flash; - animation-name: flash; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes pulse { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 50% { - -webkit-transform: scale3d(1.05, 1.05, 1.05); - transform: scale3d(1.05, 1.05, 1.05); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes pulse { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 50% { - -webkit-transform: scale3d(1.05, 1.05, 1.05); - transform: scale3d(1.05, 1.05, 1.05); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.pulse { - -webkit-animation-name: pulse; - animation-name: pulse; -} - -@-webkit-keyframes rubberBand { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 30% { - -webkit-transform: scale3d(1.25, 0.75, 1); - transform: scale3d(1.25, 0.75, 1); - } - - 40% { - -webkit-transform: scale3d(0.75, 1.25, 1); - transform: scale3d(0.75, 1.25, 1); - } - - 50% { - -webkit-transform: scale3d(1.15, 0.85, 1); - transform: scale3d(1.15, 0.85, 1); - } - - 65% { - -webkit-transform: scale3d(.95, 1.05, 1); - transform: scale3d(.95, 1.05, 1); - } - - 75% { - -webkit-transform: scale3d(1.05, .95, 1); - transform: scale3d(1.05, .95, 1); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes rubberBand { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 30% { - -webkit-transform: scale3d(1.25, 0.75, 1); - transform: scale3d(1.25, 0.75, 1); - } - - 40% { - -webkit-transform: scale3d(0.75, 1.25, 1); - transform: scale3d(0.75, 1.25, 1); - } - - 50% { - -webkit-transform: scale3d(1.15, 0.85, 1); - transform: scale3d(1.15, 0.85, 1); - } - - 65% { - -webkit-transform: scale3d(.95, 1.05, 1); - transform: scale3d(.95, 1.05, 1); - } - - 75% { - -webkit-transform: scale3d(1.05, .95, 1); - transform: scale3d(1.05, .95, 1); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.rubberBand { - -webkit-animation-name: rubberBand; - animation-name: rubberBand; -} - -@-webkit-keyframes shake { - from, to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - 10%, 30%, 50%, 70%, 90% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 20%, 40%, 60%, 80% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } -} - -@keyframes shake { - from, to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - 10%, 30%, 50%, 70%, 90% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 20%, 40%, 60%, 80% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } -} - -.shake { - -webkit-animation-name: shake; - animation-name: shake; -} - -@-webkit-keyframes headShake { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 6.5% { - -webkit-transform: translateX(-6px) rotateY(-9deg); - transform: translateX(-6px) rotateY(-9deg); - } - - 18.5% { - -webkit-transform: translateX(5px) rotateY(7deg); - transform: translateX(5px) rotateY(7deg); - } - - 31.5% { - -webkit-transform: translateX(-3px) rotateY(-5deg); - transform: translateX(-3px) rotateY(-5deg); - } - - 43.5% { - -webkit-transform: translateX(2px) rotateY(3deg); - transform: translateX(2px) rotateY(3deg); - } - - 50% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes headShake { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 6.5% { - -webkit-transform: translateX(-6px) rotateY(-9deg); - transform: translateX(-6px) rotateY(-9deg); - } - - 18.5% { - -webkit-transform: translateX(5px) rotateY(7deg); - transform: translateX(5px) rotateY(7deg); - } - - 31.5% { - -webkit-transform: translateX(-3px) rotateY(-5deg); - transform: translateX(-3px) rotateY(-5deg); - } - - 43.5% { - -webkit-transform: translateX(2px) rotateY(3deg); - transform: translateX(2px) rotateY(3deg); - } - - 50% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -.headShake { - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - -webkit-animation-name: headShake; - animation-name: headShake; -} - -@-webkit-keyframes swing { - 20% { - -webkit-transform: rotate3d(0, 0, 1, 15deg); - transform: rotate3d(0, 0, 1, 15deg); - } - - 40% { - -webkit-transform: rotate3d(0, 0, 1, -10deg); - transform: rotate3d(0, 0, 1, -10deg); - } - - 60% { - -webkit-transform: rotate3d(0, 0, 1, 5deg); - transform: rotate3d(0, 0, 1, 5deg); - } - - 80% { - -webkit-transform: rotate3d(0, 0, 1, -5deg); - transform: rotate3d(0, 0, 1, -5deg); - } - - to { - -webkit-transform: rotate3d(0, 0, 1, 0deg); - transform: rotate3d(0, 0, 1, 0deg); - } -} - -@keyframes swing { - 20% { - -webkit-transform: rotate3d(0, 0, 1, 15deg); - transform: rotate3d(0, 0, 1, 15deg); - } - - 40% { - -webkit-transform: rotate3d(0, 0, 1, -10deg); - transform: rotate3d(0, 0, 1, -10deg); - } - - 60% { - -webkit-transform: rotate3d(0, 0, 1, 5deg); - transform: rotate3d(0, 0, 1, 5deg); - } - - 80% { - -webkit-transform: rotate3d(0, 0, 1, -5deg); - transform: rotate3d(0, 0, 1, -5deg); - } - - to { - -webkit-transform: rotate3d(0, 0, 1, 0deg); - transform: rotate3d(0, 0, 1, 0deg); - } -} - -.swing { - -webkit-transform-origin: top center; - transform-origin: top center; - -webkit-animation-name: swing; - animation-name: swing; -} - -@-webkit-keyframes tada { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 10%, 20% { - -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - } - - 30%, 50%, 70%, 90% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - } - - 40%, 60%, 80% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes tada { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 10%, 20% { - -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - } - - 30%, 50%, 70%, 90% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - } - - 40%, 60%, 80% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.tada { - -webkit-animation-name: tada; - animation-name: tada; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes wobble { - from { - -webkit-transform: none; - transform: none; - } - - 15% { - -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - } - - 30% { - -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - } - - 45% { - -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - } - - 60% { - -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - } - - 75% { - -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes wobble { - from { - -webkit-transform: none; - transform: none; - } - - 15% { - -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - } - - 30% { - -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - } - - 45% { - -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - } - - 60% { - -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - } - - 75% { - -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.wobble { - -webkit-animation-name: wobble; - animation-name: wobble; -} - -@-webkit-keyframes jello { - from, 11.1%, to { - -webkit-transform: none; - transform: none; - } - - 22.2% { - -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); - transform: skewX(-12.5deg) skewY(-12.5deg); - } - - 33.3% { - -webkit-transform: skewX(6.25deg) skewY(6.25deg); - transform: skewX(6.25deg) skewY(6.25deg); - } - - 44.4% { - -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); - transform: skewX(-3.125deg) skewY(-3.125deg); - } - - 55.5% { - -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); - transform: skewX(1.5625deg) skewY(1.5625deg); - } - - 66.6% { - -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); - transform: skewX(-0.78125deg) skewY(-0.78125deg); - } - - 77.7% { - -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); - transform: skewX(0.390625deg) skewY(0.390625deg); - } - - 88.8% { - -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - } -} - -@keyframes jello { - from, 11.1%, to { - -webkit-transform: none; - transform: none; - } - - 22.2% { - -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); - transform: skewX(-12.5deg) skewY(-12.5deg); - } - - 33.3% { - -webkit-transform: skewX(6.25deg) skewY(6.25deg); - transform: skewX(6.25deg) skewY(6.25deg); - } - - 44.4% { - -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); - transform: skewX(-3.125deg) skewY(-3.125deg); - } - - 55.5% { - -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); - transform: skewX(1.5625deg) skewY(1.5625deg); - } - - 66.6% { - -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); - transform: skewX(-0.78125deg) skewY(-0.78125deg); - } - - 77.7% { - -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); - transform: skewX(0.390625deg) skewY(0.390625deg); - } - - 88.8% { - -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - } -} - -.jello { - -webkit-animation-name: jello; - animation-name: jello; - -webkit-transform-origin: center; - transform-origin: center; -} - -@-webkit-keyframes bounceIn { - from, 20%, 40%, 60%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 20% { - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - 40% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(1.03, 1.03, 1.03); - transform: scale3d(1.03, 1.03, 1.03); - } - - 80% { - -webkit-transform: scale3d(.97, .97, .97); - transform: scale3d(.97, .97, .97); - } - - to { - opacity: 1; - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes bounceIn { - from, 20%, 40%, 60%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 20% { - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - 40% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(1.03, 1.03, 1.03); - transform: scale3d(1.03, 1.03, 1.03); - } - - 80% { - -webkit-transform: scale3d(.97, .97, .97); - transform: scale3d(.97, .97, .97); - } - - to { - opacity: 1; - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.bounceIn { - -webkit-animation-name: bounceIn; - animation-name: bounceIn; -} - -@-webkit-keyframes bounceInDown { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(0, -3000px, 0); - transform: translate3d(0, -3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, 25px, 0); - transform: translate3d(0, 25px, 0); - } - - 75% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, 5px, 0); - transform: translate3d(0, 5px, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes bounceInDown { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(0, -3000px, 0); - transform: translate3d(0, -3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, 25px, 0); - transform: translate3d(0, 25px, 0); - } - - 75% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, 5px, 0); - transform: translate3d(0, 5px, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.bounceInDown { - -webkit-animation-name: bounceInDown; - animation-name: bounceInDown; -} - -@-webkit-keyframes bounceInLeft { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(-3000px, 0, 0); - transform: translate3d(-3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(25px, 0, 0); - transform: translate3d(25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(5px, 0, 0); - transform: translate3d(5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes bounceInLeft { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(-3000px, 0, 0); - transform: translate3d(-3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(25px, 0, 0); - transform: translate3d(25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(5px, 0, 0); - transform: translate3d(5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.bounceInLeft { - -webkit-animation-name: bounceInLeft; - animation-name: bounceInLeft; -} - -@-webkit-keyframes bounceInRight { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(3000px, 0, 0); - transform: translate3d(3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(-25px, 0, 0); - transform: translate3d(-25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(-5px, 0, 0); - transform: translate3d(-5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes bounceInRight { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(3000px, 0, 0); - transform: translate3d(3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(-25px, 0, 0); - transform: translate3d(-25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(-5px, 0, 0); - transform: translate3d(-5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.bounceInRight { - -webkit-animation-name: bounceInRight; - animation-name: bounceInRight; -} - -@-webkit-keyframes bounceInUp { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(0, 3000px, 0); - transform: translate3d(0, 3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - 75% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, -5px, 0); - transform: translate3d(0, -5px, 0); - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes bounceInUp { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(0, 3000px, 0); - transform: translate3d(0, 3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - 75% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, -5px, 0); - transform: translate3d(0, -5px, 0); - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.bounceInUp { - -webkit-animation-name: bounceInUp; - animation-name: bounceInUp; -} - -@-webkit-keyframes bounceOut { - 20% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 50%, 55% { - opacity: 1; - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } -} - -@keyframes bounceOut { - 20% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 50%, 55% { - opacity: 1; - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } -} - -.bounceOut { - -webkit-animation-name: bounceOut; - animation-name: bounceOut; -} - -@-webkit-keyframes bounceOutDown { - 20% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -@keyframes bounceOutDown { - 20% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -.bounceOutDown { - -webkit-animation-name: bounceOutDown; - animation-name: bounceOutDown; -} - -@-webkit-keyframes bounceOutLeft { - 20% { - opacity: 1; - -webkit-transform: translate3d(20px, 0, 0); - transform: translate3d(20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -@keyframes bounceOutLeft { - 20% { - opacity: 1; - -webkit-transform: translate3d(20px, 0, 0); - transform: translate3d(20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -.bounceOutLeft { - -webkit-animation-name: bounceOutLeft; - animation-name: bounceOutLeft; -} - -@-webkit-keyframes bounceOutRight { - 20% { - opacity: 1; - -webkit-transform: translate3d(-20px, 0, 0); - transform: translate3d(-20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -@keyframes bounceOutRight { - 20% { - opacity: 1; - -webkit-transform: translate3d(-20px, 0, 0); - transform: translate3d(-20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -.bounceOutRight { - -webkit-animation-name: bounceOutRight; - animation-name: bounceOutRight; -} - -@-webkit-keyframes bounceOutUp { - 20% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, 20px, 0); - transform: translate3d(0, 20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -@keyframes bounceOutUp { - 20% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, 20px, 0); - transform: translate3d(0, 20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -.bounceOutUp { - -webkit-animation-name: bounceOutUp; - animation-name: bounceOutUp; -} - -@-webkit-keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -@keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -.fadeIn { - -webkit-animation-name: fadeIn; - animation-name: fadeIn; -} - -@-webkit-keyframes fadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInDown { - -webkit-animation-name: fadeInDown; - animation-name: fadeInDown; -} - -@-webkit-keyframes fadeInDownBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInDownBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInDownBig { - -webkit-animation-name: fadeInDownBig; - animation-name: fadeInDownBig; -} - -@-webkit-keyframes fadeInLeft { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInLeft { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInLeft { - -webkit-animation-name: fadeInLeft; - animation-name: fadeInLeft; -} - -@-webkit-keyframes fadeInLeftBig { - from { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInLeftBig { - from { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInLeftBig { - -webkit-animation-name: fadeInLeftBig; - animation-name: fadeInLeftBig; -} - -@-webkit-keyframes fadeInRight { - from { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInRight { - from { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInRight { - -webkit-animation-name: fadeInRight; - animation-name: fadeInRight; -} - -@-webkit-keyframes fadeInRightBig { - from { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInRightBig { - from { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInRightBig { - -webkit-animation-name: fadeInRightBig; - animation-name: fadeInRightBig; -} - -@-webkit-keyframes fadeInUp { - from { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInUp { - from { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInUp { - -webkit-animation-name: fadeInUp; - animation-name: fadeInUp; -} - -@-webkit-keyframes fadeInUpBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInUpBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInUpBig { - -webkit-animation-name: fadeInUpBig; - animation-name: fadeInUpBig; -} - -@-webkit-keyframes fadeOut { - from { - opacity: 1; - } - - to { - opacity: 0; - } -} - -@keyframes fadeOut { - from { - opacity: 1; - } - - to { - opacity: 0; - } -} - -.fadeOut { - -webkit-animation-name: fadeOut; - animation-name: fadeOut; -} - -@-webkit-keyframes fadeOutDown { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -@keyframes fadeOutDown { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -.fadeOutDown { - -webkit-animation-name: fadeOutDown; - animation-name: fadeOutDown; -} - -@-webkit-keyframes fadeOutDownBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -@keyframes fadeOutDownBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -.fadeOutDownBig { - -webkit-animation-name: fadeOutDownBig; - animation-name: fadeOutDownBig; -} - -@-webkit-keyframes fadeOutLeft { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -@keyframes fadeOutLeft { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -.fadeOutLeft { - -webkit-animation-name: fadeOutLeft; - animation-name: fadeOutLeft; -} - -@-webkit-keyframes fadeOutLeftBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -@keyframes fadeOutLeftBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -.fadeOutLeftBig { - -webkit-animation-name: fadeOutLeftBig; - animation-name: fadeOutLeftBig; -} - -@-webkit-keyframes fadeOutRight { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -@keyframes fadeOutRight { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -.fadeOutRight { - -webkit-animation-name: fadeOutRight; - animation-name: fadeOutRight; -} - -@-webkit-keyframes fadeOutRightBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -@keyframes fadeOutRightBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -.fadeOutRightBig { - -webkit-animation-name: fadeOutRightBig; - animation-name: fadeOutRightBig; -} - -@-webkit-keyframes fadeOutUp { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -@keyframes fadeOutUp { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -.fadeOutUp { - -webkit-animation-name: fadeOutUp; - animation-name: fadeOutUp; -} - -@-webkit-keyframes fadeOutUpBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -@keyframes fadeOutUpBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -.fadeOutUpBig { - -webkit-animation-name: fadeOutUpBig; - animation-name: fadeOutUpBig; -} - -@-webkit-keyframes flip { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 40% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 50% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 80% { - -webkit-transform: perspective(400px) scale3d(.95, .95, .95); - transform: perspective(400px) scale3d(.95, .95, .95); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } -} - -@keyframes flip { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 40% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 50% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 80% { - -webkit-transform: perspective(400px) scale3d(.95, .95, .95); - transform: perspective(400px) scale3d(.95, .95, .95); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } -} - -.animated.flip { - -webkit-backface-visibility: visible; - backface-visibility: visible; - -webkit-animation-name: flip; - animation-name: flip; -} - -@-webkit-keyframes flipInX { - from { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -@keyframes flipInX { - from { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -.flipInX { - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipInX; - animation-name: flipInX; -} - -@-webkit-keyframes flipInY { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -@keyframes flipInY { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -.flipInY { - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipInY; - animation-name: flipInY; -} - -@-webkit-keyframes flipOutX { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - opacity: 0; - } -} - -@keyframes flipOutX { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - opacity: 0; - } -} - -.flipOutX { - -webkit-animation-name: flipOutX; - animation-name: flipOutX; - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; -} - -@-webkit-keyframes flipOutY { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - opacity: 0; - } -} - -@keyframes flipOutY { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - opacity: 0; - } -} - -.flipOutY { - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipOutY; - animation-name: flipOutY; -} - -@-webkit-keyframes lightSpeedIn { - from { - -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); - transform: translate3d(100%, 0, 0) skewX(-30deg); - opacity: 0; - } - - 60% { - -webkit-transform: skewX(20deg); - transform: skewX(20deg); - opacity: 1; - } - - 80% { - -webkit-transform: skewX(-5deg); - transform: skewX(-5deg); - opacity: 1; - } - - to { - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes lightSpeedIn { - from { - -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); - transform: translate3d(100%, 0, 0) skewX(-30deg); - opacity: 0; - } - - 60% { - -webkit-transform: skewX(20deg); - transform: skewX(20deg); - opacity: 1; - } - - 80% { - -webkit-transform: skewX(-5deg); - transform: skewX(-5deg); - opacity: 1; - } - - to { - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.lightSpeedIn { - -webkit-animation-name: lightSpeedIn; - animation-name: lightSpeedIn; - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; -} - -@-webkit-keyframes lightSpeedOut { - from { - opacity: 1; - } - - to { - -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); - transform: translate3d(100%, 0, 0) skewX(30deg); - opacity: 0; - } -} - -@keyframes lightSpeedOut { - from { - opacity: 1; - } - - to { - -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); - transform: translate3d(100%, 0, 0) skewX(30deg); - opacity: 0; - } -} - -.lightSpeedOut { - -webkit-animation-name: lightSpeedOut; - animation-name: lightSpeedOut; - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; -} - -@-webkit-keyframes rotateIn { - from { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, -200deg); - transform: rotate3d(0, 0, 1, -200deg); - opacity: 0; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateIn { - from { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, -200deg); - transform: rotate3d(0, 0, 1, -200deg); - opacity: 0; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateIn { - -webkit-animation-name: rotateIn; - animation-name: rotateIn; -} - -@-webkit-keyframes rotateInDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInDownLeft { - -webkit-animation-name: rotateInDownLeft; - animation-name: rotateInDownLeft; -} - -@-webkit-keyframes rotateInDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInDownRight { - -webkit-animation-name: rotateInDownRight; - animation-name: rotateInDownRight; -} - -@-webkit-keyframes rotateInUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInUpLeft { - -webkit-animation-name: rotateInUpLeft; - animation-name: rotateInUpLeft; -} - -@-webkit-keyframes rotateInUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -90deg); - transform: rotate3d(0, 0, 1, -90deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -90deg); - transform: rotate3d(0, 0, 1, -90deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInUpRight { - -webkit-animation-name: rotateInUpRight; - animation-name: rotateInUpRight; -} - -@-webkit-keyframes rotateOut { - from { - -webkit-transform-origin: center; - transform-origin: center; - opacity: 1; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, 200deg); - transform: rotate3d(0, 0, 1, 200deg); - opacity: 0; - } -} - -@keyframes rotateOut { - from { - -webkit-transform-origin: center; - transform-origin: center; - opacity: 1; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, 200deg); - transform: rotate3d(0, 0, 1, 200deg); - opacity: 0; - } -} - -.rotateOut { - -webkit-animation-name: rotateOut; - animation-name: rotateOut; -} - -@-webkit-keyframes rotateOutDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } -} - -@keyframes rotateOutDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } -} - -.rotateOutDownLeft { - -webkit-animation-name: rotateOutDownLeft; - animation-name: rotateOutDownLeft; -} - -@-webkit-keyframes rotateOutDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -@keyframes rotateOutDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -.rotateOutDownRight { - -webkit-animation-name: rotateOutDownRight; - animation-name: rotateOutDownRight; -} - -@-webkit-keyframes rotateOutUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -@keyframes rotateOutUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -.rotateOutUpLeft { - -webkit-animation-name: rotateOutUpLeft; - animation-name: rotateOutUpLeft; -} - -@-webkit-keyframes rotateOutUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 90deg); - transform: rotate3d(0, 0, 1, 90deg); - opacity: 0; - } -} - -@keyframes rotateOutUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 90deg); - transform: rotate3d(0, 0, 1, 90deg); - opacity: 0; - } -} - -.rotateOutUpRight { - -webkit-animation-name: rotateOutUpRight; - animation-name: rotateOutUpRight; -} - -@-webkit-keyframes hinge { - 0% { - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 20%, 60% { - -webkit-transform: rotate3d(0, 0, 1, 80deg); - transform: rotate3d(0, 0, 1, 80deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 40%, 80% { - -webkit-transform: rotate3d(0, 0, 1, 60deg); - transform: rotate3d(0, 0, 1, 60deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - opacity: 1; - } - - to { - -webkit-transform: translate3d(0, 700px, 0); - transform: translate3d(0, 700px, 0); - opacity: 0; - } -} - -@keyframes hinge { - 0% { - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 20%, 60% { - -webkit-transform: rotate3d(0, 0, 1, 80deg); - transform: rotate3d(0, 0, 1, 80deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 40%, 80% { - -webkit-transform: rotate3d(0, 0, 1, 60deg); - transform: rotate3d(0, 0, 1, 60deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - opacity: 1; - } - - to { - -webkit-transform: translate3d(0, 700px, 0); - transform: translate3d(0, 700px, 0); - opacity: 0; - } -} - -.hinge { - -webkit-animation-name: hinge; - animation-name: hinge; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes rollIn { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes rollIn { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.rollIn { - -webkit-animation-name: rollIn; - animation-name: rollIn; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes rollOut { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - } -} - -@keyframes rollOut { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - } -} - -.rollOut { - -webkit-animation-name: rollOut; - animation-name: rollOut; -} - -@-webkit-keyframes zoomIn { - from { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 50% { - opacity: 1; - } -} - -@keyframes zoomIn { - from { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 50% { - opacity: 1; - } -} - -.zoomIn { - -webkit-animation-name: zoomIn; - animation-name: zoomIn; -} - -@-webkit-keyframes zoomInDown { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInDown { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInDown { - -webkit-animation-name: zoomInDown; - animation-name: zoomInDown; -} - -@-webkit-keyframes zoomInLeft { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInLeft { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInLeft { - -webkit-animation-name: zoomInLeft; - animation-name: zoomInLeft; -} - -@-webkit-keyframes zoomInRight { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInRight { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInRight { - -webkit-animation-name: zoomInRight; - animation-name: zoomInRight; -} - -@-webkit-keyframes zoomInUp { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInUp { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInUp { - -webkit-animation-name: zoomInUp; - animation-name: zoomInUp; -} - -@-webkit-keyframes zoomOut { - from { - opacity: 1; - } - - 50% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - to { - opacity: 0; - } -} - -@keyframes zoomOut { - from { - opacity: 1; - } - - 50% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - to { - opacity: 0; - } -} - -.zoomOut { - -webkit-animation-name: zoomOut; - animation-name: zoomOut; -} - -@-webkit-keyframes zoomOutDown { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomOutDown { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomOutDown { - -webkit-animation-name: zoomOutDown; - animation-name: zoomOutDown; -} - -@-webkit-keyframes zoomOutLeft { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); - transform: scale(.1) translate3d(-2000px, 0, 0); - -webkit-transform-origin: left center; - transform-origin: left center; - } -} - -@keyframes zoomOutLeft { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); - transform: scale(.1) translate3d(-2000px, 0, 0); - -webkit-transform-origin: left center; - transform-origin: left center; - } -} - -.zoomOutLeft { - -webkit-animation-name: zoomOutLeft; - animation-name: zoomOutLeft; -} - -@-webkit-keyframes zoomOutRight { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(2000px, 0, 0); - transform: scale(.1) translate3d(2000px, 0, 0); - -webkit-transform-origin: right center; - transform-origin: right center; - } -} - -@keyframes zoomOutRight { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(2000px, 0, 0); - transform: scale(.1) translate3d(2000px, 0, 0); - -webkit-transform-origin: right center; - transform-origin: right center; - } -} - -.zoomOutRight { - -webkit-animation-name: zoomOutRight; - animation-name: zoomOutRight; -} - -@-webkit-keyframes zoomOutUp { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomOutUp { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomOutUp { - -webkit-animation-name: zoomOutUp; - animation-name: zoomOutUp; -} - -@-webkit-keyframes slideInDown { - from { - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInDown { - from { - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInDown { - -webkit-animation-name: slideInDown; - animation-name: slideInDown; -} - -@-webkit-keyframes slideInLeft { - from { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInLeft { - from { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInLeft { - -webkit-animation-name: slideInLeft; - animation-name: slideInLeft; -} - -@-webkit-keyframes slideInRight { - from { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInRight { - from { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInRight { - -webkit-animation-name: slideInRight; - animation-name: slideInRight; -} - -@-webkit-keyframes slideInUp { - from { - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInUp { - from { - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInUp { - -webkit-animation-name: slideInUp; - animation-name: slideInUp; -} - -@-webkit-keyframes slideOutDown { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -@keyframes slideOutDown { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -.slideOutDown { - -webkit-animation-name: slideOutDown; - animation-name: slideOutDown; -} - -@-webkit-keyframes slideOutLeft { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -@keyframes slideOutLeft { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -.slideOutLeft { - -webkit-animation-name: slideOutLeft; - animation-name: slideOutLeft; -} - -@-webkit-keyframes slideOutRight { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -@keyframes slideOutRight { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -.slideOutRight { - -webkit-animation-name: slideOutRight; - animation-name: slideOutRight; -} - -@-webkit-keyframes slideOutUp { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -@keyframes slideOutUp { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -.slideOutUp { - -webkit-animation-name: slideOutUp; - animation-name: slideOutUp; -} diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/animate-css/animate.min.css b/Plan/common/src/main/resources/assets/plan/web/plugins/animate-css/animate.min.css deleted file mode 100644 index 995954196..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/animate-css/animate.min.css +++ /dev/null @@ -1,11 +0,0 @@ -@charset "UTF-8"; - -/*! - * animate.css -http://daneden.me/animate - * Version - 3.5.0 - * Licensed under the MIT license - http://opensource.org/licenses/MIT - * - * Copyright (c) 2016 Daniel Eden - */ - -.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}40%,43%,70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06)}70%{-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}40%,43%,70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06)}70%{-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}.headShake{-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-name:headShake;animation-name:headShake}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:none;transform:none}}@keyframes wobble{0%{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{0%,11.1%,to{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{0%,11.1%,to{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:none;transform:none}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) rotateY(-1turn);transform:perspective(400px) rotateY(-1turn)}0%,40%{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-190deg);transform:perspective(400px) translateZ(150px) rotateY(-190deg)}50%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-170deg);transform:perspective(400px) translateZ(150px) rotateY(-170deg)}50%,80%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95)}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) rotateY(-1turn);transform:perspective(400px) rotateY(-1turn)}0%,40%{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-190deg);transform:perspective(400px) translateZ(150px) rotateY(-190deg)}50%{-webkit-transform:perspective(400px) translateZ(150px) rotateY(-170deg);transform:perspective(400px) translateZ(150px) rotateY(-170deg)}50%,80%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95)}to{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}0%,40%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg)}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}0%,40%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg)}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}0%,40%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg)}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}0%,40%{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg)}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg)}60%,80%{opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg)}60%,80%{opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{transform-origin:center;-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}0%,to{-webkit-transform-origin:center}to{transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{0%{transform-origin:center;-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}0%,to{-webkit-transform-origin:center}to{transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{0%{transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{transform-origin:right bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{0%{transform-origin:right bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{0%{transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{0%{transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{transform-origin:center;opacity:1}0%,to{-webkit-transform-origin:center}to{transform-origin:center;-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}@keyframes rotateOut{0%{transform-origin:center;opacity:1}0%,to{-webkit-transform-origin:center}to{transform-origin:center;-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{transform-origin:left bottom;opacity:1}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{transform-origin:left bottom;opacity:1}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{transform-origin:right bottom;opacity:1}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{transform-origin:right bottom;opacity:1}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{transform-origin:left bottom;opacity:1}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{transform-origin:left bottom;opacity:1}0%,to{-webkit-transform-origin:left bottom}to{transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{transform-origin:right bottom;opacity:1}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutUpRight{0%{transform-origin:right bottom;opacity:1}0%,to{-webkit-transform-origin:right bottom}to{transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{transform-origin:top left}0%,20%,60%{-webkit-transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);transform-origin:top left}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{transform-origin:top left}0%,20%,60%{-webkit-transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);transform-origin:top left}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}@keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%,to{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%,to{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/autosize/autosize.js b/Plan/common/src/main/resources/assets/plan/web/plugins/autosize/autosize.js deleted file mode 100644 index 49b8b0b95..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/autosize/autosize.js +++ /dev/null @@ -1,262 +0,0 @@ -/*! - Autosize 3.0.17 - license: MIT - http://www.jacklmoore.com/autosize -*/ -(function (global, factory) { - if (typeof define === 'function' && define.amd) { - define(['exports', 'module'], factory); - } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') { - factory(exports, module); - } else { - var mod = { - exports: {} - }; - factory(mod.exports, mod); - global.autosize = mod.exports; - } -})(this, function (exports, module) { - 'use strict'; - - var set = typeof Set === 'function' ? new Set() : (function () { - var list = []; - - return { - has: function has(key) { - return Boolean(list.indexOf(key) > -1); - }, - add: function add(key) { - list.push(key); - }, - 'delete': function _delete(key) { - list.splice(list.indexOf(key), 1); - } }; - })(); - - var createEvent = function createEvent(name) { - return new Event(name); - }; - try { - new Event('test'); - } catch (e) { - // IE does not support `new Event()` - createEvent = function (name) { - var evt = document.createEvent('Event'); - evt.initEvent(name, true, false); - return evt; - }; - } - - function assign(ta) { - if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || set.has(ta)) return; - - var heightOffset = null; - var clientWidth = ta.clientWidth; - var cachedHeight = null; - - function init() { - var style = window.getComputedStyle(ta, null); - - if (style.resize === 'vertical') { - ta.style.resize = 'none'; - } else if (style.resize === 'both') { - ta.style.resize = 'horizontal'; - } - - if (style.boxSizing === 'content-box') { - heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); - } else { - heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); - } - // Fix when a textarea is not on document body and heightOffset is Not a Number - if (isNaN(heightOffset)) { - heightOffset = 0; - } - - update(); - } - - function changeOverflow(value) { - { - // Chrome/Safari-specific fix: - // When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space - // made available by removing the scrollbar. The following forces the necessary text reflow. - var width = ta.style.width; - ta.style.width = '0px'; - // Force reflow: - /* jshint ignore:start */ - ta.offsetWidth; - /* jshint ignore:end */ - ta.style.width = width; - } - - ta.style.overflowY = value; - - resize(); - } - - function getParentOverflows(el) { - var arr = []; - - while (el && el.parentNode && el.parentNode instanceof Element) { - if (el.parentNode.scrollTop) { - arr.push({ - node: el.parentNode, - scrollTop: el.parentNode.scrollTop }); - } - el = el.parentNode; - } - - return arr; - } - - function resize() { - var originalHeight = ta.style.height; - var overflows = getParentOverflows(ta); - var docTop = document.documentElement && document.documentElement.scrollTop; // Needed for Mobile IE (ticket #240) - - ta.style.height = 'auto'; - - var endHeight = ta.scrollHeight + heightOffset; - - if (ta.scrollHeight === 0) { - // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM. - ta.style.height = originalHeight; - return; - } - - ta.style.height = endHeight + 'px'; - - // used to check if an update is actually necessary on window.resize - clientWidth = ta.clientWidth; - - // prevents scroll-position jumping - overflows.forEach(function (el) { - el.node.scrollTop = el.scrollTop; - }); - - if (docTop) { - document.documentElement.scrollTop = docTop; - } - } - - function update() { - resize(); - - var computed = window.getComputedStyle(ta, null); - var computedHeight = Math.round(parseFloat(computed.height)); - var styleHeight = Math.round(parseFloat(ta.style.height)); - - // The computed height not matching the height set via resize indicates that - // the max-height has been exceeded, in which case the overflow should be set to visible. - if (computedHeight !== styleHeight) { - if (computed.overflowY !== 'visible') { - changeOverflow('visible'); - } - } else { - // Normally keep overflow set to hidden, to avoid flash of scrollbar as the textarea expands. - if (computed.overflowY !== 'hidden') { - changeOverflow('hidden'); - } - } - - if (cachedHeight !== computedHeight) { - cachedHeight = computedHeight; - var evt = createEvent('autosize:resized'); - ta.dispatchEvent(evt); - } - } - - var pageResize = function pageResize() { - if (ta.clientWidth !== clientWidth) { - update(); - } - }; - - var destroy = (function (style) { - window.removeEventListener('resize', pageResize, false); - ta.removeEventListener('input', update, false); - ta.removeEventListener('keyup', update, false); - ta.removeEventListener('autosize:destroy', destroy, false); - ta.removeEventListener('autosize:update', update, false); - set['delete'](ta); - - Object.keys(style).forEach(function (key) { - ta.style[key] = style[key]; - }); - }).bind(ta, { - height: ta.style.height, - resize: ta.style.resize, - overflowY: ta.style.overflowY, - overflowX: ta.style.overflowX, - wordWrap: ta.style.wordWrap }); - - ta.addEventListener('autosize:destroy', destroy, false); - - // IE9 does not fire onpropertychange or oninput for deletions, - // so binding to onkeyup to catch most of those events. - // There is no way that I know of to detect something like 'cut' in IE9. - if ('onpropertychange' in ta && 'oninput' in ta) { - ta.addEventListener('keyup', update, false); - } - - window.addEventListener('resize', pageResize, false); - ta.addEventListener('input', update, false); - ta.addEventListener('autosize:update', update, false); - set.add(ta); - ta.style.overflowX = 'hidden'; - ta.style.wordWrap = 'break-word'; - - init(); - } - - function destroy(ta) { - if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; - var evt = createEvent('autosize:destroy'); - ta.dispatchEvent(evt); - } - - function update(ta) { - if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; - var evt = createEvent('autosize:update'); - ta.dispatchEvent(evt); - } - - var autosize = null; - - // Do nothing in Node.js environment and IE8 (or lower) - if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') { - autosize = function (el) { - return el; - }; - autosize.destroy = function (el) { - return el; - }; - autosize.update = function (el) { - return el; - }; - } else { - autosize = function (el, options) { - if (el) { - Array.prototype.forEach.call(el.length ? el : [el], function (x) { - return assign(x, options); - }); - } - return el; - }; - autosize.destroy = function (el) { - if (el) { - Array.prototype.forEach.call(el.length ? el : [el], destroy); - } - return el; - }; - autosize.update = function (el) { - if (el) { - Array.prototype.forEach.call(el.length ? el : [el], update); - } - return el; - }; - } - - module.exports = autosize; -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/autosize/autosize.min.js b/Plan/common/src/main/resources/assets/plan/web/plugins/autosize/autosize.min.js deleted file mode 100644 index 2108e9033..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/autosize/autosize.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - Autosize 3.0.17 - license: MIT - http://www.jacklmoore.com/autosize -*/ -!function(e,t){if("function"==typeof define&&define.amd)define(["exports","module"],t);else if("undefined"!=typeof exports&&"undefined"!=typeof module)t(exports,module);else{var n={exports:{}};t(n.exports,n),e.autosize=n.exports}}(this,function(e,t){"use strict";function n(e){function t(){var t=window.getComputedStyle(e,null);"vertical"===t.resize?e.style.resize="none":"both"===t.resize&&(e.style.resize="horizontal"),l="content-box"===t.boxSizing?-(parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)):parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth),isNaN(l)&&(l=0),a()}function n(t){var n=e.style.width;e.style.width="0px",e.offsetWidth,e.style.width=n,e.style.overflowY=t,r()}function o(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&t.push({node:e.parentNode,scrollTop:e.parentNode.scrollTop}),e=e.parentNode;return t}function r(){var t=e.style.height,n=o(e),r=document.documentElement&&document.documentElement.scrollTop;e.style.height="auto";var i=e.scrollHeight+l;return 0===e.scrollHeight?void(e.style.height=t):(e.style.height=i+"px",s=e.clientWidth,n.forEach(function(e){e.node.scrollTop=e.scrollTop}),void(r&&(document.documentElement.scrollTop=r)))}function a(){r();var t=window.getComputedStyle(e,null),o=Math.round(parseFloat(t.height)),i=Math.round(parseFloat(e.style.height));if(o!==i?"visible"!==t.overflowY&&n("visible"):"hidden"!==t.overflowY&&n("hidden"),u!==o){u=o;var a=d("autosize:resized");e.dispatchEvent(a)}}if(e&&e.nodeName&&"TEXTAREA"===e.nodeName&&!i.has(e)){var l=null,s=e.clientWidth,u=null,c=function(){e.clientWidth!==s&&a()},p=function(t){window.removeEventListener("resize",c,!1),e.removeEventListener("input",a,!1),e.removeEventListener("keyup",a,!1),e.removeEventListener("autosize:destroy",p,!1),e.removeEventListener("autosize:update",a,!1),i["delete"](e),Object.keys(t).forEach(function(n){e.style[n]=t[n]})}.bind(e,{height:e.style.height,resize:e.style.resize,overflowY:e.style.overflowY,overflowX:e.style.overflowX,wordWrap:e.style.wordWrap});e.addEventListener("autosize:destroy",p,!1),"onpropertychange"in e&&"oninput"in e&&e.addEventListener("keyup",a,!1),window.addEventListener("resize",c,!1),e.addEventListener("input",a,!1),e.addEventListener("autosize:update",a,!1),i.add(e),e.style.overflowX="hidden",e.style.wordWrap="break-word",t()}}function o(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName){var t=d("autosize:destroy");e.dispatchEvent(t)}}function r(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName){var t=d("autosize:update");e.dispatchEvent(t)}}var i="function"==typeof Set?new Set:function(){var e=[];return{has:function(t){return Boolean(e.indexOf(t)>-1)},add:function(t){e.push(t)},"delete":function(t){e.splice(e.indexOf(t),1)}}}(),d=function(e){return new Event(e)};try{new Event("test")}catch(a){d=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!1),t}}var l=null;"undefined"==typeof window||"function"!=typeof window.getComputedStyle?(l=function(e){return e},l.destroy=function(e){return e},l.update=function(e){return e}):(l=function(e,t){return e&&Array.prototype.forEach.call(e.length?e:[e],function(e){return n(e,t)}),e},l.destroy=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],o),e},l.update=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],r),e}),t.exports=l}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.css b/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.css deleted file mode 100644 index 0f47dd40f..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.css +++ /dev/null @@ -1,222 +0,0 @@ -/*! - * Bootstrap Colorpicker v2.3.3 - * http://mjolnic.github.io/bootstrap-colorpicker/ - * - * Originally written by (c) 2012 Stefan Petre - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0.txt - * - */ -.colorpicker-saturation { - width: 100px; - height: 100px; - background-image: url("../img/bootstrap-colorpicker/saturation.png"); - cursor: crosshair; - float: left; -} -.colorpicker-saturation i { - display: block; - height: 5px; - width: 5px; - border: 1px solid #000; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - position: absolute; - top: 0; - left: 0; - margin: -4px 0 0 -4px; -} -.colorpicker-saturation i b { - display: block; - height: 5px; - width: 5px; - border: 1px solid #fff; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.colorpicker-hue, -.colorpicker-alpha { - width: 15px; - height: 100px; - float: left; - cursor: row-resize; - margin-left: 4px; - margin-bottom: 4px; -} -.colorpicker-hue i, -.colorpicker-alpha i { - display: block; - height: 1px; - background: #000; - border-top: 1px solid #fff; - position: absolute; - top: 0; - left: 0; - width: 100%; - margin-top: -1px; -} -.colorpicker-hue { - background-image: url("../img/bootstrap-colorpicker/hue.png"); -} -.colorpicker-alpha { - background-image: url("../img/bootstrap-colorpicker/alpha.png"); - display: none; -} -.colorpicker-saturation, -.colorpicker-hue, -.colorpicker-alpha { - background-size: contain; -} -.colorpicker { - padding: 4px; - min-width: 130px; - margin-top: 1px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - z-index: 2500; -} -.colorpicker:before, -.colorpicker:after { - display: table; - content: ""; - line-height: 0; -} -.colorpicker:after { - clear: both; -} -.colorpicker:before { - content: ''; - display: inline-block; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; - border-bottom-color: rgba(0, 0, 0, 0.2); - position: absolute; - top: -7px; - left: 6px; -} -.colorpicker:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #ffffff; - position: absolute; - top: -6px; - left: 7px; -} -.colorpicker div { - position: relative; -} -.colorpicker.colorpicker-with-alpha { - min-width: 140px; -} -.colorpicker.colorpicker-with-alpha .colorpicker-alpha { - display: block; -} -.colorpicker-color { - height: 10px; - margin-top: 5px; - clear: both; - background-image: url("../img/bootstrap-colorpicker/alpha.png"); - background-position: 0 100%; -} -.colorpicker-color div { - height: 10px; -} -.colorpicker-selectors { - display: none; - height: 10px; - margin-top: 5px; - clear: both; -} -.colorpicker-selectors i { - cursor: pointer; - float: left; - height: 10px; - width: 10px; -} -.colorpicker-selectors i + i { - margin-left: 3px; -} -.colorpicker-element .input-group-addon i, -.colorpicker-element .add-on i { - display: inline-block; - cursor: pointer; - height: 16px; - vertical-align: text-top; - width: 16px; -} -.colorpicker.colorpicker-inline { - position: relative; - display: inline-block; - float: none; - z-index: auto; -} -.colorpicker.colorpicker-horizontal { - width: 110px; - min-width: 110px; - height: auto; -} -.colorpicker.colorpicker-horizontal .colorpicker-saturation { - margin-bottom: 4px; -} -.colorpicker.colorpicker-horizontal .colorpicker-color { - width: 100px; -} -.colorpicker.colorpicker-horizontal .colorpicker-hue, -.colorpicker.colorpicker-horizontal .colorpicker-alpha { - width: 100px; - height: 15px; - float: left; - cursor: col-resize; - margin-left: 0; - margin-bottom: 4px; -} -.colorpicker.colorpicker-horizontal .colorpicker-hue i, -.colorpicker.colorpicker-horizontal .colorpicker-alpha i { - display: block; - height: 15px; - background: #ffffff; - position: absolute; - top: 0; - left: 0; - width: 1px; - border: none; - margin-top: 0; -} -.colorpicker.colorpicker-horizontal .colorpicker-hue { - background-image: url("../img/bootstrap-colorpicker/hue-horizontal.png"); -} -.colorpicker.colorpicker-horizontal .colorpicker-alpha { - background-image: url("../img/bootstrap-colorpicker/alpha-horizontal.png"); -} -.colorpicker.colorpicker-hidden { - display: none; -} -.colorpicker.colorpicker-visible { - display: block; -} -.colorpicker-inline.colorpicker-visible { - display: inline-block; -} -.colorpicker-right:before { - left: auto; - right: 6px; -} -.colorpicker-right:after { - left: auto; - right: 7px; -} -.colorpicker-no-arrow:before { - border-right: 0; - border-left: 0; -} -.colorpicker-no-arrow:after { - border-right: 0; - border-left: 0; -} -/*# sourceMappingURL=bootstrap-colorpicker.css.map */ \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.css.map b/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.css.map deleted file mode 100644 index e61413ad6..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["src/less/colorpicker.less"],"names":[],"mappings":";;;;;;;;;AAqBA;EACE,YAAA;EACA,aAAA;EAXA,sBAAsB,8CAAtB;EAaA,iBAAA;EACA,WAAA;;AALF,uBAME;EACE,cAAA;EACA,WAAA;EACA,UAAA;EACA,sBAAA;EAfF,0BAAA;EACA,uBAAA;EACA,kBAAA;EAeE,kBAAA;EACA,MAAA;EACA,OAAA;EACA,qBAAA;;AAfJ,uBAME,EAUE;EACE,cAAA;EACA,WAAA;EACA,UAAA;EACA,sBAAA;EAzBJ,0BAAA;EACA,uBAAA;EACA,kBAAA;;AA6BF;AACA;EACE,WAAA;EACA,aAAA;EACA,WAAA;EACA,kBAAA;EACA,gBAAA;EACA,kBAAA;;AAGF,gBAAiB;AACjB,kBAAmB;EACjB,cAAA;EACA,WAAA;EACA,gBAAA;EACA,0BAAA;EACA,kBAAA;EACA,MAAA;EACA,OAAA;EACA,WAAA;EACA,gBAAA;;AAGF;EA1DE,sBAAsB,uCAAtB;;AA8DF;EA9DE,sBAAsB,yCAAtB;EAgEA,aAAA;;AAGF;AACA;AACA;EACE,wBAAA;;AAGF;EACE,YAAA;EACA,gBAAA;EACA,eAAA;EAxEA,0BAAA;EACA,uBAAA;EACA,kBAAA;EAwEA,aAAA;;AAGF,YAAY;AACZ,YAAY;EACV,cAAA;EACA,SAAS,EAAT;EACA,cAAA;;AAGF,YAAY;EACV,WAAA;;AAGF,YAAY;EACV,SAAS,EAAT;EACA,qBAAA;EACA,kCAAA;EACA,mCAAA;EACA,6BAAA;EACA,uCAAA;EACA,kBAAA;EACA,SAAA;EACA,SAAA;;AAGF,YAAY;EACV,SAAS,EAAT;EACA,qBAAA;EACA,kCAAA;EACA,mCAAA;EACA,gCAAA;EACA,kBAAA;EACA,SAAA;EACA,SAAA;;AAGF,YAAa;EACX,kBAAA;;AAGF,YAAY;EACV,gBAAA;;AAGF,YAAY,uBAAwB;EAClC,cAAA;;AAGF;EACE,YAAA;EACA,eAAA;EACA,WAAA;EAlIA,sBAAsB,yCAAtB;EAoIA,2BAAA;;AAGF,kBAAmB;EACjB,YAAA;;AAGF;EACE,aAAA;EACA,YAAA;EACA,eAAA;EACA,WAAA;;AAGF,sBAAuB;EACrB,eAAA;EACA,WAAA;EACA,YAAA;EACA,WAAA;;AAGF,sBAAuB,EAAE;EACvB,gBAAA;;AAGF,oBAAqB,mBAAmB;AACxC,oBAAqB,QAAQ;EAC3B,qBAAA;EACA,eAAA;EACA,YAAA;EACA,wBAAA;EACA,WAAA;;AAGF,YAAY;EACV,kBAAA;EACA,qBAAA;EACA,WAAA;EACA,aAAA;;AAGF,YAAY;EACV,YAAA;EACA,gBAAA;EACA,YAAA;;AAGF,YAAY,uBAAwB;EAClC,kBAAA;;AAGF,YAAY,uBAAwB;EAClC,YAAA;;AAGF,YAAY,uBAAwB;AACpC,YAAY,uBAAwB;EAClC,YAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,gBAAA;EACA,kBAAA;;AAGF,YAAY,uBAAwB,iBAAiB;AACrD,YAAY,uBAAwB,mBAAmB;EACrD,cAAA;EACA,YAAA;EACA,mBAAA;EACA,kBAAA;EACA,MAAA;EACA,OAAA;EACA,UAAA;EACA,YAAA;EACA,eAAA;;AAGF,YAAY,uBAAwB;EAlNlC,sBAAsB,kDAAtB;;AAsNF,YAAY,uBAAwB;EAtNlC,sBAAsB,oDAAtB;;AA0NF,YAAY;EACV,aAAA;;AAGF,YAAY;EACV,cAAA;;AAGF,mBAAmB;EACjB,qBAAA;;AAGF,kBAAkB;EAChB,UAAA;EACA,UAAA;;AAGF,kBAAkB;EAChB,UAAA;EACA,UAAA;;AAGF,qBAAqB;EACnB,eAAA;EACA,cAAA;;AAGF,qBAAqB;EACnB,eAAA;EACA,cAAA","sourcesContent":["/*!\n * Bootstrap Colorpicker v2.3.3\n * http://mjolnic.github.io/bootstrap-colorpicker/\n *\n * Originally written by (c) 2012 Stefan Petre\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0.txt\n *\n */\n@imgPath: \"../img/bootstrap-colorpicker/\";\n\n.bgImg(@imgFilename) {\n background-image: url(\"@{imgPath}@{imgFilename}\");\n}\n\n.borderRadius(@size) {\n -webkit-border-radius: @size;\n -moz-border-radius: @size;\n border-radius: @size;\n}\n\n.colorpicker-saturation {\n width: 100px;\n height: 100px;\n .bgImg('saturation.png');\n cursor: crosshair;\n float: left;\n i {\n display: block;\n height: 5px;\n width: 5px;\n border: 1px solid #000;\n .borderRadius(5px);\n position: absolute;\n top: 0;\n left: 0;\n margin: -4px 0 0 -4px;\n b {\n display: block;\n height: 5px;\n width: 5px;\n border: 1px solid #fff;\n .borderRadius(5px);\n }\n }\n}\n\n.colorpicker-hue,\n.colorpicker-alpha {\n width: 15px;\n height: 100px;\n float: left;\n cursor: row-resize;\n margin-left: 4px;\n margin-bottom: 4px;\n}\n\n.colorpicker-hue i,\n.colorpicker-alpha i {\n display: block;\n height: 1px;\n background: #000;\n border-top: 1px solid #fff;\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n margin-top: -1px;\n}\n\n.colorpicker-hue {\n .bgImg('hue.png');\n}\n\n.colorpicker-alpha {\n .bgImg('alpha.png');\n display: none;\n}\n\n.colorpicker-saturation,\n.colorpicker-hue,\n.colorpicker-alpha {\n background-size: contain;\n}\n\n.colorpicker {\n padding: 4px;\n min-width: 130px;\n margin-top: 1px;\n .borderRadius(4px);\n z-index: 2500;\n}\n\n.colorpicker:before,\n.colorpicker:after {\n display: table;\n content: \"\";\n line-height: 0;\n}\n\n.colorpicker:after {\n clear: both;\n}\n\n.colorpicker:before {\n content: '';\n display: inline-block;\n border-left: 7px solid transparent;\n border-right: 7px solid transparent;\n border-bottom: 7px solid #ccc;\n border-bottom-color: rgba(0, 0, 0, 0.2);\n position: absolute;\n top: -7px;\n left: 6px;\n}\n\n.colorpicker:after {\n content: '';\n display: inline-block;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid #ffffff;\n position: absolute;\n top: -6px;\n left: 7px;\n}\n\n.colorpicker div {\n position: relative;\n}\n\n.colorpicker.colorpicker-with-alpha {\n min-width: 140px;\n}\n\n.colorpicker.colorpicker-with-alpha .colorpicker-alpha {\n display: block;\n}\n\n.colorpicker-color {\n height: 10px;\n margin-top: 5px;\n clear: both;\n .bgImg('alpha.png');\n background-position: 0 100%;\n}\n\n.colorpicker-color div {\n height: 10px;\n}\n\n.colorpicker-selectors {\n display: none;\n height: 10px;\n margin-top: 5px;\n clear: both;\n}\n\n.colorpicker-selectors i {\n cursor: pointer;\n float: left;\n height: 10px;\n width: 10px;\n}\n\n.colorpicker-selectors i + i {\n margin-left: 3px;\n}\n\n.colorpicker-element .input-group-addon i,\n.colorpicker-element .add-on i {\n display: inline-block;\n cursor: pointer;\n height: 16px;\n vertical-align: text-top;\n width: 16px;\n}\n\n.colorpicker.colorpicker-inline {\n position: relative;\n display: inline-block;\n float: none;\n z-index: auto;\n}\n\n.colorpicker.colorpicker-horizontal {\n width: 110px;\n min-width: 110px;\n height: auto;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-saturation {\n margin-bottom: 4px;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-color {\n width: 100px;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-hue,\n.colorpicker.colorpicker-horizontal .colorpicker-alpha {\n width: 100px;\n height: 15px;\n float: left;\n cursor: col-resize;\n margin-left: 0px;\n margin-bottom: 4px;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-hue i,\n.colorpicker.colorpicker-horizontal .colorpicker-alpha i {\n display: block;\n height: 15px;\n background: #ffffff;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n border: none;\n margin-top: 0px;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-hue {\n .bgImg('hue-horizontal.png');\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-alpha {\n .bgImg('alpha-horizontal.png');\n}\n\n.colorpicker.colorpicker-hidden {\n display: none;\n}\n\n.colorpicker.colorpicker-visible {\n display: block;\n}\n\n.colorpicker-inline.colorpicker-visible {\n display: inline-block;\n}\n\n.colorpicker-right:before {\n left: auto;\n right: 6px;\n}\n\n.colorpicker-right:after {\n left: auto;\n right: 7px;\n}\n\n.colorpicker-no-arrow:before {\n border-right: 0;\n border-left: 0;\n}\n\n.colorpicker-no-arrow:after {\n border-right: 0;\n border-left: 0;\n}\n"]} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css b/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css deleted file mode 100644 index 22e5c37ae..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * Bootstrap Colorpicker v2.3.3 - * http://mjolnic.github.io/bootstrap-colorpicker/ - * - * Originally written by (c) 2012 Stefan Petre - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0.txt - * - */.colorpicker-saturation{width:100px;height:100px;background-image:url(../img/bootstrap-colorpicker/saturation.png);cursor:crosshair;float:left}.colorpicker-saturation i{display:block;height:5px;width:5px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;position:absolute;top:0;left:0;margin:-4px 0 0 -4px}.colorpicker-saturation i b{display:block;height:5px;width:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-alpha,.colorpicker-hue{width:15px;height:100px;float:left;cursor:row-resize;margin-left:4px;margin-bottom:4px}.colorpicker-alpha i,.colorpicker-hue i{display:block;height:1px;background:#000;border-top:1px solid #fff;position:absolute;top:0;left:0;width:100%;margin-top:-1px}.colorpicker-hue{background-image:url(../img/bootstrap-colorpicker/hue.png)}.colorpicker-alpha{background-image:url(../img/bootstrap-colorpicker/alpha.png);display:none}.colorpicker-alpha,.colorpicker-hue,.colorpicker-saturation{background-size:contain}.colorpicker{padding:4px;min-width:130px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;z-index:2500}.colorpicker:after,.colorpicker:before{display:table;content:"";line-height:0}.colorpicker:after{clear:both}.colorpicker:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);position:absolute;top:-7px;left:6px}.colorpicker:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:7px}.colorpicker div{position:relative}.colorpicker.colorpicker-with-alpha{min-width:140px}.colorpicker.colorpicker-with-alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-image:url(../img/bootstrap-colorpicker/alpha.png);background-position:0 100%}.colorpicker-color div{height:10px}.colorpicker-selectors{display:none;height:10px;margin-top:5px;clear:both}.colorpicker-selectors i{cursor:pointer;float:left;height:10px;width:10px}.colorpicker-selectors i+i{margin-left:3px}.colorpicker-element .add-on i,.colorpicker-element .input-group-addon i{display:inline-block;cursor:pointer;height:16px;vertical-align:text-top;width:16px}.colorpicker.colorpicker-inline{position:relative;display:inline-block;float:none;z-index:auto}.colorpicker.colorpicker-horizontal{width:110px;min-width:110px;height:auto}.colorpicker.colorpicker-horizontal .colorpicker-saturation{margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-color{width:100px}.colorpicker.colorpicker-horizontal .colorpicker-alpha,.colorpicker.colorpicker-horizontal .colorpicker-hue{width:100px;height:15px;float:left;cursor:col-resize;margin-left:0;margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-alpha i,.colorpicker.colorpicker-horizontal .colorpicker-hue i{display:block;height:15px;background:#fff;position:absolute;top:0;left:0;width:1px;border:none;margin-top:0}.colorpicker.colorpicker-horizontal .colorpicker-hue{background-image:url(../img/bootstrap-colorpicker/hue-horizontal.png)}.colorpicker.colorpicker-horizontal .colorpicker-alpha{background-image:url(../img/bootstrap-colorpicker/alpha-horizontal.png)}.colorpicker.colorpicker-hidden{display:none}.colorpicker.colorpicker-visible{display:block}.colorpicker-inline.colorpicker-visible{display:inline-block}.colorpicker-right:before{left:auto;right:6px}.colorpicker-right:after{left:auto;right:7px}.colorpicker-no-arrow:before{border-right:0;border-left:0}.colorpicker-no-arrow:after{border-right:0;border-left:0} -/*# sourceMappingURL=bootstrap-colorpicker.min.css.map */ \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css.map b/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css.map deleted file mode 100644 index f61ccb3e2..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["src/less/colorpicker.less"],"names":[],"mappings":";;;;;;;;AAqBA,wBACE,MAAA,MACA,OAAA,MAXA,iBAAsB,iDAatB,OAAA,UACA,MAAA,KACA,0BACE,QAAA,MACA,OAAA,IACA,MAAA,IACA,OAAA,IAAA,MAAA,KAfF,sBAAA,IACA,mBAAA,IACA,cAAA,IAeE,SAAA,SACA,IAAA,EACA,KAAA,EACA,OAAA,KAAA,EAAA,EAAA,KACA,4BACE,QAAA,MACA,OAAA,IACA,MAAA,IACA,OAAA,IAAA,MAAA,KAzBJ,sBAAA,IACA,mBAAA,IACA,cAAA,IA8BF,mBADA,iBAEE,MAAA,KACA,OAAA,MACA,MAAA,KACA,OAAA,WACA,YAAA,IACA,cAAA,IAIiB,qBADF,mBAEf,QAAA,MACA,OAAA,IACA,WAAA,KACA,WAAA,IAAA,MAAA,KACA,SAAA,SACA,IAAA,EACA,KAAA,EACA,MAAA,KACA,WAAA,KAGF,iBA1DE,iBAAsB,0CA8DxB,mBA9DE,iBAAsB,4CAgEtB,QAAA,KAKF,mBADA,iBADA,wBAGE,gBAAA,QAGF,aACE,QAAA,IACA,UAAA,MACA,WAAA,IAxEA,sBAAA,IACA,mBAAA,IACA,cAAA,IAwEA,QAAA,KAIU,mBADA,oBAEV,QAAA,MACA,QAAA,GACA,YAAA,EAGU,mBACV,MAAA,KAGU,oBACV,QAAA,GACA,QAAA,aACA,YAAA,IAAA,MAAA,YACA,aAAA,IAAA,MAAA,YACA,cAAA,IAAA,MAAA,KACA,oBAAA,eACA,SAAA,SACA,IAAA,KACA,KAAA,IAGU,mBACV,QAAA,GACA,QAAA,aACA,YAAA,IAAA,MAAA,YACA,aAAA,IAAA,MAAA,YACA,cAAA,IAAA,MAAA,KACA,SAAA,SACA,IAAA,KACA,KAAA,IAGW,iBACX,SAAA,SAGU,oCACV,UAAA,MAGkC,uDAClC,QAAA,MAGF,mBACE,OAAA,KACA,WAAA,IACA,MAAA,KAlIA,iBAAsB,4CAoItB,oBAAA,EAAA,KAGiB,uBACjB,OAAA,KAGF,uBACE,QAAA,KACA,OAAA,KACA,WAAA,IACA,MAAA,KAGqB,yBACrB,OAAA,QACA,MAAA,KACA,OAAA,KACA,MAAA,KAGuB,2BACvB,YAAA,IAI2B,+BADW,0CAEtC,QAAA,aACA,OAAA,QACA,OAAA,KACA,eAAA,SACA,MAAA,KAGU,gCACV,SAAA,SACA,QAAA,aACA,MAAA,KACA,QAAA,KAGU,oCACV,MAAA,MACA,UAAA,MACA,OAAA,KAGkC,4DAClC,cAAA,IAGkC,uDAClC,MAAA,MAIkC,uDADA,qDAElC,MAAA,MACA,OAAA,KACA,MAAA,KACA,OAAA,WACA,YAAA,EACA,cAAA,IAIqD,yDADF,uDAEnD,QAAA,MACA,OAAA,KACA,WAAA,KACA,SAAA,SACA,IAAA,EACA,KAAA,EACA,MAAA,IACA,OAAA,KACA,WAAA,EAGkC,qDAlNlC,iBAAsB,qDAsNY,uDAtNlC,iBAAsB,uDA0NZ,gCACV,QAAA,KAGU,iCACV,QAAA,MAGiB,wCACjB,QAAA,aAGgB,0BAChB,KAAA,KACA,MAAA,IAGgB,yBAChB,KAAA,KACA,MAAA,IAGmB,6BACnB,aAAA,EACA,YAAA,EAGmB,4BACnB,aAAA,EACA,YAAA"} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png b/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png deleted file mode 100644 index f83188951a8e4fab4ba847c8c89f3105354a9816..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 557 zcmV+|0@D47P)Nkl5JbD$mJ%t8>^MX+pA8q_5}cAta0DO|R@{IU5|M(GxNxgy+GBd8l;w&2Ec?5< zVo(HvFZxdJAnNTau8ZPXtKOAPtn2rp+IrX0nbY#4bkaNYzIIZLJrooctxYd|?rp8? z)cO+ap+cSA7pbEAUi(YitNzQ6mD^}>0x7Ez^ll73R_Xc-*~Q+Zpz#R`Ko|>@qj2QF zAcKncK;vstA0eL^`!E>xIk#_;8u-NduvaQXn$g$>7z4ttYmjqc8pS->gW&WGdI5U9QmYbj;6~_suM0VjVBk)9?FjGKLNzR9mK$u}% zJ?3)?fRmicTx%xVMC69^f7R;rWA8uZm)yve{K1EP8^1~E?L`XT8&R{cit@G7SGmNI zD-;bNVa)Z2Mil~Fb~9WBo8Kj@u3_#HiLFA<1-{qWmO2-=?0YdKVz6%S z2*9Wz8-&7K@4=W?VKkD82M*@cB4wmZ=tias{62*I43WQYJZEcwS<&N#Nal+GF`i11 zY=e+9d7#-KG!R}kc+3AQ$^6t@932p}V@@!QyyuhBvt_KD{nGq0=-+8wbOe^=^onsM vr1hwgCt@ro;xv+DFr+*}$b1+=kSNMOdLipIvOQ8u00000NkvXXu0mjf9#jU9 diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png b/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png deleted file mode 100644 index 2e53a30e73175009326fc030f00862d682ddfc45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 488 zcmVP)B00056Nkl} zZ#=A8HwTy*Ji~Hui*DN)Xc=D2SbWU)JF^vFq?ipSE1)dQB?%2~zL;*2(|O#(oBR;O z#J!!4+zDc0I&77>T+tDIE@oI;6%kXWiptfQV#*c>2foJxnWs^#66pqri5SJi0v*Xc z_vjIT9?6}|hzFF05)=1g9#80;7y9mior*2jP95+vQ|{sWGtx)s=39zr^u6;HX^F`p zkx2{{y^wicti6Khm3Wyed%Eg2H=fbPc7D3VBcDWdj{r#qvrgUX$)#2lTEc%5bs}9E zZ`+UiVVyX}VI5jr+$k@C{pP8ABQF)*q|@k8ll1fgWY+Q?y|Zg0V9OmodqfH%3xo%V zF_0b~gfCME=jtfJ($v-Y^!<}BBQx2`+78RhRbxt$n5&{MunD^|({9#^#Hp{!+@o)R z!Ci&=u08T*r)OJ-Py8D;`eSXCiKA=ket6eR*LHXng}b_5r%ttFu8MwPi~vTbhPJwk eS?^O73H$>F-M_zn@}r;t0000ShR^6anYhsD}*2sixx#_ z;;N9)z(r=E(k3ElBO!xKg9K3|ZCX@f)afnmy=Qme_QYdH!ujj-fpFu|`s2Y~2olQ6 z2|AMd=Wf7d@urrB#gesBBwHjZbrP3WX_M>HCxbE~lQJV2S(N2p_yyDW7AJ5R`>_W* z@De7l32U$%Be)tvE2K~&QXw@GlZ2$CLwcoOp2~#0leB!5-{KN}!+D&+S2%(L*oR%% zhDnTLEkEmxDdue*zK#wJq_##5Q`F$=0GT~`-7ysSAOhUwhSHMLP5MN9R=S!a}6CtN3K7ctc(wrm-Pb|Ljm}_kZeK)QSKA diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png b/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png deleted file mode 100644 index 6f5ec2e502ae3e3e03f4725b0e868e8762d089ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 504 zcmWlVPe_vi0L6c6Mj^~HS41FE*i8vzMTa!3jau0Ftck^RiETv4%*eh1etNgh#Z9kO+%DF(^hwQhXE(;=A}Olt({N8qK0N zXbe3;F%&_a$d3$k2-TpSsMI2>O_Yl&aZnr=K5;=@6TM_+u^<&@c2A zeL`>1OY{`=qnoG;wWCIK1notY$WDGs$^MZILnglaZfCu>$G?91_ND(cr{ke#6QRt+ zxJqh^itgTVIcMJOt{i?I4CJy~?T;TddFSW$ImQ!Le#{N~;{Hg%w%rj(^){Y+e`3H9 zTzq)u@>2EbL?Hd3spCs1l?Z0~Tf=MR2fDMV=&AFcTa(?n#hCBv@7kW#Y`U-c;y&>!CvSwpt@}Bttx69*vb-3-;Ki8A$y8r+H diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png b/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png deleted file mode 100644 index 170841cba2fe51c604a6ed63d9fa119dc4f7a73a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4143 zcmV+~5YX?5P)+#sK+(JQRJ~A(_5>{!ukUR)i7jcSrf7+9fQH~lRI)qc5p5fP$Ioc!An4H= z%NP;FPmORvKp_F;eH0~_u{d=%(&6=qp`vB+dUNkoR;dv6{jpm2FGdQS-0 zkO&rONv#g|hQn2{-!^;ciBCQB9slSPO+jRcXo>jL0JAkU5cK~*ks!JHB>=hUsIVu z@+1V0SNEtlMF>cW{vad@AXRu0nPW;db+}bjtJqPs>v?)C4#Qs8F&IA$Z-(P{g$;9Ny5>td)kU%{Fb^%WKTZ z15Z?_+}qS)!L0;i3^lzm3d>ZbJ{N-Ss$( z+x^uK8s%jhxBjwPq&t&90$kHE*DBE2Gn&Bxm;@wjkEuv@;;MU=AP%L9IB%;0F*7Bx zFlJ&sPP+ASMApy)4Ldd+YH%wXs&;hgIwO(eY-P;5X5N*?dR_5%&*)Ci7t2Ex@MASb zTLRgQ*2{b@w{t$)VHLX_2DjJY%{8(v@uG;98mW#$SrJIU2$1H!pa;>ZLMTbYf<2Fu zB(cc%27Jbh7;p0#+T{I7qm8_yq7FTdN)?+`IzbAlNa{h4MvLg{AmMN&K=Ve>J;y2t ztYM~*)Mmv{CuV}aPDKcLMkkA$1kMA7<|bF13GPTg~!z4!Bb zX1+c1@An;Ro$XxRz08_fv-V*=`#ZCq2j|1_J`PtnEWQoEcSXy)w9bztz|-v+PkNCjeJz*q(RKdoL%ctZ zz+l0|ND#{c!n}hRSQb7FC~yD+kpbKNKFlEu3XV`Hx%<69Y*zy@9x((nUxy@$T=m)4 zM--niy+iQaL645-de886?YIk>a#rJ`8xmNATa~Wu*VY&bUipD zJH(RF^MoD7O)}q?C_zk*#5h4juRiXFKI`4!-+#wlkv|6rRSV{L>1;Cp9CM%zJv`719nfKvfcm6XKwS zfdC;w>}Ugz!~NBii8%?7KfVkCbSUtCQ6cXnXGsBZ0E_}rDMUDmMBs649VD^XRu-)w zN7}u)4CD_xh!q5ns0a}V3j%3VMcI%5ha2t9%AA}zI<}SZO2)FOa>#)ro9jBBALs8o zNWEN3xe--^#8-UXk9; z-q65QJ?CRu>tGx5R80Decmxd+EUhIO$$6^QQU`Dp+)eJgL7+gckMp+#!P-oWP|>ai za@ebQNmC?pZ!I>OmMD3W@In~N|DZ7)bc89;%UBGF*uut<-GXiKqzyyrPVGO3l(vHt4Z;*4ZH@(PYp!$9P@F)Xz3GY1L^=4L3CQY%ma0T z=d={_yupP91Wi_u%oWVdVncvPv{-&0evr%jiGx7VK!BzOU#)DV0_DJ?-zCWTB?Sd8 z{A33Kw0nMg*+IH0sZ7{?%{$1CJBV8qSQ!Fo0hT^hWVb-5eBvaTZwrWaAn9|0v$Y1l zvN%j=GDIXanet|SkRV+PLTM>eP|cT0yWuQ3;X$ZIX~f8LS3@+z!I$6$w%UC>m zn-QdP2}ETAVjz^TYrHxTOL ziqJ=nDnx-)Li0YE5^e{fgAy!Y3ABMgW#EKC8+Lt9|1-Zr5Ecr>teF@~Yh^`|CP;xL zN}2%>hWR=x#tJbOW$Zj4;i-;Mi^T=<xt#ti9DjI?jq=1;`f-MB(=Y@zK^f z>RAPPOC`VpSw>Yc7F&M!7e|03@D9~gB9d0?y{E6{7aWA`!CT$tT9v2@F8#2qOW%*=cG@A)|c*)>p%cj-a@ zR#ld^;;gXPk!p~71)|rNqX7A=gK*Thzxx&m-;?`km4=Q#&+ zhrxrsnx7#EA;zWz_p#(cyaI(sgvGl+3YM*a_1jJYBpqQ1^MF_L(**JK%o&NA##tyK z8Ukl(n~cnHj94t)3Al9OAPC~D3F+RPdrcSv`ILkFuXZy~jUooZ@JxFaM1&$#1QA38 zK?DIr5CIWH5D^6N-F*bTs(k_z_x3XRI{UK$Yp-lJlT0!*UuLqUK#9^W=K?4wKnXp8 zLKI6C#GoN^$x<#a)=+T9Xac$LuYmM8w7iUCMos~zv6L1uirhE^XdxGX0I*(K7yd;+ zfFMf*2vi3yOcCce_$6)ax!q(eox7skBJuuva)MIgR9j zPqp(qfowLA_cKU}kVy3dV5R{vsjLJlN~RUGhz>{a2FwidPChOc6uDLdXH~b^_Vyoq(#fZHzS#?hu5Uxdftsz_1;doDi>&8d>WgZzhnP?8*7e zo`T^4b_GNafN=;JO2(Xg(DJ!VdO%)JATz)+WV0L$VqC?r(!fm^c&oItRufxH9+-|6I5f{To zL8QgJxFkE*)qqG0s;8BGzp3Y&VvS+`DdxM@=IY}A5|_<9_QpzVp&2%>l~M8%B$0cM zzgDfbAWPqPWJms-jP#_@QCg;{N@BV{j$+*8E+Wz*JUpQ38S!U;^n>7qKM*sP>JhPP z8Uvy_BexSBNPCbcJCMX`NZAtvJajrh6nX(% zF|6E(70sq@{qY{8m3FE9W^?1z(7+Mu5y<$UBECbg%nJe0aG7C=PzuR~(i9+fQcNf#jJes2Q7UNuir%@CMnz6%a)W)%XY z!GVnXoWC2k^}7=Y%2M6PPIAPIn6ib|g#szf2v|NX$&i`~kRN^r5cD|9vN%9q-=N^g z^sC0lCILBJfT;XG8sr1{0Oa-zf=cLf0ubnAks4uiRikPIq#5K^0}+&i%vAHM*?~eZ z8pusR`n-crHxOm*2yMJ$>`W;FWa}pZBAJwZ2qWz{ICIA1ZDU_qcVgfD_`*(cA`And t>uB}5*8g_@W@q+?3O)eH;oGro{{qbcPck5Ql{)|c002ovPDHLkV1nX9d?Nq= diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/js/bootstrap-colorpicker.js b/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/js/bootstrap-colorpicker.js deleted file mode 100644 index 758ebc381..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/bootstrap-colorpicker/js/bootstrap-colorpicker.js +++ /dev/null @@ -1,1106 +0,0 @@ -/*! - * Bootstrap Colorpicker v2.3.3 - * http://mjolnic.github.io/bootstrap-colorpicker/ - * - * Originally written by (c) 2012 Stefan Petre - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0.txt - * - */ - -(function(factory) { - "use strict"; - if (typeof exports === 'object') { - module.exports = factory(window.jQuery); - } else if (typeof define === 'function' && define.amd) { - define(['jquery'], factory); - } else if (window.jQuery && !window.jQuery.fn.colorpicker) { - factory(window.jQuery); - } -}(function($) { - 'use strict'; - - /** - * Color manipulation helper class - * - * @param {Object|String} val - * @param {Object} predefinedColors - * @constructor - */ - var Color = function(val, predefinedColors) { - this.value = { - h: 0, - s: 0, - b: 0, - a: 1 - }; - this.origFormat = null; // original string format - if (predefinedColors) { - $.extend(this.colors, predefinedColors); - } - if (val) { - if (val.toLowerCase !== undefined) { - // cast to string - val = val + ''; - this.setColor(val); - } else if (val.h !== undefined) { - this.value = val; - } - } - }; - - Color.prototype = { - constructor: Color, - // 140 predefined colors from the HTML Colors spec - colors: { - "aliceblue": "#f0f8ff", - "antiquewhite": "#faebd7", - "aqua": "#00ffff", - "aquamarine": "#7fffd4", - "azure": "#f0ffff", - "beige": "#f5f5dc", - "bisque": "#ffe4c4", - "black": "#000000", - "blanchedalmond": "#ffebcd", - "blue": "#0000ff", - "blueviolet": "#8a2be2", - "brown": "#a52a2a", - "burlywood": "#deb887", - "cadetblue": "#5f9ea0", - "chartreuse": "#7fff00", - "chocolate": "#d2691e", - "coral": "#ff7f50", - "cornflowerblue": "#6495ed", - "cornsilk": "#fff8dc", - "crimson": "#dc143c", - "cyan": "#00ffff", - "darkblue": "#00008b", - "darkcyan": "#008b8b", - "darkgoldenrod": "#b8860b", - "darkgray": "#a9a9a9", - "darkgreen": "#006400", - "darkkhaki": "#bdb76b", - "darkmagenta": "#8b008b", - "darkolivegreen": "#556b2f", - "darkorange": "#ff8c00", - "darkorchid": "#9932cc", - "darkred": "#8b0000", - "darksalmon": "#e9967a", - "darkseagreen": "#8fbc8f", - "darkslateblue": "#483d8b", - "darkslategray": "#2f4f4f", - "darkturquoise": "#00ced1", - "darkviolet": "#9400d3", - "deeppink": "#ff1493", - "deepskyblue": "#00bfff", - "dimgray": "#696969", - "dodgerblue": "#1e90ff", - "firebrick": "#b22222", - "floralwhite": "#fffaf0", - "forestgreen": "#228b22", - "fuchsia": "#ff00ff", - "gainsboro": "#dcdcdc", - "ghostwhite": "#f8f8ff", - "gold": "#ffd700", - "goldenrod": "#daa520", - "gray": "#808080", - "green": "#008000", - "greenyellow": "#adff2f", - "honeydew": "#f0fff0", - "hotpink": "#ff69b4", - "indianred": "#cd5c5c", - "indigo": "#4b0082", - "ivory": "#fffff0", - "khaki": "#f0e68c", - "lavender": "#e6e6fa", - "lavenderblush": "#fff0f5", - "lawngreen": "#7cfc00", - "lemonchiffon": "#fffacd", - "lightblue": "#add8e6", - "lightcoral": "#f08080", - "lightcyan": "#e0ffff", - "lightgoldenrodyellow": "#fafad2", - "lightgrey": "#d3d3d3", - "lightgreen": "#90ee90", - "lightpink": "#ffb6c1", - "lightsalmon": "#ffa07a", - "lightseagreen": "#20b2aa", - "lightskyblue": "#87cefa", - "lightslategray": "#778899", - "lightsteelblue": "#b0c4de", - "lightyellow": "#ffffe0", - "lime": "#00ff00", - "limegreen": "#32cd32", - "linen": "#faf0e6", - "magenta": "#ff00ff", - "maroon": "#800000", - "mediumaquamarine": "#66cdaa", - "mediumblue": "#0000cd", - "mediumorchid": "#ba55d3", - "mediumpurple": "#9370d8", - "mediumseagreen": "#3cb371", - "mediumslateblue": "#7b68ee", - "mediumspringgreen": "#00fa9a", - "mediumturquoise": "#48d1cc", - "mediumvioletred": "#c71585", - "midnightblue": "#191970", - "mintcream": "#f5fffa", - "mistyrose": "#ffe4e1", - "moccasin": "#ffe4b5", - "navajowhite": "#ffdead", - "navy": "#000080", - "oldlace": "#fdf5e6", - "olive": "#808000", - "olivedrab": "#6b8e23", - "orange": "#ffa500", - "orangered": "#ff4500", - "orchid": "#da70d6", - "palegoldenrod": "#eee8aa", - "palegreen": "#98fb98", - "paleturquoise": "#afeeee", - "palevioletred": "#d87093", - "papayawhip": "#ffefd5", - "peachpuff": "#ffdab9", - "peru": "#cd853f", - "pink": "#ffc0cb", - "plum": "#dda0dd", - "powderblue": "#b0e0e6", - "purple": "#800080", - "red": "#ff0000", - "rosybrown": "#bc8f8f", - "royalblue": "#4169e1", - "saddlebrown": "#8b4513", - "salmon": "#fa8072", - "sandybrown": "#f4a460", - "seagreen": "#2e8b57", - "seashell": "#fff5ee", - "sienna": "#a0522d", - "silver": "#c0c0c0", - "skyblue": "#87ceeb", - "slateblue": "#6a5acd", - "slategray": "#708090", - "snow": "#fffafa", - "springgreen": "#00ff7f", - "steelblue": "#4682b4", - "tan": "#d2b48c", - "teal": "#008080", - "thistle": "#d8bfd8", - "tomato": "#ff6347", - "turquoise": "#40e0d0", - "violet": "#ee82ee", - "wheat": "#f5deb3", - "white": "#ffffff", - "whitesmoke": "#f5f5f5", - "yellow": "#ffff00", - "yellowgreen": "#9acd32", - "transparent": "transparent" - }, - _sanitizeNumber: function(val) { - if (typeof val === 'number') { - return val; - } - if (isNaN(val) || (val === null) || (val === '') || (val === undefined)) { - return 1; - } - if (val === '') { - return 0; - } - if (val.toLowerCase !== undefined) { - if (val.match(/^\./)) { - val = "0" + val; - } - return Math.ceil(parseFloat(val) * 100) / 100; - } - return 1; - }, - isTransparent: function(strVal) { - if (!strVal) { - return false; - } - strVal = strVal.toLowerCase().trim(); - return (strVal === 'transparent') || (strVal.match(/#?00000000/)) || (strVal.match(/(rgba|hsla)\(0,0,0,0?\.?0\)/)); - }, - rgbaIsTransparent: function(rgba) { - return ((rgba.r === 0) && (rgba.g === 0) && (rgba.b === 0) && (rgba.a === 0)); - }, - //parse a string to HSB - setColor: function(strVal) { - strVal = strVal.toLowerCase().trim(); - if (strVal) { - if (this.isTransparent(strVal)) { - this.value = { - h: 0, - s: 0, - b: 0, - a: 0 - }; - } else { - this.value = this.stringToHSB(strVal) || { - h: 0, - s: 0, - b: 0, - a: 1 - }; // if parser fails, defaults to black - } - } - }, - stringToHSB: function(strVal) { - strVal = strVal.toLowerCase(); - var alias; - if (typeof this.colors[strVal] !== 'undefined') { - strVal = this.colors[strVal]; - alias = 'alias'; - } - var that = this, - result = false; - $.each(this.stringParsers, function(i, parser) { - var match = parser.re.exec(strVal), - values = match && parser.parse.apply(that, [match]), - format = alias || parser.format || 'rgba'; - if (values) { - if (format.match(/hsla?/)) { - result = that.RGBtoHSB.apply(that, that.HSLtoRGB.apply(that, values)); - } else { - result = that.RGBtoHSB.apply(that, values); - } - that.origFormat = format; - return false; - } - return true; - }); - return result; - }, - setHue: function(h) { - this.value.h = 1 - h; - }, - setSaturation: function(s) { - this.value.s = s; - }, - setBrightness: function(b) { - this.value.b = 1 - b; - }, - setAlpha: function(a) { - this.value.a = Math.round((parseInt((1 - a) * 100, 10) / 100) * 100) / 100; - }, - toRGB: function(h, s, b, a) { - if (!h) { - h = this.value.h; - s = this.value.s; - b = this.value.b; - } - h *= 360; - var R, G, B, X, C; - h = (h % 360) / 60; - C = b * s; - X = C * (1 - Math.abs(h % 2 - 1)); - R = G = B = b - C; - - h = ~~h; - R += [C, X, 0, 0, X, C][h]; - G += [X, C, C, X, 0, 0][h]; - B += [0, 0, X, C, C, X][h]; - return { - r: Math.round(R * 255), - g: Math.round(G * 255), - b: Math.round(B * 255), - a: a || this.value.a - }; - }, - toHex: function(h, s, b, a) { - var rgb = this.toRGB(h, s, b, a); - if (this.rgbaIsTransparent(rgb)) { - return 'transparent'; - } - return '#' + ((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1); - }, - toHSL: function(h, s, b, a) { - h = h || this.value.h; - s = s || this.value.s; - b = b || this.value.b; - a = a || this.value.a; - - var H = h, - L = (2 - s) * b, - S = s * b; - if (L > 0 && L <= 1) { - S /= L; - } else { - S /= 2 - L; - } - L /= 2; - if (S > 1) { - S = 1; - } - return { - h: isNaN(H) ? 0 : H, - s: isNaN(S) ? 0 : S, - l: isNaN(L) ? 0 : L, - a: isNaN(a) ? 0 : a - }; - }, - toAlias: function(r, g, b, a) { - var rgb = this.toHex(r, g, b, a); - for (var alias in this.colors) { - if (this.colors[alias] === rgb) { - return alias; - } - } - return false; - }, - RGBtoHSB: function(r, g, b, a) { - r /= 255; - g /= 255; - b /= 255; - - var H, S, V, C; - V = Math.max(r, g, b); - C = V - Math.min(r, g, b); - H = (C === 0 ? null : - V === r ? (g - b) / C : - V === g ? (b - r) / C + 2 : - (r - g) / C + 4 - ); - H = ((H + 360) % 6) * 60 / 360; - S = C === 0 ? 0 : C / V; - return { - h: this._sanitizeNumber(H), - s: S, - b: V, - a: this._sanitizeNumber(a) - }; - }, - HueToRGB: function(p, q, h) { - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - if ((h * 6) < 1) { - return p + (q - p) * h * 6; - } else if ((h * 2) < 1) { - return q; - } else if ((h * 3) < 2) { - return p + (q - p) * ((2 / 3) - h) * 6; - } else { - return p; - } - }, - HSLtoRGB: function(h, s, l, a) { - if (s < 0) { - s = 0; - } - var q; - if (l <= 0.5) { - q = l * (1 + s); - } else { - q = l + s - (l * s); - } - - var p = 2 * l - q; - - var tr = h + (1 / 3); - var tg = h; - var tb = h - (1 / 3); - - var r = Math.round(this.HueToRGB(p, q, tr) * 255); - var g = Math.round(this.HueToRGB(p, q, tg) * 255); - var b = Math.round(this.HueToRGB(p, q, tb) * 255); - return [r, g, b, this._sanitizeNumber(a)]; - }, - toString: function(format) { - format = format || 'rgba'; - var c = false; - switch (format) { - case 'rgb': - { - c = this.toRGB(); - if (this.rgbaIsTransparent(c)) { - return 'transparent'; - } - return 'rgb(' + c.r + ',' + c.g + ',' + c.b + ')'; - } - break; - case 'rgba': - { - c = this.toRGB(); - return 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + c.a + ')'; - } - break; - case 'hsl': - { - c = this.toHSL(); - return 'hsl(' + Math.round(c.h * 360) + ',' + Math.round(c.s * 100) + '%,' + Math.round(c.l * 100) + '%)'; - } - break; - case 'hsla': - { - c = this.toHSL(); - return 'hsla(' + Math.round(c.h * 360) + ',' + Math.round(c.s * 100) + '%,' + Math.round(c.l * 100) + '%,' + c.a + ')'; - } - break; - case 'hex': - { - return this.toHex(); - } - break; - case 'alias': - return this.toAlias() || this.toHex(); - default: - { - return c; - } - break; - } - }, - // a set of RE's that can match strings and generate color tuples. - // from John Resig color plugin - // https://github.com/jquery/jquery-color/ - stringParsers: [{ - re: /rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/, - format: 'rgb', - parse: function(execResult) { - return [ - execResult[1], - execResult[2], - execResult[3], - 1 - ]; - } - }, { - re: /rgb\(\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*?\)/, - format: 'rgb', - parse: function(execResult) { - return [ - 2.55 * execResult[1], - 2.55 * execResult[2], - 2.55 * execResult[3], - 1 - ]; - } - }, { - re: /rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/, - format: 'rgba', - parse: function(execResult) { - return [ - execResult[1], - execResult[2], - execResult[3], - execResult[4] - ]; - } - }, { - re: /rgba\(\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/, - format: 'rgba', - parse: function(execResult) { - return [ - 2.55 * execResult[1], - 2.55 * execResult[2], - 2.55 * execResult[3], - execResult[4] - ]; - } - }, { - re: /hsl\(\s*(\d*(?:\.\d+)?)\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*?\)/, - format: 'hsl', - parse: function(execResult) { - return [ - execResult[1] / 360, - execResult[2] / 100, - execResult[3] / 100, - execResult[4] - ]; - } - }, { - re: /hsla\(\s*(\d*(?:\.\d+)?)\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/, - format: 'hsla', - parse: function(execResult) { - return [ - execResult[1] / 360, - execResult[2] / 100, - execResult[3] / 100, - execResult[4] - ]; - } - }, { - re: /#?([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/, - format: 'hex', - parse: function(execResult) { - return [ - parseInt(execResult[1], 16), - parseInt(execResult[2], 16), - parseInt(execResult[3], 16), - 1 - ]; - } - }, { - re: /#?([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/, - format: 'hex', - parse: function(execResult) { - return [ - parseInt(execResult[1] + execResult[1], 16), - parseInt(execResult[2] + execResult[2], 16), - parseInt(execResult[3] + execResult[3], 16), - 1 - ]; - } - }], - colorNameToHex: function(name) { - if (typeof this.colors[name.toLowerCase()] !== 'undefined') { - return this.colors[name.toLowerCase()]; - } - return false; - } - }; - - /* - * Default plugin options - */ - var defaults = { - horizontal: false, // horizontal mode layout ? - inline: false, //forces to show the colorpicker as an inline element - color: false, //forces a color - format: false, //forces a format - input: 'input', // children input selector - container: false, // container selector - component: '.add-on, .input-group-addon', // children component selector - sliders: { - saturation: { - maxLeft: 100, - maxTop: 100, - callLeft: 'setSaturation', - callTop: 'setBrightness' - }, - hue: { - maxLeft: 0, - maxTop: 100, - callLeft: false, - callTop: 'setHue' - }, - alpha: { - maxLeft: 0, - maxTop: 100, - callLeft: false, - callTop: 'setAlpha' - } - }, - slidersHorz: { - saturation: { - maxLeft: 100, - maxTop: 100, - callLeft: 'setSaturation', - callTop: 'setBrightness' - }, - hue: { - maxLeft: 100, - maxTop: 0, - callLeft: 'setHue', - callTop: false - }, - alpha: { - maxLeft: 100, - maxTop: 0, - callLeft: 'setAlpha', - callTop: false - } - }, - template: '
    '+this.renderBgTrHtml(t)+'

    '+(this.getIsNumbersVisible()?""+this.renderNumberTrHtml(t)+"":"")+"
    "},e.prototype.getIsNumbersVisible=function(){return this.getIsDayNumbersVisible()||this.cellWeekNumbersVisible},e.prototype.getIsDayNumbersVisible=function(){return this.rowCnt>1},e.prototype.renderNumberTrHtml=function(t){return""+(this.isRTL?"":this.renderNumberIntroHtml(t))+this.renderNumberCellsHtml(t)+(this.isRTL?this.renderNumberIntroHtml(t):"")+""},e.prototype.renderNumberIntroHtml=function(t){return this.renderIntroHtml()},e.prototype.renderNumberCellsHtml=function(t){var e,n,i=[];for(e=0;e",this.cellWeekNumbersVisible&&t.day()===n&&(r+=i.buildGotoAnchorHtml({date:t,type:"week"},{class:"fc-week-number"},t.format("w"))),s&&(r+=i.buildGotoAnchorHtml(t,{class:"fc-day-number"},t.format("D"))),r+=""):""},e.prototype.prepareHits=function(){this.colCoordCache.build(),this.rowCoordCache.build(),this.rowCoordCache.bottoms[this.rowCnt-1]+=this.bottomCoordPadding},e.prototype.releaseHits=function(){this.colCoordCache.clear(),this.rowCoordCache.clear()},e.prototype.queryHit=function(t,e){if(this.colCoordCache.isLeftInBounds(t)&&this.rowCoordCache.isTopInBounds(e)){var n=this.colCoordCache.getHorizontalIndex(t),i=this.rowCoordCache.getVerticalIndex(e);if(null!=i&&null!=n)return this.getCellHit(i,n)}},e.prototype.getHitFootprint=function(t){var e=this.getCellRange(t.row,t.col);return new u.default(new l.default(e.start,e.end),!0)},e.prototype.getHitEl=function(t){return this.getCellEl(t.row,t.col)},e.prototype.getCellHit=function(t,e){return{row:t,col:e,component:this,left:this.colCoordCache.getLeftOffset(e),right:this.colCoordCache.getRightOffset(e),top:this.rowCoordCache.getTopOffset(t),bottom:this.rowCoordCache.getBottomOffset(t)}},e.prototype.getCellEl=function(t,e){return this.cellEls.eq(t*this.colCnt+e)},e.prototype.executeEventUnrender=function(){this.removeSegPopover(),t.prototype.executeEventUnrender.call(this)},e.prototype.getOwnEventSegs=function(){ -return t.prototype.getOwnEventSegs.call(this).concat(this.popoverSegs||[])},e.prototype.renderDrag=function(t,e,n){var i;for(i=0;i td > :first-child").each(e),i.position().top+o>a)return n;return!1},e.prototype.limitRow=function(t,e){var n,i,o,s,a,l,u,d,c,p,h,f,g,v,y,m=this,b=this.eventRenderer.rowStructs[t],w=[],D=0,E=function(n){for(;D").append(y),c.append(v),w.push(v[0])),D++};if(e&&e').attr("rowspan",p),l=d[f],y=this.renderMoreLink(t,a.leftCol+f,[a].concat(l)),v=r("
    ").append(y),g.append(v),h.push(g[0]),w.push(g[0]);c.addClass("fc-limited").after(r(h)),o.push(c[0])}}E(this.colCnt),b.moreEls=r(w),b.limitedEls=r(o)}},e.prototype.unlimitRow=function(t){var e=this.eventRenderer.rowStructs[t];e.moreEls&&(e.moreEls.remove(),e.moreEls=null),e.limitedEls&&(e.limitedEls.removeClass("fc-limited"),e.limitedEls=null)},e.prototype.renderMoreLink=function(t,e,n){var i=this,o=this.view;return r('').text(this.getMoreLinkText(n.length)).on("click",function(s){var a=i.opt("eventLimitClick"),l=i.getCellDate(t,e),u=r(s.currentTarget),d=i.getCellEl(t,e),c=i.getCellSegs(t,e),p=i.resliceDaySegs(c,l),h=i.resliceDaySegs(n,l);"function"==typeof a&&(a=i.publiclyTrigger("eventLimitClick",{context:o,args:[{date:l.clone(),dayEl:d,moreEl:u,segs:p,hiddenSegs:h},s,o]})),"popover"===a?i.showSegPopover(t,e,u,p):"string"==typeof a&&o.calendar.zoomTo(l,a)})},e.prototype.showSegPopover=function(t,e,n,i){var r,o,s=this,l=this.view,u=n.parent();r=1===this.rowCnt?l.el:this.rowEls.eq(t),o={className:"fc-more-popover "+l.calendar.theme.getClass("popover"),content:this.renderSegPopoverContent(t,e,i),parentEl:l.el,top:r.offset().top,autoHide:!0,viewportConstrain:this.opt("popoverViewportConstrain"),hide:function(){s.popoverSegs&&s.triggerBeforeEventSegsDestroyed(s.popoverSegs),s.segPopover.removeElement(),s.segPopover=null,s.popoverSegs=null}},this.isRTL?o.right=u.offset().left+u.outerWidth()+1:o.left=u.offset().left-1,this.segPopover=new a.default(o),this.segPopover.show(),this.bindAllSegHandlersToEl(this.segPopover.el),this.triggerAfterEventSegsRendered(i)},e.prototype.renderSegPopoverContent=function(t,e,n){var i,s=this.view,a=s.calendar.theme,l=this.getCellDate(t,e).format(this.opt("dayPopoverFormat")),u=r('
    '+o.htmlEscape(l)+'
    '),d=u.find(".fc-event-container");for(n=this.eventRenderer.renderFgSegEls(n,!0),this.popoverSegs=n,i=0;i"+s.htmlEscape(this.opt("weekNumberTitle"))+"":""},e.prototype.renderNumberIntroHtml=function(t){var e=this.view,n=this.getCellDate(t,0);return this.colWeekNumbersVisible?'"+e.buildGotoAnchorHtml({date:n,type:"week",forceOff:1===this.colCnt},n.format("w"))+"":""},e.prototype.renderBgIntroHtml=function(){var t=this.view;return this.colWeekNumbersVisible?'":""},e.prototype.renderIntroHtml=function(){var t=this.view;return this.colWeekNumbersVisible?'":""},e.prototype.getIsNumbersVisible=function(){return d.default.prototype.getIsNumbersVisible.apply(this,arguments)||this.colWeekNumbersVisible},e}(t)}Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=n(3),s=n(4),a=n(39),l=n(41),u=n(228),d=n(61),c=function(t){function e(e,n){var i=t.call(this,e,n)||this;return i.dayGrid=i.instantiateDayGrid(),i.dayGrid.isRigid=i.hasRigidRows(),i.opt("weekNumbers")&&(i.opt("weekNumbersWithinDays")?(i.dayGrid.cellWeekNumbersVisible=!0,i.dayGrid.colWeekNumbersVisible=!1):(i.dayGrid.cellWeekNumbersVisible=!1,i.dayGrid.colWeekNumbersVisible=!0)),i.addChild(i.dayGrid),i.scroller=new a.default({overflowX:"hidden",overflowY:"auto"}),i}return r.__extends(e,t),e.prototype.instantiateDayGrid=function(){return new(i(this.dayGridClass))(this)},e.prototype.executeDateRender=function(e){this.dayGrid.breakOnWeeks=/year|month|week/.test(e.currentRangeUnit),t.prototype.executeDateRender.call(this,e)},e.prototype.renderSkeleton=function(){var t,e;this.el.addClass("fc-basic-view").html(this.renderSkeletonHtml()),this.scroller.render(),t=this.scroller.el.addClass("fc-day-grid-container"),e=o('
    ').appendTo(t),this.el.find(".fc-body > tr > td").append(t),this.dayGrid.headContainerEl=this.el.find(".fc-head-container"),this.dayGrid.setElement(e)},e.prototype.unrenderSkeleton=function(){this.dayGrid.removeElement(),this.scroller.destroy()},e.prototype.renderSkeletonHtml=function(){var t=this.calendar.theme;return''+(this.opt("columnHeader")?'':"")+'
     
    '},e.prototype.weekNumberStyleAttr=function(){return null!=this.weekNumberWidth?'style="width:'+this.weekNumberWidth+'px"':""},e.prototype.hasRigidRows=function(){var t=this.opt("eventLimit");return t&&"number"!=typeof t},e.prototype.updateSize=function(e,n,i){var r,o,a=this.opt("eventLimit"),l=this.dayGrid.headContainerEl.find(".fc-row");if(!this.dayGrid.rowEls)return void(n||(r=this.computeScrollerHeight(e),this.scroller.setHeight(r)));t.prototype.updateSize.call(this,e,n,i),this.dayGrid.colWeekNumbersVisible&&(this.weekNumberWidth=s.matchCellWidths(this.el.find(".fc-week-number"))),this.scroller.clear(),s.uncompensateScroll(l),this.dayGrid.removeSegPopover(),a&&"number"==typeof a&&this.dayGrid.limitRows(a),r=this.computeScrollerHeight(e),this.setGridHeight(r,n),a&&"number"!=typeof a&&this.dayGrid.limitRows(a),n||(this.scroller.setHeight(r),o=this.scroller.getScrollbarWidths(),(o.left||o.right)&&(s.compensateScroll(l,o),r=this.computeScrollerHeight(e),this.scroller.setHeight(r)),this.scroller.lockOverflow(o))},e.prototype.computeScrollerHeight=function(t){return t-s.subtractInnerElHeight(this.el,this.scroller.el)},e.prototype.setGridHeight=function(t,e){e?s.undistributeHeight(this.dayGrid.rowEls):s.distributeHeight(this.dayGrid.rowEls,t,!0)},e.prototype.computeInitialDateScroll=function(){return{top:0}},e.prototype.queryDateScroll=function(){return{top:this.scroller.getScrollTop()}},e.prototype.applyDateScroll=function(t){void 0!==t.top&&this.scroller.setScrollTop(t.top)},e}(l.default);e.default=c,c.prototype.dateProfileGeneratorClass=u.default,c.prototype.dayGridClass=d.default},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(t,e,n){function i(t,e,n){var i;for(i=0;i=0;e--)switch(n=i[e],n.type){case"init":r=!1;case"add":case"remove":i.splice(e,1)}return r&&i.push(t),r},e}(r.default);e.default=o},function(t,e,n){function i(t){var e,n,i,r=[];for(e in t)for(n=t[e].eventInstances,i=0;i'+n+"
    ":""+n+""},e.prototype.getAllDayHtml=function(){return this.opt("allDayHtml")||a.htmlEscape(this.opt("allDayText"))},e.prototype.getDayClasses=function(t,e){var n,i=this._getView(),r=[] -;return this.dateProfile.activeUnzonedRange.containsDate(t)?(r.push("fc-"+a.dayIDs[t.day()]),i.isDateInOtherMonth(t,this.dateProfile)&&r.push("fc-other-month"),n=i.calendar.getNow(),t.isSame(n,"day")?(r.push("fc-today"),!0!==e&&r.push(i.calendar.theme.getClass("today"))):t=this.nextDayThreshold&&o.add(1,"days"),o<=n&&(o=n.clone().add(1,"days")),{start:n,end:o}},e.prototype.isMultiDayRange=function(t){var e=this.computeDayRange(t);return e.end.diff(e.start,"days")>1},e.guid=0,e}(d.default);e.default=p},function(t,e,n){function i(t,e){return null==e?t:r.isFunction(e)?t.filter(e):(e+="",t.filter(function(t){return t.id==e||t._id===e}))}Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),o=n(0),s=n(4),a=n(32),l=n(238),u=n(21),d=n(11),c=n(7),p=n(239),h=n(240),f=n(241),g=n(207),v=n(31),y=n(10),m=n(5),b=n(12),w=n(17),D=n(242),E=n(212),S=n(38),C=n(49),R=n(13),T=n(37),M=n(6),I=n(51),H=function(){function t(t,e){this.loadingLevel=0,this.ignoreUpdateViewSize=0,this.freezeContentHeightDepth=0,u.default.needed(),this.el=t,this.viewsByType={},this.optionsManager=new h.default(this,e),this.viewSpecManager=new f.default(this.optionsManager,this),this.initMomentInternals(),this.initCurrentDate(),this.initEventManager(),this.constraints=new g.default(this.eventManager,this),this.constructed()}return t.prototype.constructed=function(){},t.prototype.getView=function(){return this.view},t.prototype.publiclyTrigger=function(t,e){var n,i,o=this.opt(t);if(r.isPlainObject(e)?(n=e.context,i=e.args):r.isArray(e)&&(i=e),null==n&&(n=this.el[0]),i||(i=[]),this.triggerWith(t,n,i),o)return o.apply(n,i)},t.prototype.hasPublicHandlers=function(t){return this.hasHandlers(t)||this.opt(t)},t.prototype.option=function(t,e){var n;if("string"==typeof t){if(void 0===e)return this.optionsManager.get(t);n={},n[t]=e,this.optionsManager.add(n)}else"object"==typeof t&&this.optionsManager.add(t)},t.prototype.opt=function(t){return this.optionsManager.get(t)},t.prototype.instantiateView=function(t){var e=this.viewSpecManager.getViewSpec(t);if(!e)throw new Error('View type "'+t+'" is not valid');return new e.class(this,e)},t.prototype.isValidViewType=function(t){return Boolean(this.viewSpecManager.getViewSpec(t))},t.prototype.changeView=function(t,e){e&&(e.start&&e.end?this.optionsManager.recordOverrides({visibleRange:e}):this.currentDate=this.moment(e).stripZone()),this.renderView(t)},t.prototype.zoomTo=function(t,e){var n;e=e||"day",n=this.viewSpecManager.getViewSpec(e)||this.viewSpecManager.getUnitViewSpec(e),this.currentDate=t.clone(),this.renderView(n?n.type:null)},t.prototype.initCurrentDate=function(){var t=this.opt("defaultDate");this.currentDate=null!=t?this.moment(t).stripZone():this.getNow()},t.prototype.prev=function(){var t=this.view,e=t.dateProfileGenerator.buildPrev(t.get("dateProfile"));e.isValid&&(this.currentDate=e.date,this.renderView())},t.prototype.next=function(){var t=this.view,e=t.dateProfileGenerator.buildNext(t.get("dateProfile"));e.isValid&&(this.currentDate=e.date,this.renderView())},t.prototype.prevYear=function(){this.currentDate.add(-1,"years"),this.renderView()},t.prototype.nextYear=function(){this.currentDate.add(1,"years"),this.renderView()},t.prototype.today=function(){this.currentDate=this.getNow(),this.renderView()},t.prototype.gotoDate=function(t){this.currentDate=this.moment(t).stripZone(),this.renderView()},t.prototype.incrementDate=function(t){this.currentDate.add(o.duration(t)),this.renderView()},t.prototype.getDate=function(){return this.applyTimezone(this.currentDate)},t.prototype.pushLoading=function(){this.loadingLevel++||this.publiclyTrigger("loading",[!0,this.view])},t.prototype.popLoading=function(){--this.loadingLevel||this.publiclyTrigger("loading",[!1,this.view])},t.prototype.render=function(){this.contentEl?this.elementVisible()&&(this.calcSize(),this.updateViewSize()):this.initialRender()},t.prototype.initialRender=function(){var t=this,e=this.el;e.addClass("fc"),e.on("click.fc","a[data-goto]",function(e){var n=r(e.currentTarget),i=n.data("goto"),o=t.moment(i.date),a=i.type,l=t.view.opt("navLink"+s.capitaliseFirstLetter(a)+"Click");"function"==typeof l?l(o,e):("string"==typeof l&&(a=l),t.zoomTo(o,a))}),this.optionsManager.watch("settingTheme",["?theme","?themeSystem"],function(n){var i=I.getThemeSystemClass(n.themeSystem||n.theme),r=new i(t.optionsManager),o=r.getClass("widget");t.theme=r,o&&e.addClass(o)},function(){var n=t.theme.getClass("widget");t.theme=null,n&&e.removeClass(n)}),this.optionsManager.watch("settingBusinessHourGenerator",["?businessHours"],function(e){t.businessHourGenerator=new E.default(e.businessHours,t),t.view&&t.view.set("businessHourGenerator",t.businessHourGenerator)},function(){t.businessHourGenerator=null}),this.optionsManager.watch("applyingDirClasses",["?isRTL","?locale"],function(t){e.toggleClass("fc-ltr",!t.isRTL),e.toggleClass("fc-rtl",t.isRTL)}),this.contentEl=r("
    ").prependTo(e),this.initToolbars(),this.renderHeader(),this.renderFooter(),this.renderView(this.opt("defaultView")),this.opt("handleWindowResize")&&r(window).resize(this.windowResizeProxy=s.debounce(this.windowResize.bind(this),this.opt("windowResizeDelay")))},t.prototype.destroy=function(){this.view&&this.clearView(),this.toolbarsManager.proxyCall("removeElement"),this.contentEl.remove(),this.el.removeClass("fc fc-ltr fc-rtl"),this.optionsManager.unwatch("settingTheme"),this.optionsManager.unwatch("settingBusinessHourGenerator"),this.el.off(".fc"),this.windowResizeProxy&&(r(window).unbind("resize",this.windowResizeProxy),this.windowResizeProxy=null),u.default.unneeded()},t.prototype.elementVisible=function(){return this.el.is(":visible")},t.prototype.bindViewHandlers=function(t){var e=this;t.watch("titleForCalendar",["title"],function(n){t===e.view&&e.setToolbarsTitle(n.title)}),t.watch("dateProfileForCalendar",["dateProfile"],function(n){t===e.view&&(e.currentDate=n.dateProfile.date,e.updateToolbarButtons(n.dateProfile))})},t.prototype.unbindViewHandlers=function(t){t.unwatch("titleForCalendar"),t.unwatch("dateProfileForCalendar")},t.prototype.renderView=function(t){var e,n=this.view;this.freezeContentHeight(),n&&t&&n.type!==t&&this.clearView(),!this.view&&t&&(e=this.view=this.viewsByType[t]||(this.viewsByType[t]=this.instantiateView(t)),this.bindViewHandlers(e),e.startBatchRender(),e.setElement(r("
    ").appendTo(this.contentEl)),this.toolbarsManager.proxyCall("activateButton",t)),this.view&&(this.view.get("businessHourGenerator")!==this.businessHourGenerator&&this.view.set("businessHourGenerator",this.businessHourGenerator),this.view.setDate(this.currentDate),e&&e.stopBatchRender()),this.thawContentHeight()},t.prototype.clearView=function(){var t=this.view;this.toolbarsManager.proxyCall("deactivateButton",t.type),this.unbindViewHandlers(t),t.removeElement(),t.unsetDate(),this.view=null},t.prototype.reinitView=function(){var t=this.view,e=t.queryScroll();this.freezeContentHeight(),this.clearView(),this.calcSize(),this.renderView(t.type),this.view.applyScroll(e),this.thawContentHeight()},t.prototype.getSuggestedViewHeight=function(){return null==this.suggestedViewHeight&&this.calcSize(),this.suggestedViewHeight},t.prototype.isHeightAuto=function(){return"auto"===this.opt("contentHeight")||"auto"===this.opt("height")},t.prototype.updateViewSize=function(t){void 0===t&&(t=!1);var e,n=this.view;if(!this.ignoreUpdateViewSize&&n)return t&&(this.calcSize(),e=n.queryScroll()),this.ignoreUpdateViewSize++,n.updateSize(this.getSuggestedViewHeight(),this.isHeightAuto(),t),this.ignoreUpdateViewSize--,t&&n.applyScroll(e),!0},t.prototype.calcSize=function(){this.elementVisible()&&this._calcSize()},t.prototype._calcSize=function(){var t=this.opt("contentHeight"),e=this.opt("height");this.suggestedViewHeight="number"==typeof t?t:"function"==typeof t?t():"number"==typeof e?e-this.queryToolbarsHeight():"function"==typeof e?e()-this.queryToolbarsHeight():"parent"===e?this.el.parent().height()-this.queryToolbarsHeight():Math.round(this.contentEl.width()/Math.max(this.opt("aspectRatio"),.5))},t.prototype.windowResize=function(t){t.target===window&&this.view&&this.view.isDatesRendered&&this.updateViewSize(!0)&&this.publiclyTrigger("windowResize",[this.view])},t.prototype.freezeContentHeight=function(){this.freezeContentHeightDepth++||this.forceFreezeContentHeight()},t.prototype.forceFreezeContentHeight=function(){this.contentEl.css({width:"100%",height:this.contentEl.height(),overflow:"hidden"})},t.prototype.thawContentHeight=function(){this.freezeContentHeightDepth--,this.contentEl.css({width:"",height:"",overflow:""}),this.freezeContentHeightDepth&&this.forceFreezeContentHeight()},t.prototype.initToolbars=function(){this.header=new p.default(this,this.computeHeaderOptions()),this.footer=new p.default(this,this.computeFooterOptions()),this.toolbarsManager=new l.default([this.header,this.footer])},t.prototype.computeHeaderOptions=function(){return{extraClasses:"fc-header-toolbar",layout:this.opt("header")}},t.prototype.computeFooterOptions=function(){return{extraClasses:"fc-footer-toolbar",layout:this.opt("footer")}},t.prototype.renderHeader=function(){var t=this.header;t.setToolbarOptions(this.computeHeaderOptions()),t.render(),t.el&&this.el.prepend(t.el)},t.prototype.renderFooter=function(){var t=this.footer;t.setToolbarOptions(this.computeFooterOptions()),t.render(),t.el&&this.el.append(t.el)},t.prototype.setToolbarsTitle=function(t){this.toolbarsManager.proxyCall("updateTitle",t)},t.prototype.updateToolbarButtons=function(t){var e=this.getNow(),n=this.view,i=n.dateProfileGenerator.build(e),r=n.dateProfileGenerator.buildPrev(n.get("dateProfile")),o=n.dateProfileGenerator.buildNext(n.get("dateProfile"));this.toolbarsManager.proxyCall(i.isValid&&!t.currentUnzonedRange.containsDate(e)?"enableButton":"disableButton","today"),this.toolbarsManager.proxyCall(r.isValid?"enableButton":"disableButton","prev"),this.toolbarsManager.proxyCall(o.isValid?"enableButton":"disableButton","next")},t.prototype.queryToolbarsHeight=function(){return this.toolbarsManager.items.reduce(function(t,e){return t+(e.el?e.el.outerHeight(!0):0)},0)},t.prototype.select=function(t,e){this.view.select(this.buildSelectFootprint.apply(this,arguments))},t.prototype.unselect=function(){this.view&&this.view.unselect()},t.prototype.buildSelectFootprint=function(t,e){var n,i=this.moment(t).stripZone();return n=e?this.moment(e).stripZone():i.hasTime()?i.clone().add(this.defaultTimedEventDuration):i.clone().add(this.defaultAllDayEventDuration),new b.default(new m.default(i,n),!i.hasTime())},t.prototype.initMomentInternals=function(){var t=this;this.defaultAllDayEventDuration=o.duration(this.opt("defaultAllDayEventDuration")),this.defaultTimedEventDuration=o.duration(this.opt("defaultTimedEventDuration")),this.optionsManager.watch("buildingMomentLocale",["?locale","?monthNames","?monthNamesShort","?dayNames","?dayNamesShort","?firstDay","?weekNumberCalculation"],function(e){var n,i=e.weekNumberCalculation,r=e.firstDay;"iso"===i&&(i="ISO");var o=Object.create(v.getMomentLocaleData(e.locale));e.monthNames&&(o._months=e.monthNames),e.monthNamesShort&&(o._monthsShort=e.monthNamesShort),e.dayNames&&(o._weekdays=e.dayNames),e.dayNamesShort&&(o._weekdaysShort=e.dayNamesShort),null==r&&"ISO"===i&&(r=1),null!=r&&(n=Object.create(o._week),n.dow=r,o._week=n),"ISO"!==i&&"local"!==i&&"function"!=typeof i||(o._fullCalendar_weekCalc=i),t.localeData=o,t.currentDate&&t.localizeMoment(t.currentDate)})},t.prototype.moment=function(){for(var t=[],e=0;e864e5&&r.time(n-864e5)),new o.default(i,r)},t.prototype.buildRangeFromDuration=function(t,e,n,s){function a(){d=t.clone().startOf(h),c=d.clone().add(n),p=new o.default(d,c)}var l,u,d,c,p,h=this.opt("dateAlignment");return h||(l=this.opt("dateIncrement"),l?(u=i.duration(l),h=uo.getStart()&&(i=new a.default,i.setEndDelta(l),r=new s.default,r.setDateMutation(i),r)},e}(u.default);e.default=d},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(4),o=n(37),s=n(50),a=n(54),l=n(23),u=n(244),d=n(15),c=function(t){function e(e,n){var i=t.call(this,e)||this;return i.isDragging=!1,i.eventPointing=n,i}return i.__extends(e,t),e.prototype.end=function(){this.dragListener&&this.dragListener.endInteraction()},e.prototype.getSelectionDelay=function(){var t=this.opt("eventLongPressDelay");return null==t&&(t=this.opt("longPressDelay")),t},e.prototype.bindToEl=function(t){var e=this.component;e.bindSegHandlerToEl(t,"mousedown",this.handleMousedown.bind(this)),e.bindSegHandlerToEl(t,"touchstart",this.handleTouchStart.bind(this))},e.prototype.handleMousedown=function(t,e){!this.component.shouldIgnoreMouse()&&this.component.canStartDrag(t,e)&&this.buildDragListener(t).startInteraction(e,{distance:5})},e.prototype.handleTouchStart=function(t,e){var n=this.component,i={delay:this.view.isEventDefSelected(t.footprint.eventDef)?0:this.getSelectionDelay()};n.canStartDrag(t,e)?this.buildDragListener(t).startInteraction(e,i):n.canStartSelection(t,e)&&this.buildSelectListener(t).startInteraction(e,i)},e.prototype.buildSelectListener=function(t){var e=this,n=this.view,i=t.footprint.eventDef,r=t.footprint.eventInstance;if(this.dragListener)return this.dragListener;var o=this.dragListener=new a.default({dragStart:function(t){o.isTouch&&!n.isEventDefSelected(i)&&r&&n.selectEventInstance(r)},interactionEnd:function(t){e.dragListener=null}});return o},e.prototype.buildDragListener=function(t){var e,n,i,o=this,s=this.component,a=this.view,d=a.calendar,c=d.eventManager,p=t.el,h=t.footprint.eventDef,f=t.footprint.eventInstance;if(this.dragListener)return this.dragListener;var g=this.dragListener=new l.default(a,{scroll:this.opt("dragScroll"),subjectEl:p,subjectCenter:!0,interactionStart:function(i){t.component=s,e=!1,n=new u.default(t.el,{additionalClass:"fc-dragging",parentEl:a.el,opacity:g.isTouch?null:o.opt("dragOpacity"),revertDuration:o.opt("dragRevertDuration"),zIndex:2}),n.hide(),n.start(i)},dragStart:function(n){g.isTouch&&!a.isEventDefSelected(h)&&f&&a.selectEventInstance(f),e=!0,o.eventPointing.handleMouseout(t,n),o.segDragStart(t,n),a.hideEventsWithId(t.footprint.eventDef.id)},hitOver:function(e,l,u){var p,f,v,y=!0;t.hit&&(u=t.hit),p=u.component.getSafeHitFootprint(u),f=e.component.getSafeHitFootprint(e),p&&f?(i=o.computeEventDropMutation(p,f,h),i?(v=c.buildMutatedEventInstanceGroup(h.id,i),y=s.isEventInstanceGroupAllowed(v)):y=!1):y=!1,y||(i=null,r.disableCursor()),i&&a.renderDrag(s.eventRangesToEventFootprints(v.sliceRenderRanges(s.dateProfile.renderUnzonedRange,d)),t,g.isTouch)?n.hide():n.show(),l&&(i=null)},hitOut:function(){a.unrenderDrag(t),n.show(),i=null},hitDone:function(){r.enableCursor()},interactionEnd:function(r){delete t.component,n.stop(!i,function(){e&&(a.unrenderDrag(t),o.segDragStop(t,r)),a.showEventsWithId(t.footprint.eventDef.id),i&&a.reportEventDrop(f,i,p,r)}),o.dragListener=null}});return g},e.prototype.segDragStart=function(t,e){this.isDragging=!0,this.component.publiclyTrigger("eventDragStart",{context:t.el[0],args:[t.footprint.getEventLegacy(),e,{},this.view]})},e.prototype.segDragStop=function(t,e){this.isDragging=!1,this.component.publiclyTrigger("eventDragStop",{context:t.el[0],args:[t.footprint.getEventLegacy(),e,{},this.view]})},e.prototype.computeEventDropMutation=function(t,e,n){var i=new o.default;return i.setDateMutation(this.computeEventDateMutation(t,e)),i},e.prototype.computeEventDateMutation=function(t,e){var n,i,r=t.unzonedRange.getStart(),o=e.unzonedRange.getStart(),a=!1,l=!1,u=!1;return t.isAllDay!==e.isAllDay&&(a=!0,e.isAllDay?(u=!0,r.stripTime()):l=!0),n=this.component.diffDates(o,r),i=new s.default,i.clearEnd=a,i.forceTimed=l,i.forceAllDay=u,i.setDateDelta(n),i},e}(d.default);e.default=c},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(4),o=n(23),s=n(12),a=n(5),l=n(15),u=function(t){function e(e){var n=t.call(this,e)||this;return n.dragListener=n.buildDragListener(),n}return i.__extends(e,t),e.prototype.end=function(){this.dragListener.endInteraction()},e.prototype.getDelay=function(){var t=this.opt("selectLongPressDelay");return null==t&&(t=this.opt("longPressDelay")),t},e.prototype.bindToEl=function(t){var e=this,n=this.component,i=this.dragListener;n.bindDateHandlerToEl(t,"mousedown",function(t){e.opt("selectable")&&!n.shouldIgnoreMouse()&&i.startInteraction(t,{distance:e.opt("selectMinDistance")})}),n.bindDateHandlerToEl(t,"touchstart",function(t){e.opt("selectable")&&!n.shouldIgnoreTouch()&&i.startInteraction(t,{delay:e.getDelay()})}),r.preventSelection(t)},e.prototype.buildDragListener=function(){var t,e=this,n=this.component;return new o.default(n,{scroll:this.opt("dragScroll"),interactionStart:function(){t=null},dragStart:function(t){e.view.unselect(t)},hitOver:function(i,o,s){var a,l;s&&(a=n.getSafeHitFootprint(s),l=n.getSafeHitFootprint(i),t=a&&l?e.computeSelection(a,l):null,t?n.renderSelectionFootprint(t):!1===t&&r.disableCursor())},hitOut:function(){t=null,n.unrenderSelection()},hitDone:function(){r.enableCursor()},interactionEnd:function(n,i){!i&&t&&e.view.reportSelection(t,n)}})},e.prototype.computeSelection=function(t,e){var n=this.computeSelectionFootprint(t,e);return!(n&&!this.isSelectionFootprintAllowed(n))&&n},e.prototype.computeSelectionFootprint=function(t,e){var n=[t.unzonedRange.startMs,t.unzonedRange.endMs,e.unzonedRange.startMs,e.unzonedRange.endMs];return n.sort(r.compareNumbers),new s.default(new a.default(n[0],n[3]),t.isAllDay)},e.prototype.isSelectionFootprintAllowed=function(t){return this.component.dateProfile.validUnzonedRange.containsRange(t.unzonedRange)&&this.view.calendar.constraints.isSelectionFootprintAllowed(t)},e}(l.default);e.default=u},function(t,e,n){function i(t){var e,n=[],i=[];for(e=0;e').appendTo(t),this.el.find(".fc-body > tr > td").append(t),this.timeGrid.headContainerEl=this.el.find(".fc-head-container"),this.timeGrid.setElement(e),this.dayGrid&&(this.dayGrid.setElement(this.el.find(".fc-day-grid")),this.dayGrid.bottomCoordPadding=this.dayGrid.el.next("hr").outerHeight())},e.prototype.unrenderSkeleton=function(){this.timeGrid.removeElement(),this.dayGrid&&this.dayGrid.removeElement(),this.scroller.destroy()},e.prototype.renderSkeletonHtml=function(){var t=this.calendar.theme;return''+(this.opt("columnHeader")?'':"")+'
     
    '+(this.dayGrid?'

    ':"")+"
    "},e.prototype.axisStyleAttr=function(){return null!=this.axisWidth?'style="width:'+this.axisWidth+'px"':""},e.prototype.getNowIndicatorUnit=function(){return this.timeGrid.getNowIndicatorUnit()},e.prototype.updateSize=function(e,n,i){var r,o,s;if(t.prototype.updateSize.call(this,e,n,i),this.axisWidth=u.matchCellWidths(this.el.find(".fc-axis")),!this.timeGrid.colEls)return void(n||(o=this.computeScrollerHeight(e),this.scroller.setHeight(o)));var a=this.el.find(".fc-row:not(.fc-scroller *)");this.timeGrid.bottomRuleEl.hide(),this.scroller.clear(),u.uncompensateScroll(a),this.dayGrid&&(this.dayGrid.removeSegPopover(),r=this.opt("eventLimit"),r&&"number"!=typeof r&&(r=5),r&&this.dayGrid.limitRows(r)),n||(o=this.computeScrollerHeight(e),this.scroller.setHeight(o),s=this.scroller.getScrollbarWidths(),(s.left||s.right)&&(u.compensateScroll(a,s),o=this.computeScrollerHeight(e),this.scroller.setHeight(o)),this.scroller.lockOverflow(s),this.timeGrid.getTotalSlatHeight()"+e.buildGotoAnchorHtml({date:i,type:"week",forceOff:this.colCnt>1},u.htmlEscape(t))+""):'"},renderBgIntroHtml:function(){var t=this.view;return'"},renderIntroHtml:function(){return'"}},o={renderBgIntroHtml:function(){var t=this.view;return'"+t.getAllDayHtml()+""},renderIntroHtml:function(){return'"}}},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(3),o=n(0),s=n(4),a=n(40),l=n(56),u=n(60),d=n(55),c=n(53),p=n(5),h=n(12),f=n(246),g=n(247),v=n(248),y=[{hours:1},{minutes:30},{minutes:15},{seconds:30},{seconds:15}],m=function(t){function e(e){var n=t.call(this,e)||this;return n.processOptions(),n}return i.__extends(e,t),e.prototype.componentFootprintToSegs=function(t){var e,n=this.sliceRangeByTimes(t.unzonedRange);for(e=0;e=0;e--)if(n=o.duration(y[e]),i=s.divideDurationByDuration(n,t),s.isInt(i)&&i>1)return n;return o.duration(t)},e.prototype.renderDates=function(t){this.dateProfile=t,this.updateDayTable(),this.renderSlats(),this.renderColumns()},e.prototype.unrenderDates=function(){this.unrenderColumns()},e.prototype.renderSkeleton=function(){var t=this.view.calendar.theme;this.el.html('
    '),this.bottomRuleEl=this.el.find("hr")},e.prototype.renderSlats=function(){var t=this.view.calendar.theme;this.slatContainerEl=this.el.find("> .fc-slats").html(''+this.renderSlatRowHtml()+"
    "),this.slatEls=this.slatContainerEl.find("tr"),this.slatCoordCache=new c.default({els:this.slatEls,isVertical:!0})},e.prototype.renderSlatRowHtml=function(){for(var t,e,n,i=this.view,r=i.calendar,a=r.theme,l=this.isRTL,u=this.dateProfile,d="",c=o.duration(+u.minTime),p=o.duration(0);c"+(e?""+s.htmlEscape(t.format(this.labelFormat))+"":"")+"",d+='"+(l?"":n)+''+(l?n:"")+"",c.add(this.slotDuration),p.add(this.slotDuration);return d},e.prototype.renderColumns=function(){var t=this.dateProfile,e=this.view.calendar.theme;this.dayRanges=this.dayDates.map(function(e){return new p.default(e.clone().add(t.minTime),e.clone().add(t.maxTime))}),this.headContainerEl&&this.headContainerEl.html(this.renderHeadHtml()),this.el.find("> .fc-bg").html(''+this.renderBgTrHtml(0)+"
    "),this.colEls=this.el.find(".fc-day, .fc-disabled-day"),this.colCoordCache=new c.default({els:this.colEls,isHorizontal:!0}),this.renderContentSkeleton()},e.prototype.unrenderColumns=function(){this.unrenderContentSkeleton()},e.prototype.renderContentSkeleton=function(){var t,e,n="";for(t=0;t
    ';e=this.contentSkeletonEl=r('
    '+n+"
    "),this.colContainerEls=e.find(".fc-content-col"),this.helperContainerEls=e.find(".fc-helper-container"),this.fgContainerEls=e.find(".fc-event-container:not(.fc-helper-container)"),this.bgContainerEls=e.find(".fc-bgevent-container"),this.highlightContainerEls=e.find(".fc-highlight-container"),this.businessContainerEls=e.find(".fc-business-container"),this.bookendCells(e.find("tr")),this.el.append(e)},e.prototype.unrenderContentSkeleton=function(){this.contentSkeletonEl&&(this.contentSkeletonEl.remove(),this.contentSkeletonEl=null,this.colContainerEls=null,this.helperContainerEls=null,this.fgContainerEls=null,this.bgContainerEls=null,this.highlightContainerEls=null,this.businessContainerEls=null)},e.prototype.groupSegsByCol=function(t){var e,n=[];for(e=0;e
    ').css("top",i).appendTo(this.colContainerEls.eq(n[e].col))[0]);n.length>0&&o.push(r('
    ').css("top",i).appendTo(this.el.find(".fc-content-skeleton"))[0]),this.nowIndicatorEls=r(o)}},e.prototype.unrenderNowIndicator=function(){this.nowIndicatorEls&&(this.nowIndicatorEls.remove(),this.nowIndicatorEls=null)},e.prototype.updateSize=function(e,n,i){t.prototype.updateSize.call(this,e,n,i),this.slatCoordCache.build(),i&&this.updateSegVerticals([].concat(this.eventRenderer.getSegs(),this.businessSegs||[]))},e.prototype.getTotalSlatHeight=function(){return this.slatContainerEl.outerHeight()},e.prototype.computeDateTop=function(t,e){return this.computeTimeTop(o.duration(t-e.clone().stripTime()))},e.prototype.computeTimeTop=function(t){var e,n,i=this.slatEls.length,r=this.dateProfile,o=(t-r.minTime)/this.slotDuration;return o=Math.max(0,o),o=Math.min(i,o),e=Math.floor(o),e=Math.min(e,i-1),n=o-e,this.slatCoordCache.getTopPosition(e)+this.slatCoordCache.getHeight(e)*n},e.prototype.updateSegVerticals=function(t){this.computeSegVerticals(t),this.assignSegVerticals(t)},e.prototype.computeSegVerticals=function(t){var e,n,i,r=this.opt("agendaEventMinHeight");for(e=0;e
    '+o.htmlEscape(this.opt("noEventsMessage"))+"
    ")},e.prototype.renderSegList=function(t){var e,n,i,o=this.groupSegsByDay(t),s=r('
    '),a=s.find("tbody");for(e=0;e'+(e?this.buildGotoAnchorHtml(t,{class:"fc-list-heading-main"},o.htmlEscape(t.format(e))):"")+(n?this.buildGotoAnchorHtml(t,{class:"fc-list-heading-alt"},o.htmlEscape(t.format(n))):"")+""},e}(a.default);e.default=c,c.prototype.eventRendererClass=u.default,c.prototype.eventPointingClass=d.default},,,,,,function(t,e,n){var i=n(3),r=n(16),o=n(4),s=n(220);n(10),n(47),n(256),n(257),n(260),n(261),n(262),n(263),i.fullCalendar=r,i.fn.fullCalendar=function(t){var e=Array.prototype.slice.call(arguments,1),n=this;return this.each(function(r,a){var l,u=i(a),d=u.data("fullCalendar");"string"==typeof t?"getCalendar"===t?r||(n=d):"destroy"===t?d&&(d.destroy(),u.removeData("fullCalendar")):d?i.isFunction(d[t])?(l=d[t].apply(d,e),r||(n=l),"destroy"===t&&u.removeData("fullCalendar")):o.warn("'"+t+"' is an unknown FullCalendar method."):o.warn("Attempting to call a FullCalendar method on an element with no calendar."):d||(d=new s.default(u,t),u.data("fullCalendar",d),d.render())}),n},t.exports=r},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(48),o=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return i.__extends(e,t),e.prototype.setElement=function(t){this.el=t,this.bindGlobalHandlers(),this.renderSkeleton(),this.set("isInDom",!0)},e.prototype.removeElement=function(){this.unset("isInDom"),this.unrenderSkeleton(),this.unbindGlobalHandlers(),this.el.remove()},e.prototype.bindGlobalHandlers=function(){},e.prototype.unbindGlobalHandlers=function(){},e.prototype.renderSkeleton=function(){},e.prototype.unrenderSkeleton=function(){},e}(r.default);e.default=o},function(t,e){Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t){this.items=t||[]}return t.prototype.proxyCall=function(t){for(var e=[],n=1;n"),e.append(this.renderSection("left")).append(this.renderSection("right")).append(this.renderSection("center")).append('
    ')):this.removeElement()},t.prototype.removeElement=function(){this.el&&(this.el.remove(),this.el=null)},t.prototype.renderSection=function(t){var e=this,n=this.calendar,o=n.theme,s=n.optionsManager,a=n.viewSpecManager,l=i('
    '),u=this.toolbarOptions.layout[t],d=s.get("customButtons")||{},c=s.overrides.buttonText||{},p=s.get("buttonText")||{};return u&&i.each(u.split(" "),function(t,s){var u,h=i(),f=!0;i.each(s.split(","),function(t,s){var l,u,g,v,y,m,b,w,D;"title"===s?(h=h.add(i("

     

    ")),f=!1):((l=d[s])?(g=function(t){l.click&&l.click.call(w[0],t)},(v=o.getCustomButtonIconClass(l))||(v=o.getIconClass(s))||(y=l.text)):(u=a.getViewSpec(s))?(e.viewsWithButtons.push(s),g=function(){n.changeView(s)},(y=u.buttonTextOverride)||(v=o.getIconClass(s))||(y=u.buttonTextDefault)):n[s]&&(g=function(){n[s]()},(y=c[s])||(v=o.getIconClass(s))||(y=p[s])),g&&(b=["fc-"+s+"-button",o.getClass("button"),o.getClass("stateDefault")],y?(m=r.htmlEscape(y),D=""):v&&(m="",D=' aria-label="'+s+'"'),w=i('").click(function(t){w.hasClass(o.getClass("stateDisabled"))||(g(t),(w.hasClass(o.getClass("stateActive"))||w.hasClass(o.getClass("stateDisabled")))&&w.removeClass(o.getClass("stateHover")))}).mousedown(function(){w.not("."+o.getClass("stateActive")).not("."+o.getClass("stateDisabled")).addClass(o.getClass("stateDown"))}).mouseup(function(){w.removeClass(o.getClass("stateDown"))}).hover(function(){w.not("."+o.getClass("stateActive")).not("."+o.getClass("stateDisabled")).addClass(o.getClass("stateHover"))},function(){w.removeClass(o.getClass("stateHover")).removeClass(o.getClass("stateDown"))}),h=h.add(w)))}),f&&h.first().addClass(o.getClass("cornerLeft")).end().last().addClass(o.getClass("cornerRight")).end(),h.length>1?(u=i("
    "),f&&u.addClass(o.getClass("buttonGroup")),u.append(h),l.append(u)):l.append(h)}),l},t.prototype.updateTitle=function(t){this.el&&this.el.find("h2").text(t)},t.prototype.activateButton=function(t){this.el&&this.el.find(".fc-"+t+"-button").addClass(this.calendar.theme.getClass("stateActive"))},t.prototype.deactivateButton=function(t){this.el&&this.el.find(".fc-"+t+"-button").removeClass(this.calendar.theme.getClass("stateActive"))},t.prototype.disableButton=function(t){this.el&&this.el.find(".fc-"+t+"-button").prop("disabled",!0).addClass(this.calendar.theme.getClass("stateDisabled"))},t.prototype.enableButton=function(t){this.el&&this.el.find(".fc-"+t+"-button").prop("disabled",!1).removeClass(this.calendar.theme.getClass("stateDisabled"))},t.prototype.getViewsWithButtons=function(){return this.viewsWithButtons},t}();e.default=o},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(3),o=n(4),s=n(32),a=n(31),l=n(48),u=function(t){function e(e,n){var i=t.call(this)||this;return i._calendar=e,i.overrides=r.extend({},n),i.dynamicOverrides={},i.compute(),i}return i.__extends(e,t),e.prototype.add=function(t){var e,n=0;this.recordOverrides(t);for(e in t)n++;if(1===n){if("height"===e||"contentHeight"===e||"aspectRatio"===e)return void this._calendar.updateViewSize(!0);if("defaultDate"===e)return;if("businessHours"===e)return;if(/^(event|select)(Overlap|Constraint|Allow)$/.test(e))return;if("timezone"===e)return void this._calendar.view.flash("initialEvents")}this._calendar.renderHeader(),this._calendar.renderFooter(),this._calendar.viewsByType={},this._calendar.reinitView()},e.prototype.compute=function(){var t,e,n,i,r;t=o.firstDefined(this.dynamicOverrides.locale,this.overrides.locale),e=a.localeOptionHash[t],e||(t=s.globalDefaults.locale,e=a.localeOptionHash[t]||{}),n=o.firstDefined(this.dynamicOverrides.isRTL,this.overrides.isRTL,e.isRTL,s.globalDefaults.isRTL),i=n?s.rtlDefaults:{},this.dirDefaults=i,this.localeDefaults=e,r=s.mergeOptions([s.globalDefaults,i,e,this.overrides,this.dynamicOverrides]),a.populateInstanceComputableOptions(r),this.reset(r)},e.prototype.recordOverrides=function(t){var e;for(e in t)this.dynamicOverrides[e]=t[e];this._calendar.viewSpecManager.clearCache(),this.compute()},e}(l.default);e.default=u},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(0),r=n(3),o=n(22),s=n(4),a=n(32),l=n(31),u=function(){function t(t,e){this.optionsManager=t,this._calendar=e,this.clearCache()}return t.prototype.clearCache=function(){this.viewSpecCache={}},t.prototype.getViewSpec=function(t){var e=this.viewSpecCache;return e[t]||(e[t]=this.buildViewSpec(t))},t.prototype.getUnitViewSpec=function(t){var e,n,i;if(-1!==r.inArray(t,s.unitsDesc))for(e=this._calendar.header.getViewsWithButtons(),r.each(o.viewHash,function(t){e.push(t)}),n=0;ne.top&&t.top
    '+(n?'
    '+u.htmlEscape(n)+"
    ":"")+(d.title?'
    '+u.htmlEscape(d.title)+"
    ":"")+'
    '+(h?'
    ':"")+""},e.prototype.updateFgSegCoords=function(t){this.timeGrid.computeSegVerticals(t),this.computeFgSegHorizontals(t),this.timeGrid.assignSegVerticals(t),this.assignFgSegHorizontals(t)},e.prototype.computeFgSegHorizontals=function(t){var e,n,s;if(this.sortEventSegs(t),e=i(t),r(e),n=e[0]){for(s=0;s').addClass(e.className||"").css({top:0,left:0}).append(e.content).appendTo(e.parentEl),this.el.on("click",".fc-close",function(){t.hide()}),e.autoHide&&this.listenTo(i(document),"mousedown",this.documentMousedown)},t.prototype.documentMousedown=function(t){this.el&&!i(t.target).closest(this.el).length&&this.hide()},t.prototype.removeElement=function(){this.hide(),this.el&&(this.el.remove(),this.el=null),this.stopListeningTo(i(document),"mousedown")},t.prototype.position=function(){var t,e,n,o,s,a=this.options,l=this.el.offsetParent().offset(),u=this.el.outerWidth(),d=this.el.outerHeight(),c=i(window),p=r.getScrollParent(this.el);o=a.top||0,s=void 0!==a.left?a.left:void 0!==a.right?a.right-u:0,p.is(window)||p.is(document)?(p=c,t=0,e=0):(n=p.offset(),t=n.top,e=n.left),t+=c.scrollTop(),e+=c.scrollLeft(),!1!==a.viewportConstrain&&(o=Math.min(o,t+p.outerHeight()-d-this.margin),o=Math.max(o,t+this.margin),s=Math.min(s,e+p.outerWidth()-u-this.margin),s=Math.max(s,e+this.margin)),this.el.css({top:o-l.top,left:s-l.left})},t.prototype.trigger=function(t){this.options[t]&&this.options[t].apply(this,Array.prototype.slice.call(arguments,1))},t}();e.default=s,o.default.mixInto(s)},function(t,e,n){function i(t,e){var n,i;for(n=0;n=t.leftCol)return!0;return!1}function r(t,e){return t.leftCol-e.leftCol}Object.defineProperty(e,"__esModule",{value:!0});var o=n(2),s=n(3),a=n(4),l=n(42),u=function(t){function e(e,n){var i=t.call(this,e,n)||this;return i.dayGrid=e,i}return o.__extends(e,t),e.prototype.renderBgRanges=function(e){e=s.grep(e,function(t){return t.eventDef.isAllDay()}),t.prototype.renderBgRanges.call(this,e)},e.prototype.renderFgSegs=function(t){var e=this.rowStructs=this.renderSegRows(t);this.dayGrid.rowEls.each(function(t,n){s(n).find(".fc-content-skeleton > table").append(e[t].tbodyEl)})},e.prototype.unrenderFgSegs=function(){for(var t,e=this.rowStructs||[];t=e.pop();)t.tbodyEl.remove();this.rowStructs=null},e.prototype.renderSegRows=function(t){var e,n,i=[];for(e=this.groupSegRows(t),n=0;n"),a.append(d)),v[i][o]=d,y[i][o]=d,o++}var i,r,o,a,l,u,d,c=this.dayGrid.colCnt,p=this.buildSegLevels(e),h=Math.max(1,p.length),f=s(""),g=[],v=[],y=[];for(i=0;i"),g.push([]),v.push([]),y.push([]),r)for(l=0;l').append(u.el),u.leftCol!==u.rightCol?d.attr("colspan",u.rightCol-u.leftCol+1):y[i][o]=d;o<=u.rightCol;)v[i][o]=d,g[i][o]=u,o++;a.append(d)}n(c),this.dayGrid.bookendCells(a),f.append(a)}return{row:t,tbodyEl:f,cellMatrix:v,segMatrix:g,segLevels:p,segs:e}},e.prototype.buildSegLevels=function(t){var e,n,o,s=[];for(this.sortEventSegs(t),e=0;e'+a.htmlEscape(n)+""),i=''+(a.htmlEscape(o.title||"")||" ")+"",'
    '+(this.dayGrid.isRTL?i+" "+h:h+" "+i)+"
    "+(u?'
    ':"")+(d?'
    ':"")+""},e}(l.default);e.default=u},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(3),o=n(58),s=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return i.__extends(e,t),e.prototype.renderSegs=function(t,e){var n,i=[];return n=this.eventRenderer.renderSegRows(t),this.component.rowEls.each(function(t,o){var s,a,l=r(o),u=r('
    ');e&&e.row===t?a=e.el.position().top:(s=l.find(".fc-content-skeleton tbody"),s.length||(s=l.find(".fc-content-skeleton table")),a=s.position().top),u.css("top",a).find("table").append(n[t].tbodyEl),l.append(u),i.push(u[0])}),r(i)},e}(o.default);e.default=s},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(3),o=n(57),s=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.fillSegTag="td",e}return i.__extends(e,t),e.prototype.attachSegEls=function(t,e){var n,i,r,o=[];for(n=0;n
    '),o=i.find("tr"),a>0&&o.append(''),o.append(e.el.attr("colspan",l-a)),l'),this.component.bookendCells(o),i},e}(o.default);e.default=s},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(228),o=n(5),s=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return i.__extends(e,t),e.prototype.buildRenderRange=function(e,n,i){var r,s=t.prototype.buildRenderRange.call(this,e,n,i),a=this.msToUtcMoment(s.startMs,i),l=this.msToUtcMoment(s.endMs,i);return this.opt("fixedWeekCount")&&(r=Math.ceil(l.diff(a,"weeks",!0)),l.add(6-r,"weeks")),new o.default(a,l)},e}(r.default);e.default=s},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(4),o=n(42),s=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return i.__extends(e,t),e.prototype.renderFgSegs=function(t){t.length?this.component.renderSegList(t):this.component.renderEmptyMessage()},e.prototype.fgSegHtml=function(t){var e,n=this.view,i=n.calendar,o=i.theme,s=t.footprint,a=s.eventDef,l=s.componentFootprint,u=a.url,d=["fc-list-item"].concat(this.getClasses(a)),c=this.getBgColor(a);return e=l.isAllDay?n.getAllDayHtml():n.isMultiDayRange(l.unzonedRange)?t.isStart||t.isEnd?r.htmlEscape(this._getTimeText(i.msToMoment(t.startMs),i.msToMoment(t.endMs),l.isAllDay)):n.getAllDayHtml():r.htmlEscape(this.getTimeText(s)),u&&d.push("fc-has-url"),''+(this.displayEventTime?''+(e||"")+"":"")+'"+r.htmlEscape(a.title||"")+""},e.prototype.computeEventTimeFormat=function(){return this.opt("mediumTimeFormat")},e}(o.default);e.default=s},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(3),o=n(59),s=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return i.__extends(e,t),e.prototype.handleClick=function(e,n){var i;t.prototype.handleClick.call(this,e,n),r(n.target).closest("a[href]").length||(i=e.footprint.eventDef.url)&&!n.isDefaultPrevented()&&(window.location.href=i)},e}(o.default);e.default=s},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(38),r=n(52),o=n(215),s=n(216);i.default.registerClass(r.default),i.default.registerClass(o.default),i.default.registerClass(s.default)},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(51),r=n(213),o=n(214),s=n(258),a=n(259);i.defineThemeSystem("standard",r.default),i.defineThemeSystem("jquery-ui",o.default),i.defineThemeSystem("bootstrap3",s.default),i.defineThemeSystem("bootstrap4",a.default)},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(19),o=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return i.__extends(e,t),e}(r.default);e.default=o,o.prototype.classes={widget:"fc-bootstrap3",tableGrid:"table-bordered",tableList:"table",tableListHeading:"active",buttonGroup:"btn-group",button:"btn btn-default",stateActive:"active",stateDisabled:"disabled",today:"alert alert-info",popover:"panel panel-default",popoverHeader:"panel-heading",popoverContent:"panel-body",headerRow:"panel-default",dayRow:"panel-default",listView:"panel panel-default"},o.prototype.baseIconClass="glyphicon",o.prototype.iconClasses={close:"glyphicon-remove",prev:"glyphicon-chevron-left",next:"glyphicon-chevron-right",prevYear:"glyphicon-backward",nextYear:"glyphicon-forward"},o.prototype.iconOverrideOption="bootstrapGlyphicons",o.prototype.iconOverrideCustomButtonOption="bootstrapGlyphicon",o.prototype.iconOverridePrefix="glyphicon-"},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(2),r=n(19),o=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return i.__extends(e,t),e}(r.default);e.default=o,o.prototype.classes={widget:"fc-bootstrap4",tableGrid:"table-bordered",tableList:"table",tableListHeading:"table-active",buttonGroup:"btn-group",button:"btn btn-primary",stateActive:"active",stateDisabled:"disabled",today:"alert alert-info",popover:"card card-primary",popoverHeader:"card-header",popoverContent:"card-body",headerRow:"table-bordered",dayRow:"table-bordered",listView:"card card-primary"},o.prototype.baseIconClass="fa",o.prototype.iconClasses={close:"fa-times",prev:"fa-chevron-left",next:"fa-chevron-right",prevYear:"fa-angle-double-left",nextYear:"fa-angle-double-right"},o.prototype.iconOverrideOption="bootstrapFontAwesome",o.prototype.iconOverrideCustomButtonOption="bootstrapFontAwesome",o.prototype.iconOverridePrefix="fa-"},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(22),r=n(62),o=n(229);i.defineView("basic",{class:r.default}),i.defineView("basicDay",{type:"basic",duration:{days:1}}),i.defineView("basicWeek",{type:"basic",duration:{weeks:1}}),i.defineView("month",{class:o.default,duration:{months:1},defaults:{fixedWeekCount:!0}})},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(22),r=n(226);i.defineView("agenda",{class:r.default,defaults:{allDaySlot:!0,slotDuration:"00:30:00",slotEventOverlap:!0}}),i.defineView("agendaDay",{type:"agenda",duration:{days:1}}),i.defineView("agendaWeek",{type:"agenda",duration:{weeks:1}})},function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var i=n(22),r=n(230);i.defineView("list",{class:r.default,buttonTextKey:"list",defaults:{buttonText:"list",listDayFormat:"LL",noEventsMessage:"No events to display"}}),i.defineView("listDay",{type:"list",duration:{days:1},defaults:{listDayFormat:"dddd"}}),i.defineView("listWeek",{type:"list",duration:{weeks:1},defaults:{listDayFormat:"dddd",listDayAltFormat:"LL"}}),i.defineView("listMonth",{type:"list",duration:{month:1},defaults:{listDayAltFormat:"dddd"}}),i.defineView("listYear",{type:"list",duration:{year:1},defaults:{listDayAltFormat:"dddd"}})},function(t,e){Object.defineProperty(e,"__esModule",{value:!0})}])}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-cookie/jquery.cookie.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-cookie/jquery.cookie.js deleted file mode 100644 index c7f3a59b5..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-cookie/jquery.cookie.js +++ /dev/null @@ -1,117 +0,0 @@ -/*! - * jQuery Cookie Plugin v1.4.1 - * https://github.com/carhartl/jquery-cookie - * - * Copyright 2013 Klaus Hartl - * Released under the MIT license - */ -(function (factory) { - if (typeof define === 'function' && define.amd) { - // AMD - define(['jquery'], factory); - } else if (typeof exports === 'object') { - // CommonJS - factory(require('jquery')); - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - - var pluses = /\+/g; - - function encode(s) { - return config.raw ? s : encodeURIComponent(s); - } - - function decode(s) { - return config.raw ? s : decodeURIComponent(s); - } - - function stringifyCookieValue(value) { - return encode(config.json ? JSON.stringify(value) : String(value)); - } - - function parseCookieValue(s) { - if (s.indexOf('"') === 0) { - // This is a quoted cookie as according to RFC2068, unescape... - s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); - } - - try { - // Replace server-side written pluses with spaces. - // If we can't decode the cookie, ignore it, it's unusable. - // If we can't parse the cookie, ignore it, it's unusable. - s = decodeURIComponent(s.replace(pluses, ' ')); - return config.json ? JSON.parse(s) : s; - } catch(e) {} - } - - function read(s, converter) { - var value = config.raw ? s : parseCookieValue(s); - return $.isFunction(converter) ? converter(value) : value; - } - - var config = $.cookie = function (key, value, options) { - - // Write - - if (value !== undefined && !$.isFunction(value)) { - options = $.extend({}, config.defaults, options); - - if (typeof options.expires === 'number') { - var days = options.expires, t = options.expires = new Date(); - t.setTime(+t + days * 864e+5); - } - - return (document.cookie = [ - encode(key), '=', stringifyCookieValue(value), - options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE - options.path ? '; path=' + options.path : '', - options.domain ? '; domain=' + options.domain : '', - options.secure ? '; secure' : '' - ].join('')); - } - - // Read - - var result = key ? undefined : {}; - - // To prevent the for loop in the first place assign an empty array - // in case there are no cookies at all. Also prevents odd result when - // calling $.cookie(). - var cookies = document.cookie ? document.cookie.split('; ') : []; - - for (var i = 0, l = cookies.length; i < l; i++) { - var parts = cookies[i].split('='); - var name = decode(parts.shift()); - var cookie = parts.join('='); - - if (key && key === name) { - // If second argument (value) is a function it's a converter... - result = read(cookie, value); - break; - } - - // Prevent storing a cookie that we couldn't decode. - if (!key && (cookie = read(cookie)) !== undefined) { - result[name] = cookie; - } - } - - return result; - }; - - config.defaults = {}; - - $.removeCookie = function (key, options) { - if ($.cookie(key) === undefined) { - return false; - } - - // Must not alter options, thus extending a fresh object... - $.cookie(key, '', $.extend({}, options, { expires: -1 })); - return !$.cookie(key); - }; - -})); diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-countto/jquery.countTo.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-countto/jquery.countTo.js deleted file mode 100644 index 594091259..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-countto/jquery.countTo.js +++ /dev/null @@ -1,130 +0,0 @@ -(function (factory) { - if (typeof define === 'function' && define.amd) { - // AMD - define(['jquery'], factory); - } else if (typeof exports === 'object') { - // CommonJS - factory(require('jquery')); - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - var CountTo = function (element, options) { - this.$element = $(element); - this.options = $.extend({}, CountTo.DEFAULTS, this.dataOptions(), options); - this.init(); - }; - - CountTo.DEFAULTS = { - from: 0, // the number the element should start at - to: 0, // the number the element should end at - speed: 1000, // how long it should take to count between the target numbers - refreshInterval: 100, // how often the element should be updated - decimals: 0, // the number of decimal places to show - formatter: formatter, // handler for formatting the value before rendering - onUpdate: null, // callback method for every time the element is updated - onComplete: null // callback method for when the element finishes updating - }; - - CountTo.prototype.init = function () { - this.value = this.options.from; - this.loops = Math.ceil(this.options.speed / this.options.refreshInterval); - this.loopCount = 0; - this.increment = (this.options.to - this.options.from) / this.loops; - }; - - CountTo.prototype.dataOptions = function () { - var options = { - from: this.$element.data('from'), - to: this.$element.data('to'), - speed: this.$element.data('speed'), - refreshInterval: this.$element.data('refresh-interval'), - decimals: this.$element.data('decimals') - }; - - var keys = Object.keys(options); - - for (var i in keys) { - var key = keys[i]; - - if (typeof(options[key]) === 'undefined') { - delete options[key]; - } - } - - return options; - }; - - CountTo.prototype.update = function () { - this.value += this.increment; - this.loopCount++; - - this.render(); - - if (typeof(this.options.onUpdate) == 'function') { - this.options.onUpdate.call(this.$element, this.value); - } - - if (this.loopCount >= this.loops) { - clearInterval(this.interval); - this.value = this.options.to; - - if (typeof(this.options.onComplete) == 'function') { - this.options.onComplete.call(this.$element, this.value); - } - } - }; - - CountTo.prototype.render = function () { - var formattedValue = this.options.formatter.call(this.$element, this.value, this.options); - this.$element.text(formattedValue); - }; - - CountTo.prototype.restart = function () { - this.stop(); - this.init(); - this.start(); - }; - - CountTo.prototype.start = function () { - this.stop(); - this.render(); - this.interval = setInterval(this.update.bind(this), this.options.refreshInterval); - }; - - CountTo.prototype.stop = function () { - if (this.interval) { - clearInterval(this.interval); - } - }; - - CountTo.prototype.toggle = function () { - if (this.interval) { - this.stop(); - } else { - this.start(); - } - }; - - function formatter(value, options) { - return value.toFixed(options.decimals); - } - - $.fn.countTo = function (option) { - return this.each(function () { - var $this = $(this); - var data = $this.data('countTo'); - var init = !data || typeof(option) === 'object'; - var options = typeof(option) === 'object' ? option : {}; - var method = typeof(option) === 'string' ? option : 'start'; - - if (init) { - if (data) data.stop(); - $this.data('countTo', data = new CountTo(this, options)); - } - - data[method].call(data); - }); - }; -})); diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.date.extensions.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.date.extensions.js deleted file mode 100644 index df435fdf9..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.date.extensions.js +++ /dev/null @@ -1,515 +0,0 @@ -/*! -* inputmask.date.extensions.js -* https://github.com/RobinHerbots/jquery.inputmask -* Copyright (c) 2010 - 2016 Robin Herbots -* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -* Version: 3.3.1 -*/ -!function(factory) { - "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib.jquery"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask); -}(function($, Inputmask) { - return Inputmask.extendDefinitions({ - h: { - validator: "[01][0-9]|2[0-3]", - cardinality: 2, - prevalidator: [ { - validator: "[0-2]", - cardinality: 1 - } ] - }, - s: { - validator: "[0-5][0-9]", - cardinality: 2, - prevalidator: [ { - validator: "[0-5]", - cardinality: 1 - } ] - }, - d: { - validator: "0[1-9]|[12][0-9]|3[01]", - cardinality: 2, - prevalidator: [ { - validator: "[0-3]", - cardinality: 1 - } ] - }, - m: { - validator: "0[1-9]|1[012]", - cardinality: 2, - prevalidator: [ { - validator: "[01]", - cardinality: 1 - } ] - }, - y: { - validator: "(19|20)\\d{2}", - cardinality: 4, - prevalidator: [ { - validator: "[12]", - cardinality: 1 - }, { - validator: "(19|20)", - cardinality: 2 - }, { - validator: "(19|20)\\d", - cardinality: 3 - } ] - } - }), Inputmask.extendAliases({ - "dd/mm/yyyy": { - mask: "1/2/y", - placeholder: "dd/mm/yyyy", - regex: { - val1pre: new RegExp("[0-3]"), - val1: new RegExp("0[1-9]|[12][0-9]|3[01]"), - val2pre: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|[12][0-9]|3[01])" + escapedSeparator + "[01])"); - }, - val2: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|[12][0-9])" + escapedSeparator + "(0[1-9]|1[012]))|(30" + escapedSeparator + "(0[13-9]|1[012]))|(31" + escapedSeparator + "(0[13578]|1[02]))"); - } - }, - leapday: "29/02/", - separator: "/", - yearrange: { - minyear: 1900, - maxyear: 2099 - }, - isInYearRange: function(chrs, minyear, maxyear) { - if (isNaN(chrs)) return !1; - var enteredyear = parseInt(chrs.concat(minyear.toString().slice(chrs.length))), enteredyear2 = parseInt(chrs.concat(maxyear.toString().slice(chrs.length))); - return (isNaN(enteredyear) ? !1 : enteredyear >= minyear && maxyear >= enteredyear) || (isNaN(enteredyear2) ? !1 : enteredyear2 >= minyear && maxyear >= enteredyear2); - }, - determinebaseyear: function(minyear, maxyear, hint) { - var currentyear = new Date().getFullYear(); - if (minyear > currentyear) return minyear; - if (currentyear > maxyear) { - for (var maxYearPrefix = maxyear.toString().slice(0, 2), maxYearPostfix = maxyear.toString().slice(2, 4); maxYearPrefix + hint > maxyear; ) maxYearPrefix--; - var maxxYear = maxYearPrefix + maxYearPostfix; - return minyear > maxxYear ? minyear : maxxYear; - } - if (currentyear >= minyear && maxyear >= currentyear) { - for (var currentYearPrefix = currentyear.toString().slice(0, 2); currentYearPrefix + hint > maxyear; ) currentYearPrefix--; - var currentYearAndHint = currentYearPrefix + hint; - return minyear > currentYearAndHint ? minyear : currentYearAndHint; - } - return currentyear; - }, - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) { - var today = new Date(); - $input.val(today.getDate().toString() + (today.getMonth() + 1).toString() + today.getFullYear().toString()), - $input.trigger("setvalue"); - } - }, - getFrontValue: function(mask, buffer, opts) { - for (var start = 0, length = 0, i = 0; i < mask.length && "2" !== mask.charAt(i); i++) { - var definition = opts.definitions[mask.charAt(i)]; - definition ? (start += length, length = definition.cardinality) : length++; - } - return buffer.join("").substr(start, length); - }, - definitions: { - "1": { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.regex.val1.test(chrs); - return strict || isValid || chrs.charAt(1) !== opts.separator && -1 === "-./".indexOf(chrs.charAt(1)) || !(isValid = opts.regex.val1.test("0" + chrs.charAt(0))) ? isValid : (maskset.buffer[pos - 1] = "0", - { - refreshFromBuffer: { - start: pos - 1, - end: pos - }, - pos: pos, - c: chrs.charAt(0) - }); - }, - cardinality: 2, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - var pchrs = chrs; - isNaN(maskset.buffer[pos + 1]) || (pchrs += maskset.buffer[pos + 1]); - var isValid = 1 === pchrs.length ? opts.regex.val1pre.test(pchrs) : opts.regex.val1.test(pchrs); - if (!strict && !isValid) { - if (isValid = opts.regex.val1.test(chrs + "0")) return maskset.buffer[pos] = chrs, - maskset.buffer[++pos] = "0", { - pos: pos, - c: "0" - }; - if (isValid = opts.regex.val1.test("0" + chrs)) return maskset.buffer[pos] = "0", - pos++, { - pos: pos - }; - } - return isValid; - }, - cardinality: 1 - } ] - }, - "2": { - validator: function(chrs, maskset, pos, strict, opts) { - var frontValue = opts.getFrontValue(maskset.mask, maskset.buffer, opts); - -1 !== frontValue.indexOf(opts.placeholder[0]) && (frontValue = "01" + opts.separator); - var isValid = opts.regex.val2(opts.separator).test(frontValue + chrs); - if (!strict && !isValid && (chrs.charAt(1) === opts.separator || -1 !== "-./".indexOf(chrs.charAt(1))) && (isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs.charAt(0)))) return maskset.buffer[pos - 1] = "0", - { - refreshFromBuffer: { - start: pos - 1, - end: pos - }, - pos: pos, - c: chrs.charAt(0) - }; - if (opts.mask.indexOf("2") === opts.mask.length - 1 && isValid) { - var dayMonthValue = maskset.buffer.join("").substr(4, 4) + chrs; - if (dayMonthValue !== opts.leapday) return !0; - var year = parseInt(maskset.buffer.join("").substr(0, 4), 10); - return year % 4 === 0 ? year % 100 === 0 ? year % 400 === 0 ? !0 : !1 : !0 : !1; - } - return isValid; - }, - cardinality: 2, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - isNaN(maskset.buffer[pos + 1]) || (chrs += maskset.buffer[pos + 1]); - var frontValue = opts.getFrontValue(maskset.mask, maskset.buffer, opts); - -1 !== frontValue.indexOf(opts.placeholder[0]) && (frontValue = "01" + opts.separator); - var isValid = 1 === chrs.length ? opts.regex.val2pre(opts.separator).test(frontValue + chrs) : opts.regex.val2(opts.separator).test(frontValue + chrs); - return strict || isValid || !(isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs)) ? isValid : (maskset.buffer[pos] = "0", - pos++, { - pos: pos - }); - }, - cardinality: 1 - } ] - }, - y: { - validator: function(chrs, maskset, pos, strict, opts) { - if (opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) { - var dayMonthValue = maskset.buffer.join("").substr(0, 6); - if (dayMonthValue !== opts.leapday) return !0; - var year = parseInt(chrs, 10); - return year % 4 === 0 ? year % 100 === 0 ? year % 400 === 0 ? !0 : !1 : !0 : !1; - } - return !1; - }, - cardinality: 4, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear); - if (!strict && !isValid) { - var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 1); - if (isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) return maskset.buffer[pos++] = yearPrefix.charAt(0), - { - pos: pos - }; - if (yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 2), - isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) return maskset.buffer[pos++] = yearPrefix.charAt(0), - maskset.buffer[pos++] = yearPrefix.charAt(1), { - pos: pos - }; - } - return isValid; - }, - cardinality: 1 - }, { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear); - if (!strict && !isValid) { - var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2); - if (isValid = opts.isInYearRange(chrs[0] + yearPrefix[1] + chrs[1], opts.yearrange.minyear, opts.yearrange.maxyear)) return maskset.buffer[pos++] = yearPrefix.charAt(1), - { - pos: pos - }; - if (yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2), - opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) { - var dayMonthValue = maskset.buffer.join("").substr(0, 6); - if (dayMonthValue !== opts.leapday) isValid = !0; else { - var year = parseInt(chrs, 10); - isValid = year % 4 === 0 ? year % 100 === 0 ? year % 400 === 0 ? !0 : !1 : !0 : !1; - } - } else isValid = !1; - if (isValid) return maskset.buffer[pos - 1] = yearPrefix.charAt(0), maskset.buffer[pos++] = yearPrefix.charAt(1), - maskset.buffer[pos++] = chrs.charAt(0), { - refreshFromBuffer: { - start: pos - 3, - end: pos - }, - pos: pos - }; - } - return isValid; - }, - cardinality: 2 - }, { - validator: function(chrs, maskset, pos, strict, opts) { - return opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear); - }, - cardinality: 3 - } ] - } - }, - insertMode: !1, - autoUnmask: !1 - }, - "mm/dd/yyyy": { - placeholder: "mm/dd/yyyy", - alias: "dd/mm/yyyy", - regex: { - val2pre: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[13-9]|1[012])" + escapedSeparator + "[0-3])|(02" + escapedSeparator + "[0-2])"); - }, - val2: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "(0[1-9]|[12][0-9]))|((0[13-9]|1[012])" + escapedSeparator + "30)|((0[13578]|1[02])" + escapedSeparator + "31)"); - }, - val1pre: new RegExp("[01]"), - val1: new RegExp("0[1-9]|1[012]") - }, - leapday: "02/29/", - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) { - var today = new Date(); - $input.val((today.getMonth() + 1).toString() + today.getDate().toString() + today.getFullYear().toString()), - $input.trigger("setvalue"); - } - } - }, - "yyyy/mm/dd": { - mask: "y/1/2", - placeholder: "yyyy/mm/dd", - alias: "mm/dd/yyyy", - leapday: "/02/29", - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) { - var today = new Date(); - $input.val(today.getFullYear().toString() + (today.getMonth() + 1).toString() + today.getDate().toString()), - $input.trigger("setvalue"); - } - } - }, - "dd.mm.yyyy": { - mask: "1.2.y", - placeholder: "dd.mm.yyyy", - leapday: "29.02.", - separator: ".", - alias: "dd/mm/yyyy" - }, - "dd-mm-yyyy": { - mask: "1-2-y", - placeholder: "dd-mm-yyyy", - leapday: "29-02-", - separator: "-", - alias: "dd/mm/yyyy" - }, - "mm.dd.yyyy": { - mask: "1.2.y", - placeholder: "mm.dd.yyyy", - leapday: "02.29.", - separator: ".", - alias: "mm/dd/yyyy" - }, - "mm-dd-yyyy": { - mask: "1-2-y", - placeholder: "mm-dd-yyyy", - leapday: "02-29-", - separator: "-", - alias: "mm/dd/yyyy" - }, - "yyyy.mm.dd": { - mask: "y.1.2", - placeholder: "yyyy.mm.dd", - leapday: ".02.29", - separator: ".", - alias: "yyyy/mm/dd" - }, - "yyyy-mm-dd": { - mask: "y-1-2", - placeholder: "yyyy-mm-dd", - leapday: "-02-29", - separator: "-", - alias: "yyyy/mm/dd" - }, - datetime: { - mask: "1/2/y h:s", - placeholder: "dd/mm/yyyy hh:mm", - alias: "dd/mm/yyyy", - regex: { - hrspre: new RegExp("[012]"), - hrs24: new RegExp("2[0-4]|1[3-9]"), - hrs: new RegExp("[01][0-9]|2[0-4]"), - ampm: new RegExp("^[a|p|A|P][m|M]"), - mspre: new RegExp("[0-5]"), - ms: new RegExp("[0-5][0-9]") - }, - timeseparator: ":", - hourFormat: "24", - definitions: { - h: { - validator: function(chrs, maskset, pos, strict, opts) { - if ("24" === opts.hourFormat && 24 === parseInt(chrs, 10)) return maskset.buffer[pos - 1] = "0", - maskset.buffer[pos] = "0", { - refreshFromBuffer: { - start: pos - 1, - end: pos - }, - c: "0" - }; - var isValid = opts.regex.hrs.test(chrs); - if (!strict && !isValid && (chrs.charAt(1) === opts.timeseparator || -1 !== "-.:".indexOf(chrs.charAt(1))) && (isValid = opts.regex.hrs.test("0" + chrs.charAt(0)))) return maskset.buffer[pos - 1] = "0", - maskset.buffer[pos] = chrs.charAt(0), pos++, { - refreshFromBuffer: { - start: pos - 2, - end: pos - }, - pos: pos, - c: opts.timeseparator - }; - if (isValid && "24" !== opts.hourFormat && opts.regex.hrs24.test(chrs)) { - var tmp = parseInt(chrs, 10); - return 24 === tmp ? (maskset.buffer[pos + 5] = "a", maskset.buffer[pos + 6] = "m") : (maskset.buffer[pos + 5] = "p", - maskset.buffer[pos + 6] = "m"), tmp -= 12, 10 > tmp ? (maskset.buffer[pos] = tmp.toString(), - maskset.buffer[pos - 1] = "0") : (maskset.buffer[pos] = tmp.toString().charAt(1), - maskset.buffer[pos - 1] = tmp.toString().charAt(0)), { - refreshFromBuffer: { - start: pos - 1, - end: pos + 6 - }, - c: maskset.buffer[pos] - }; - } - return isValid; - }, - cardinality: 2, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.regex.hrspre.test(chrs); - return strict || isValid || !(isValid = opts.regex.hrs.test("0" + chrs)) ? isValid : (maskset.buffer[pos] = "0", - pos++, { - pos: pos - }); - }, - cardinality: 1 - } ] - }, - s: { - validator: "[0-5][0-9]", - cardinality: 2, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.regex.mspre.test(chrs); - return strict || isValid || !(isValid = opts.regex.ms.test("0" + chrs)) ? isValid : (maskset.buffer[pos] = "0", - pos++, { - pos: pos - }); - }, - cardinality: 1 - } ] - }, - t: { - validator: function(chrs, maskset, pos, strict, opts) { - return opts.regex.ampm.test(chrs + "m"); - }, - casing: "lower", - cardinality: 1 - } - }, - insertMode: !1, - autoUnmask: !1 - }, - datetime12: { - mask: "1/2/y h:s t\\m", - placeholder: "dd/mm/yyyy hh:mm xm", - alias: "datetime", - hourFormat: "12" - }, - "mm/dd/yyyy hh:mm xm": { - mask: "1/2/y h:s t\\m", - placeholder: "mm/dd/yyyy hh:mm xm", - alias: "datetime12", - regex: { - val2pre: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[13-9]|1[012])" + escapedSeparator + "[0-3])|(02" + escapedSeparator + "[0-2])"); - }, - val2: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "(0[1-9]|[12][0-9]))|((0[13-9]|1[012])" + escapedSeparator + "30)|((0[13578]|1[02])" + escapedSeparator + "31)"); - }, - val1pre: new RegExp("[01]"), - val1: new RegExp("0[1-9]|1[012]") - }, - leapday: "02/29/", - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) { - var today = new Date(); - $input.val((today.getMonth() + 1).toString() + today.getDate().toString() + today.getFullYear().toString()), - $input.trigger("setvalue"); - } - } - }, - "hh:mm t": { - mask: "h:s t\\m", - placeholder: "hh:mm xm", - alias: "datetime", - hourFormat: "12" - }, - "h:s t": { - mask: "h:s t\\m", - placeholder: "hh:mm xm", - alias: "datetime", - hourFormat: "12" - }, - "hh:mm:ss": { - mask: "h:s:s", - placeholder: "hh:mm:ss", - alias: "datetime", - autoUnmask: !1 - }, - "hh:mm": { - mask: "h:s", - placeholder: "hh:mm", - alias: "datetime", - autoUnmask: !1 - }, - date: { - alias: "dd/mm/yyyy" - }, - "mm/yyyy": { - mask: "1/y", - placeholder: "mm/yyyy", - leapday: "donotuse", - separator: "/", - alias: "mm/dd/yyyy" - }, - shamsi: { - regex: { - val2pre: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "[0-3])"); - }, - val2: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "(0[1-9]|[12][0-9]))|((0[1-9]|1[012])" + escapedSeparator + "30)|((0[1-6])" + escapedSeparator + "31)"); - }, - val1pre: new RegExp("[01]"), - val1: new RegExp("0[1-9]|1[012]") - }, - yearrange: { - minyear: 1300, - maxyear: 1499 - }, - mask: "y/1/2", - leapday: "/12/30", - placeholder: "yyyy/mm/dd", - alias: "mm/dd/yyyy", - clearIncomplete: !0 - } - }), Inputmask; -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.dependencyLib.jquery.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.dependencyLib.jquery.js deleted file mode 100644 index e3aeb2c85..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.dependencyLib.jquery.js +++ /dev/null @@ -1,12 +0,0 @@ -/*! -* inputmask.dependencyLib.jquery.js -* https://github.com/RobinHerbots/jquery.inputmask -* Copyright (c) 2010 - 2016 Robin Herbots -* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -* Version: 3.3.1 -*/ -!function(factory) { - "function" == typeof define && define.amd ? define([ "jquery" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery")) : factory(jQuery); -}(function($) { - return window.dependencyLib = $, $; -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.extensions.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.extensions.js deleted file mode 100644 index 292889ba0..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.extensions.js +++ /dev/null @@ -1,93 +0,0 @@ -/*! -* inputmask.extensions.js -* https://github.com/RobinHerbots/jquery.inputmask -* Copyright (c) 2010 - 2016 Robin Herbots -* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -* Version: 3.3.1 -*/ -!function(factory) { - "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib.jquery"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask); -}(function($, Inputmask) { - return Inputmask.extendDefinitions({ - A: { - validator: "[A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]", - cardinality: 1, - casing: "upper" - }, - "&": { - validator: "[0-9A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]", - cardinality: 1, - casing: "upper" - }, - "#": { - validator: "[0-9A-Fa-f]", - cardinality: 1, - casing: "upper" - } - }), Inputmask.extendAliases({ - url: { - definitions: { - i: { - validator: ".", - cardinality: 1 - } - }, - mask: "(\\http://)|(\\http\\s://)|(ftp://)|(ftp\\s://)i{+}", - insertMode: !1, - autoUnmask: !1 - }, - ip: { - mask: "i[i[i]].i[i[i]].i[i[i]].i[i[i]]", - definitions: { - i: { - validator: function(chrs, maskset, pos, strict, opts) { - return pos - 1 > -1 && "." !== maskset.buffer[pos - 1] ? (chrs = maskset.buffer[pos - 1] + chrs, - chrs = pos - 2 > -1 && "." !== maskset.buffer[pos - 2] ? maskset.buffer[pos - 2] + chrs : "0" + chrs) : chrs = "00" + chrs, - new RegExp("25[0-5]|2[0-4][0-9]|[01][0-9][0-9]").test(chrs); - }, - cardinality: 1 - } - }, - onUnMask: function(maskedValue, unmaskedValue, opts) { - return maskedValue; - } - }, - email: { - mask: "*{1,64}[.*{1,64}][.*{1,64}][.*{1,63}]@-{1,63}.-{1,63}[.-{1,63}][.-{1,63}]", - greedy: !1, - onBeforePaste: function(pastedValue, opts) { - return pastedValue = pastedValue.toLowerCase(), pastedValue.replace("mailto:", ""); - }, - definitions: { - "*": { - validator: "[0-9A-Za-z!#$%&'*+/=?^_`{|}~-]", - cardinality: 1, - casing: "lower" - }, - "-": { - validator: "[0-9A-Za-z-]", - cardinality: 1, - casing: "lower" - } - }, - onUnMask: function(maskedValue, unmaskedValue, opts) { - return maskedValue; - } - }, - mac: { - mask: "##:##:##:##:##:##" - }, - vin: { - mask: "V{13}9{4}", - definitions: { - V: { - validator: "[A-HJ-NPR-Za-hj-npr-z\\d]", - cardinality: 1, - casing: "upper" - } - }, - clearIncomplete: !0, - autoUnmask: !0 - } - }), Inputmask; -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.js deleted file mode 100644 index b1c3774b3..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.js +++ /dev/null @@ -1,1465 +0,0 @@ -/*! -* inputmask.js -* https://github.com/RobinHerbots/jquery.inputmask -* Copyright (c) 2010 - 2016 Robin Herbots -* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -* Version: 3.3.1 -*/ -!function(factory) { - "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib.jquery")) : factory(window.dependencyLib || jQuery); -}(function($) { - function Inputmask(alias, options) { - return this instanceof Inputmask ? ($.isPlainObject(alias) ? options = alias : (options = options || {}, - options.alias = alias), this.el = void 0, this.opts = $.extend(!0, {}, this.defaults, options), - this.noMasksCache = options && void 0 !== options.definitions, this.userOptions = options || {}, - this.events = {}, void resolveAlias(this.opts.alias, options, this.opts)) : new Inputmask(alias, options); - } - function isInputEventSupported(eventName) { - var el = document.createElement("input"), evName = "on" + eventName, isSupported = evName in el; - return isSupported || (el.setAttribute(evName, "return;"), isSupported = "function" == typeof el[evName]), - el = null, isSupported; - } - function isElementTypeSupported(input, opts) { - var elementType = input.getAttribute("type"), isSupported = "INPUT" === input.tagName && -1 !== $.inArray(elementType, opts.supportsInputType) || input.isContentEditable || "TEXTAREA" === input.tagName; - if (!isSupported && "INPUT" === input.tagName) { - var el = document.createElement("input"); - el.setAttribute("type", elementType), isSupported = "text" === el.type, el = null; - } - return isSupported; - } - function resolveAlias(aliasStr, options, opts) { - var aliasDefinition = opts.aliases[aliasStr]; - return aliasDefinition ? (aliasDefinition.alias && resolveAlias(aliasDefinition.alias, void 0, opts), - $.extend(!0, opts, aliasDefinition), $.extend(!0, opts, options), !0) : (null === opts.mask && (opts.mask = aliasStr), - !1); - } - function importAttributeOptions(npt, opts, userOptions) { - function importOption(option, optionData) { - optionData = void 0 !== optionData ? optionData : npt.getAttribute("data-inputmask-" + option), - null !== optionData && ("string" == typeof optionData && (0 === option.indexOf("on") ? optionData = window[optionData] : "false" === optionData ? optionData = !1 : "true" === optionData && (optionData = !0)), - userOptions[option] = optionData); - } - var option, dataoptions, optionData, p, attrOptions = npt.getAttribute("data-inputmask"); - if (attrOptions && "" !== attrOptions && (attrOptions = attrOptions.replace(new RegExp("'", "g"), '"'), - dataoptions = JSON.parse("{" + attrOptions + "}")), dataoptions) { - optionData = void 0; - for (p in dataoptions) if ("alias" === p.toLowerCase()) { - optionData = dataoptions[p]; - break; - } - } - importOption("alias", optionData), userOptions.alias && resolveAlias(userOptions.alias, userOptions, opts); - for (option in opts) { - if (dataoptions) { - optionData = void 0; - for (p in dataoptions) if (p.toLowerCase() === option.toLowerCase()) { - optionData = dataoptions[p]; - break; - } - } - importOption(option, optionData); - } - return $.extend(!0, opts, userOptions), opts; - } - function generateMaskSet(opts, nocache) { - function analyseMask(mask) { - function MaskToken(isGroup, isOptional, isQuantifier, isAlternator) { - this.matches = [], this.isGroup = isGroup || !1, this.isOptional = isOptional || !1, - this.isQuantifier = isQuantifier || !1, this.isAlternator = isAlternator || !1, - this.quantifier = { - min: 1, - max: 1 - }; - } - function insertTestDefinition(mtoken, element, position) { - var maskdef = opts.definitions[element]; - position = void 0 !== position ? position : mtoken.matches.length; - var prevMatch = mtoken.matches[position - 1]; - if (maskdef && !escaped) { - maskdef.placeholder = $.isFunction(maskdef.placeholder) ? maskdef.placeholder(opts) : maskdef.placeholder; - for (var prevalidators = maskdef.prevalidator, prevalidatorsL = prevalidators ? prevalidators.length : 0, i = 1; i < maskdef.cardinality; i++) { - var prevalidator = prevalidatorsL >= i ? prevalidators[i - 1] : [], validator = prevalidator.validator, cardinality = prevalidator.cardinality; - mtoken.matches.splice(position++, 0, { - fn: validator ? "string" == typeof validator ? new RegExp(validator) : new function() { - this.test = validator; - }() : new RegExp("."), - cardinality: cardinality ? cardinality : 1, - optionality: mtoken.isOptional, - newBlockMarker: void 0 === prevMatch || prevMatch.def !== (maskdef.definitionSymbol || element), - casing: maskdef.casing, - def: maskdef.definitionSymbol || element, - placeholder: maskdef.placeholder, - mask: element - }), prevMatch = mtoken.matches[position - 1]; - } - mtoken.matches.splice(position++, 0, { - fn: maskdef.validator ? "string" == typeof maskdef.validator ? new RegExp(maskdef.validator) : new function() { - this.test = maskdef.validator; - }() : new RegExp("."), - cardinality: maskdef.cardinality, - optionality: mtoken.isOptional, - newBlockMarker: void 0 === prevMatch || prevMatch.def !== (maskdef.definitionSymbol || element), - casing: maskdef.casing, - def: maskdef.definitionSymbol || element, - placeholder: maskdef.placeholder, - mask: element - }); - } else mtoken.matches.splice(position++, 0, { - fn: null, - cardinality: 0, - optionality: mtoken.isOptional, - newBlockMarker: void 0 === prevMatch || prevMatch.def !== element, - casing: null, - def: opts.staticDefinitionSymbol || element, - placeholder: void 0 !== opts.staticDefinitionSymbol ? element : void 0, - mask: element - }), escaped = !1; - } - function verifyGroupMarker(lastMatch, isOpenGroup) { - lastMatch.isGroup && (lastMatch.isGroup = !1, insertTestDefinition(lastMatch, opts.groupmarker.start, 0), - isOpenGroup !== !0 && insertTestDefinition(lastMatch, opts.groupmarker.end)); - } - function maskCurrentToken(m, currentToken, lastMatch, extraCondition) { - currentToken.matches.length > 0 && (void 0 === extraCondition || extraCondition) && (lastMatch = currentToken.matches[currentToken.matches.length - 1], - verifyGroupMarker(lastMatch)), insertTestDefinition(currentToken, m); - } - function defaultCase() { - if (openenings.length > 0) { - if (currentOpeningToken = openenings[openenings.length - 1], maskCurrentToken(m, currentOpeningToken, lastMatch, !currentOpeningToken.isAlternator), - currentOpeningToken.isAlternator) { - alternator = openenings.pop(); - for (var mndx = 0; mndx < alternator.matches.length; mndx++) alternator.matches[mndx].isGroup = !1; - openenings.length > 0 ? (currentOpeningToken = openenings[openenings.length - 1], - currentOpeningToken.matches.push(alternator)) : currentToken.matches.push(alternator); - } - } else maskCurrentToken(m, currentToken, lastMatch); - } - function reverseTokens(maskToken) { - function reverseStatic(st) { - return st === opts.optionalmarker.start ? st = opts.optionalmarker.end : st === opts.optionalmarker.end ? st = opts.optionalmarker.start : st === opts.groupmarker.start ? st = opts.groupmarker.end : st === opts.groupmarker.end && (st = opts.groupmarker.start), - st; - } - maskToken.matches = maskToken.matches.reverse(); - for (var match in maskToken.matches) { - var intMatch = parseInt(match); - if (maskToken.matches[match].isQuantifier && maskToken.matches[intMatch + 1] && maskToken.matches[intMatch + 1].isGroup) { - var qt = maskToken.matches[match]; - maskToken.matches.splice(match, 1), maskToken.matches.splice(intMatch + 1, 0, qt); - } - void 0 !== maskToken.matches[match].matches ? maskToken.matches[match] = reverseTokens(maskToken.matches[match]) : maskToken.matches[match] = reverseStatic(maskToken.matches[match]); - } - return maskToken; - } - for (var match, m, openingToken, currentOpeningToken, alternator, lastMatch, groupToken, tokenizer = /(?:[?*+]|\{[0-9\+\*]+(?:,[0-9\+\*]*)?\})|[^.?*+^${[]()|\\]+|./g, escaped = !1, currentToken = new MaskToken(), openenings = [], maskTokens = []; match = tokenizer.exec(mask); ) if (m = match[0], - escaped) defaultCase(); else switch (m.charAt(0)) { - case opts.escapeChar: - escaped = !0; - break; - - case opts.optionalmarker.end: - case opts.groupmarker.end: - if (openingToken = openenings.pop(), void 0 !== openingToken) if (openenings.length > 0) { - if (currentOpeningToken = openenings[openenings.length - 1], currentOpeningToken.matches.push(openingToken), - currentOpeningToken.isAlternator) { - alternator = openenings.pop(); - for (var mndx = 0; mndx < alternator.matches.length; mndx++) alternator.matches[mndx].isGroup = !1; - openenings.length > 0 ? (currentOpeningToken = openenings[openenings.length - 1], - currentOpeningToken.matches.push(alternator)) : currentToken.matches.push(alternator); - } - } else currentToken.matches.push(openingToken); else defaultCase(); - break; - - case opts.optionalmarker.start: - openenings.push(new MaskToken(!1, !0)); - break; - - case opts.groupmarker.start: - openenings.push(new MaskToken(!0)); - break; - - case opts.quantifiermarker.start: - var quantifier = new MaskToken(!1, !1, !0); - m = m.replace(/[{}]/g, ""); - var mq = m.split(","), mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), mq1 = 1 === mq.length ? mq0 : isNaN(mq[1]) ? mq[1] : parseInt(mq[1]); - if (("*" === mq1 || "+" === mq1) && (mq0 = "*" === mq1 ? 0 : 1), quantifier.quantifier = { - min: mq0, - max: mq1 - }, openenings.length > 0) { - var matches = openenings[openenings.length - 1].matches; - match = matches.pop(), match.isGroup || (groupToken = new MaskToken(!0), groupToken.matches.push(match), - match = groupToken), matches.push(match), matches.push(quantifier); - } else match = currentToken.matches.pop(), match.isGroup || (groupToken = new MaskToken(!0), - groupToken.matches.push(match), match = groupToken), currentToken.matches.push(match), - currentToken.matches.push(quantifier); - break; - - case opts.alternatormarker: - openenings.length > 0 ? (currentOpeningToken = openenings[openenings.length - 1], - lastMatch = currentOpeningToken.matches.pop()) : lastMatch = currentToken.matches.pop(), - lastMatch.isAlternator ? openenings.push(lastMatch) : (alternator = new MaskToken(!1, !1, !1, !0), - alternator.matches.push(lastMatch), openenings.push(alternator)); - break; - - default: - defaultCase(); - } - for (;openenings.length > 0; ) openingToken = openenings.pop(), verifyGroupMarker(openingToken, !0), - currentToken.matches.push(openingToken); - return currentToken.matches.length > 0 && (lastMatch = currentToken.matches[currentToken.matches.length - 1], - verifyGroupMarker(lastMatch), maskTokens.push(currentToken)), opts.numericInput && reverseTokens(maskTokens[0]), - maskTokens; - } - function generateMask(mask, metadata) { - if (null === mask || "" === mask) return void 0; - if (1 === mask.length && opts.greedy === !1 && 0 !== opts.repeat && (opts.placeholder = ""), - opts.repeat > 0 || "*" === opts.repeat || "+" === opts.repeat) { - var repeatStart = "*" === opts.repeat ? 0 : "+" === opts.repeat ? 1 : opts.repeat; - mask = opts.groupmarker.start + mask + opts.groupmarker.end + opts.quantifiermarker.start + repeatStart + "," + opts.repeat + opts.quantifiermarker.end; - } - var masksetDefinition; - return void 0 === Inputmask.prototype.masksCache[mask] || nocache === !0 ? (masksetDefinition = { - mask: mask, - maskToken: analyseMask(mask), - validPositions: {}, - _buffer: void 0, - buffer: void 0, - tests: {}, - metadata: metadata - }, nocache !== !0 && (Inputmask.prototype.masksCache[opts.numericInput ? mask.split("").reverse().join("") : mask] = masksetDefinition, - masksetDefinition = $.extend(!0, {}, Inputmask.prototype.masksCache[opts.numericInput ? mask.split("").reverse().join("") : mask]))) : masksetDefinition = $.extend(!0, {}, Inputmask.prototype.masksCache[opts.numericInput ? mask.split("").reverse().join("") : mask]), - masksetDefinition; - } - function preProcessMask(mask) { - return mask = mask.toString(); - } - var ms; - if ($.isFunction(opts.mask) && (opts.mask = opts.mask(opts)), $.isArray(opts.mask)) { - if (opts.mask.length > 1) { - opts.keepStatic = null === opts.keepStatic ? !0 : opts.keepStatic; - var altMask = "("; - return $.each(opts.numericInput ? opts.mask.reverse() : opts.mask, function(ndx, msk) { - altMask.length > 1 && (altMask += ")|("), altMask += preProcessMask(void 0 === msk.mask || $.isFunction(msk.mask) ? msk : msk.mask); - }), altMask += ")", generateMask(altMask, opts.mask); - } - opts.mask = opts.mask.pop(); - } - return opts.mask && (ms = void 0 === opts.mask.mask || $.isFunction(opts.mask.mask) ? generateMask(preProcessMask(opts.mask), opts.mask) : generateMask(preProcessMask(opts.mask.mask), opts.mask)), - ms; - } - function maskScope(actionObj, maskset, opts) { - function getMaskTemplate(baseOnInput, minimalPos, includeInput) { - minimalPos = minimalPos || 0; - var ndxIntlzr, test, testPos, maskTemplate = [], pos = 0, lvp = getLastValidPosition(); - do { - if (baseOnInput === !0 && getMaskSet().validPositions[pos]) { - var validPos = getMaskSet().validPositions[pos]; - test = validPos.match, ndxIntlzr = validPos.locator.slice(), maskTemplate.push(includeInput === !0 ? validPos.input : getPlaceholder(pos, test)); - } else testPos = getTestTemplate(pos, ndxIntlzr, pos - 1), test = testPos.match, - ndxIntlzr = testPos.locator.slice(), (opts.jitMasking === !1 || lvp > pos || isFinite(opts.jitMasking) && opts.jitMasking > pos) && maskTemplate.push(getPlaceholder(pos, test)); - pos++; - } while ((void 0 === maxLength || maxLength > pos - 1) && null !== test.fn || null === test.fn && "" !== test.def || minimalPos >= pos); - return "" === maskTemplate[maskTemplate.length - 1] && maskTemplate.pop(), maskTemplate; - } - function getMaskSet() { - return maskset; - } - function resetMaskSet(soft) { - var maskset = getMaskSet(); - maskset.buffer = void 0, soft !== !0 && (maskset.tests = {}, maskset._buffer = void 0, - maskset.validPositions = {}, maskset.p = 0); - } - function getLastValidPosition(closestTo, strict, validPositions) { - var before = -1, after = -1, valids = validPositions || getMaskSet().validPositions; - void 0 === closestTo && (closestTo = -1); - for (var posNdx in valids) { - var psNdx = parseInt(posNdx); - valids[psNdx] && (strict || null !== valids[psNdx].match.fn) && (closestTo >= psNdx && (before = psNdx), - psNdx >= closestTo && (after = psNdx)); - } - return -1 !== before && closestTo - before > 1 || closestTo > after ? before : after; - } - function setValidPosition(pos, validTest, fromSetValid, isSelection) { - if (isSelection || opts.insertMode && void 0 !== getMaskSet().validPositions[pos] && void 0 === fromSetValid) { - var i, positionsClone = $.extend(!0, {}, getMaskSet().validPositions), lvp = getLastValidPosition(); - for (i = pos; lvp >= i; i++) delete getMaskSet().validPositions[i]; - getMaskSet().validPositions[pos] = validTest; - var j, valid = !0, vps = getMaskSet().validPositions, needsValidation = !1; - for (i = j = pos; lvp >= i; i++) { - var t = positionsClone[i]; - if (void 0 !== t) for (var posMatch = j, prevPosMatch = -1; posMatch < getMaskLength() && (null == t.match.fn && vps[i] && (vps[i].match.optionalQuantifier === !0 || vps[i].match.optionality === !0) || null != t.match.fn); ) { - if (null === t.match.fn || !opts.keepStatic && vps[i] && (void 0 !== vps[i + 1] && getTests(i + 1, vps[i].locator.slice(), i).length > 1 || void 0 !== vps[i].alternation) ? posMatch++ : posMatch = seekNext(j), - needsValidation === !1 && positionsClone[posMatch] && positionsClone[posMatch].match.def === t.match.def) { - getMaskSet().validPositions[posMatch] = $.extend(!0, {}, positionsClone[posMatch]), - getMaskSet().validPositions[posMatch].input = t.input, j = posMatch, valid = !0; - break; - } - if (positionCanMatchDefinition(posMatch, t.match.def)) { - var result = isValid(posMatch, t.input, !0, !0); - if (valid = result !== !1, j = result.caret || result.insert ? getLastValidPosition() : posMatch, - needsValidation = !0, valid) break; - } else { - if (valid = null == t.match.fn, prevPosMatch === posMatch) break; - prevPosMatch = posMatch; - } - } - if (!valid) break; - } - if (!valid) return getMaskSet().validPositions = $.extend(!0, {}, positionsClone), - resetMaskSet(!0), !1; - } else getMaskSet().validPositions[pos] = validTest; - return resetMaskSet(!0), !0; - } - function stripValidPositions(start, end, nocheck, strict) { - function IsEnclosedStatic(pos) { - var posMatch = getMaskSet().validPositions[pos]; - if (void 0 !== posMatch && null === posMatch.match.fn) { - var prevMatch = getMaskSet().validPositions[pos - 1], nextMatch = getMaskSet().validPositions[pos + 1]; - return void 0 !== prevMatch && void 0 !== nextMatch; - } - return !1; - } - var i, startPos = start, positionsClone = $.extend(!0, {}, getMaskSet().validPositions), needsValidation = !1; - for (getMaskSet().p = start, i = end - 1; i >= startPos; i--) void 0 !== getMaskSet().validPositions[i] && (nocheck === !0 || !IsEnclosedStatic(i) && opts.canClearPosition(getMaskSet(), i, getLastValidPosition(), strict, opts) !== !1) && delete getMaskSet().validPositions[i]; - for (resetMaskSet(!0), i = startPos + 1; i <= getLastValidPosition(); ) { - for (;void 0 !== getMaskSet().validPositions[startPos]; ) startPos++; - var s = getMaskSet().validPositions[startPos]; - if (startPos > i && (i = startPos + 1), void 0 === getMaskSet().validPositions[i] && isMask(i) || void 0 !== s) i++; else { - var t = getTestTemplate(i); - needsValidation === !1 && positionsClone[startPos] && positionsClone[startPos].match.def === t.match.def ? (getMaskSet().validPositions[startPos] = $.extend(!0, {}, positionsClone[startPos]), - getMaskSet().validPositions[startPos].input = t.input, delete getMaskSet().validPositions[i], - i++) : positionCanMatchDefinition(startPos, t.match.def) ? isValid(startPos, t.input || getPlaceholder(i), !0) !== !1 && (delete getMaskSet().validPositions[i], - i++, needsValidation = !0) : isMask(i) || (i++, startPos--), startPos++; - } - } - resetMaskSet(!0); - } - function getTestTemplate(pos, ndxIntlzr, tstPs) { - var testPos = getMaskSet().validPositions[pos]; - if (void 0 === testPos) for (var testPositions = getTests(pos, ndxIntlzr, tstPs), lvp = getLastValidPosition(), lvTest = getMaskSet().validPositions[lvp] || getTests(0)[0], lvTestAltArr = void 0 !== lvTest.alternation ? lvTest.locator[lvTest.alternation].toString().split(",") : [], ndx = 0; ndx < testPositions.length && (testPos = testPositions[ndx], - !(testPos.match && (opts.greedy && testPos.match.optionalQuantifier !== !0 || (testPos.match.optionality === !1 || testPos.match.newBlockMarker === !1) && testPos.match.optionalQuantifier !== !0) && (void 0 === lvTest.alternation || lvTest.alternation !== testPos.alternation || void 0 !== testPos.locator[lvTest.alternation] && checkAlternationMatch(testPos.locator[lvTest.alternation].toString().split(","), lvTestAltArr)))); ndx++) ; - return testPos; - } - function getTest(pos) { - return getMaskSet().validPositions[pos] ? getMaskSet().validPositions[pos].match : getTests(pos)[0].match; - } - function positionCanMatchDefinition(pos, def) { - for (var valid = !1, tests = getTests(pos), tndx = 0; tndx < tests.length; tndx++) if (tests[tndx].match && tests[tndx].match.def === def) { - valid = !0; - break; - } - return valid; - } - function selectBestMatch(pos, alternateNdx) { - var bestMatch, indexPos; - return (getMaskSet().tests[pos] || getMaskSet().validPositions[pos]) && $.each(getMaskSet().tests[pos] || [ getMaskSet().validPositions[pos] ], function(ndx, lmnt) { - var ndxPos = lmnt.alternation ? lmnt.locator[lmnt.alternation].toString().indexOf(alternateNdx) : -1; - (void 0 === indexPos || indexPos > ndxPos) && -1 !== ndxPos && (bestMatch = lmnt, - indexPos = ndxPos); - }), bestMatch; - } - function getTests(pos, ndxIntlzr, tstPs) { - function resolveTestFromToken(maskToken, ndxInitializer, loopNdx, quantifierRecurse) { - function handleMatch(match, loopNdx, quantifierRecurse) { - function isFirstMatch(latestMatch, tokenGroup) { - var firstMatch = 0 === $.inArray(latestMatch, tokenGroup.matches); - return firstMatch || $.each(tokenGroup.matches, function(ndx, match) { - return match.isQuantifier === !0 && (firstMatch = isFirstMatch(latestMatch, tokenGroup.matches[ndx - 1])) ? !1 : void 0; - }), firstMatch; - } - function resolveNdxInitializer(pos, alternateNdx) { - var bestMatch = selectBestMatch(pos, alternateNdx); - return bestMatch ? bestMatch.locator.slice(bestMatch.alternation + 1) : []; - } - if (testPos > 1e4) throw "Inputmask: There is probably an error in your mask definition or in the code. Create an issue on github with an example of the mask you are using. " + getMaskSet().mask; - if (testPos === pos && void 0 === match.matches) return matches.push({ - match: match, - locator: loopNdx.reverse(), - cd: cacheDependency - }), !0; - if (void 0 !== match.matches) { - if (match.isGroup && quantifierRecurse !== match) { - if (match = handleMatch(maskToken.matches[$.inArray(match, maskToken.matches) + 1], loopNdx)) return !0; - } else if (match.isOptional) { - var optionalToken = match; - if (match = resolveTestFromToken(match, ndxInitializer, loopNdx, quantifierRecurse)) { - if (latestMatch = matches[matches.length - 1].match, !isFirstMatch(latestMatch, optionalToken)) return !0; - insertStop = !0, testPos = pos; - } - } else if (match.isAlternator) { - var maltMatches, alternateToken = match, malternateMatches = [], currentMatches = matches.slice(), loopNdxCnt = loopNdx.length, altIndex = ndxInitializer.length > 0 ? ndxInitializer.shift() : -1; - if (-1 === altIndex || "string" == typeof altIndex) { - var amndx, currentPos = testPos, ndxInitializerClone = ndxInitializer.slice(), altIndexArr = []; - if ("string" == typeof altIndex) altIndexArr = altIndex.split(","); else for (amndx = 0; amndx < alternateToken.matches.length; amndx++) altIndexArr.push(amndx); - for (var ndx = 0; ndx < altIndexArr.length; ndx++) { - if (amndx = parseInt(altIndexArr[ndx]), matches = [], ndxInitializer = resolveNdxInitializer(testPos, amndx), - match = handleMatch(alternateToken.matches[amndx] || maskToken.matches[amndx], [ amndx ].concat(loopNdx), quantifierRecurse) || match, - match !== !0 && void 0 !== match && altIndexArr[altIndexArr.length - 1] < alternateToken.matches.length) { - var ntndx = $.inArray(match, maskToken.matches) + 1; - maskToken.matches.length > ntndx && (match = handleMatch(maskToken.matches[ntndx], [ ntndx ].concat(loopNdx.slice(1, loopNdx.length)), quantifierRecurse), - match && (altIndexArr.push(ntndx.toString()), $.each(matches, function(ndx, lmnt) { - lmnt.alternation = loopNdx.length - 1; - }))); - } - maltMatches = matches.slice(), testPos = currentPos, matches = []; - for (var i = 0; i < ndxInitializerClone.length; i++) ndxInitializer[i] = ndxInitializerClone[i]; - for (var ndx1 = 0; ndx1 < maltMatches.length; ndx1++) { - var altMatch = maltMatches[ndx1]; - altMatch.alternation = altMatch.alternation || loopNdxCnt; - for (var ndx2 = 0; ndx2 < malternateMatches.length; ndx2++) { - var altMatch2 = malternateMatches[ndx2]; - if (altMatch.match.def === altMatch2.match.def && ("string" != typeof altIndex || -1 !== $.inArray(altMatch.locator[altMatch.alternation].toString(), altIndexArr))) { - altMatch.match.mask === altMatch2.match.mask && (maltMatches.splice(ndx1, 1), ndx1--), - -1 === altMatch2.locator[altMatch.alternation].toString().indexOf(altMatch.locator[altMatch.alternation]) && (altMatch2.locator[altMatch.alternation] = altMatch2.locator[altMatch.alternation] + "," + altMatch.locator[altMatch.alternation], - altMatch2.alternation = altMatch.alternation); - break; - } - } - } - malternateMatches = malternateMatches.concat(maltMatches); - } - "string" == typeof altIndex && (malternateMatches = $.map(malternateMatches, function(lmnt, ndx) { - if (isFinite(ndx)) { - var mamatch, alternation = lmnt.alternation, altLocArr = lmnt.locator[alternation].toString().split(","); - lmnt.locator[alternation] = void 0, lmnt.alternation = void 0; - for (var alndx = 0; alndx < altLocArr.length; alndx++) mamatch = -1 !== $.inArray(altLocArr[alndx], altIndexArr), - mamatch && (void 0 !== lmnt.locator[alternation] ? (lmnt.locator[alternation] += ",", - lmnt.locator[alternation] += altLocArr[alndx]) : lmnt.locator[alternation] = parseInt(altLocArr[alndx]), - lmnt.alternation = alternation); - if (void 0 !== lmnt.locator[alternation]) return lmnt; - } - })), matches = currentMatches.concat(malternateMatches), testPos = pos, insertStop = matches.length > 0; - } else match = handleMatch(alternateToken.matches[altIndex] || maskToken.matches[altIndex], [ altIndex ].concat(loopNdx), quantifierRecurse); - if (match) return !0; - } else if (match.isQuantifier && quantifierRecurse !== maskToken.matches[$.inArray(match, maskToken.matches) - 1]) for (var qt = match, qndx = ndxInitializer.length > 0 ? ndxInitializer.shift() : 0; qndx < (isNaN(qt.quantifier.max) ? qndx + 1 : qt.quantifier.max) && pos >= testPos; qndx++) { - var tokenGroup = maskToken.matches[$.inArray(qt, maskToken.matches) - 1]; - if (match = handleMatch(tokenGroup, [ qndx ].concat(loopNdx), tokenGroup)) { - if (latestMatch = matches[matches.length - 1].match, latestMatch.optionalQuantifier = qndx > qt.quantifier.min - 1, - isFirstMatch(latestMatch, tokenGroup)) { - if (qndx > qt.quantifier.min - 1) { - insertStop = !0, testPos = pos; - break; - } - return !0; - } - return !0; - } - } else if (match = resolveTestFromToken(match, ndxInitializer, loopNdx, quantifierRecurse)) return !0; - } else testPos++; - } - for (var tndx = ndxInitializer.length > 0 ? ndxInitializer.shift() : 0; tndx < maskToken.matches.length; tndx++) if (maskToken.matches[tndx].isQuantifier !== !0) { - var match = handleMatch(maskToken.matches[tndx], [ tndx ].concat(loopNdx), quantifierRecurse); - if (match && testPos === pos) return match; - if (testPos > pos) break; - } - } - function mergeLocators(tests) { - var locator = []; - return $.isArray(tests) || (tests = [ tests ]), void 0 === tests[0].alternation ? locator = tests[0].locator.slice() : $.each(tests, function(ndx, tst) { - if ("" !== tst.def) if (0 === locator.length) locator = tst.locator.slice(); else for (var i = 0; i < locator.length; i++) tst.locator[i] && -1 === locator[i].toString().indexOf(tst.locator[i]) && (locator[i] += "," + tst.locator[i]); - }), locator; - } - var latestMatch, maskTokens = getMaskSet().maskToken, testPos = ndxIntlzr ? tstPs : 0, ndxInitializer = ndxIntlzr || [ 0 ], matches = [], insertStop = !1, cacheDependency = ndxIntlzr ? ndxIntlzr.join("") : ""; - if (pos > -1) { - if (void 0 === ndxIntlzr) { - for (var test, previousPos = pos - 1; void 0 === (test = getMaskSet().validPositions[previousPos] || getMaskSet().tests[previousPos]) && previousPos > -1; ) previousPos--; - void 0 !== test && previousPos > -1 && (ndxInitializer = mergeLocators(test), cacheDependency = ndxInitializer.join(""), - testPos = previousPos); - } - if (getMaskSet().tests[pos] && getMaskSet().tests[pos][0].cd === cacheDependency) return getMaskSet().tests[pos]; - for (var mtndx = ndxInitializer.shift(); mtndx < maskTokens.length; mtndx++) { - var match = resolveTestFromToken(maskTokens[mtndx], ndxInitializer, [ mtndx ]); - if (match && testPos === pos || testPos > pos) break; - } - } - return (0 === matches.length || insertStop) && matches.push({ - match: { - fn: null, - cardinality: 0, - optionality: !0, - casing: null, - def: "" - }, - locator: [] - }), getMaskSet().tests[pos] = $.extend(!0, [], matches), getMaskSet().tests[pos]; - } - function getBufferTemplate() { - return void 0 === getMaskSet()._buffer && (getMaskSet()._buffer = getMaskTemplate(!1, 1)), - getMaskSet()._buffer; - } - function getBuffer(noCache) { - if (void 0 === getMaskSet().buffer || noCache === !0) { - if (noCache === !0) for (var testNdx in getMaskSet().tests) void 0 === getMaskSet().validPositions[testNdx] && delete getMaskSet().tests[testNdx]; - getMaskSet().buffer = getMaskTemplate(!0, getLastValidPosition(), !0); - } - return getMaskSet().buffer; - } - function refreshFromBuffer(start, end, buffer) { - var i; - if (buffer = buffer, start === !0) resetMaskSet(), start = 0, end = buffer.length; else for (i = start; end > i; i++) delete getMaskSet().validPositions[i], - delete getMaskSet().tests[i]; - for (i = start; end > i; i++) resetMaskSet(!0), buffer[i] !== opts.skipOptionalPartCharacter && isValid(i, buffer[i], !0, !0); - } - function casing(elem, test) { - switch (test.casing) { - case "upper": - elem = elem.toUpperCase(); - break; - - case "lower": - elem = elem.toLowerCase(); - } - return elem; - } - function checkAlternationMatch(altArr1, altArr2) { - for (var altArrC = opts.greedy ? altArr2 : altArr2.slice(0, 1), isMatch = !1, alndx = 0; alndx < altArr1.length; alndx++) if (-1 !== $.inArray(altArr1[alndx], altArrC)) { - isMatch = !0; - break; - } - return isMatch; - } - function isValid(pos, c, strict, fromSetValid) { - function isSelection(posObj) { - return isRTL ? posObj.begin - posObj.end > 1 || posObj.begin - posObj.end === 1 && opts.insertMode : posObj.end - posObj.begin > 1 || posObj.end - posObj.begin === 1 && opts.insertMode; - } - function _isValid(position, c, strict, fromSetValid) { - var rslt = !1; - return $.each(getTests(position), function(ndx, tst) { - for (var test = tst.match, loopend = c ? 1 : 0, chrs = "", i = test.cardinality; i > loopend; i--) chrs += getBufferElement(position - (i - 1)); - if (c && (chrs += c), getBuffer(!0), rslt = null != test.fn ? test.fn.test(chrs, getMaskSet(), position, strict, opts, isSelection(pos)) : c !== test.def && c !== opts.skipOptionalPartCharacter || "" === test.def ? !1 : { - c: test.placeholder || test.def, - pos: position - }, rslt !== !1) { - var elem = void 0 !== rslt.c ? rslt.c : c; - elem = elem === opts.skipOptionalPartCharacter && null === test.fn ? test.placeholder || test.def : elem; - var validatedPos = position, possibleModifiedBuffer = getBuffer(); - if (void 0 !== rslt.remove && ($.isArray(rslt.remove) || (rslt.remove = [ rslt.remove ]), - $.each(rslt.remove.sort(function(a, b) { - return b - a; - }), function(ndx, lmnt) { - stripValidPositions(lmnt, lmnt + 1, !0); - })), void 0 !== rslt.insert && ($.isArray(rslt.insert) || (rslt.insert = [ rslt.insert ]), - $.each(rslt.insert.sort(function(a, b) { - return a - b; - }), function(ndx, lmnt) { - isValid(lmnt.pos, lmnt.c, !1, fromSetValid); - })), rslt.refreshFromBuffer) { - var refresh = rslt.refreshFromBuffer; - if (strict = !0, refreshFromBuffer(refresh === !0 ? refresh : refresh.start, refresh.end, possibleModifiedBuffer), - void 0 === rslt.pos && void 0 === rslt.c) return rslt.pos = getLastValidPosition(), - !1; - if (validatedPos = void 0 !== rslt.pos ? rslt.pos : position, validatedPos !== position) return rslt = $.extend(rslt, isValid(validatedPos, elem, !0, fromSetValid)), - !1; - } else if (rslt !== !0 && void 0 !== rslt.pos && rslt.pos !== position && (validatedPos = rslt.pos, - refreshFromBuffer(position, validatedPos, getBuffer().slice()), validatedPos !== position)) return rslt = $.extend(rslt, isValid(validatedPos, elem, !0)), - !1; - return rslt !== !0 && void 0 === rslt.pos && void 0 === rslt.c ? !1 : (ndx > 0 && resetMaskSet(!0), - setValidPosition(validatedPos, $.extend({}, tst, { - input: casing(elem, test) - }), fromSetValid, isSelection(pos)) || (rslt = !1), !1); - } - }), rslt; - } - function alternate(pos, c, strict, fromSetValid) { - for (var lastAlt, alternation, isValidRslt, altPos, i, validPos, validPsClone = $.extend(!0, {}, getMaskSet().validPositions), testsClone = $.extend(!0, {}, getMaskSet().tests), lAlt = getLastValidPosition(); lAlt >= 0 && (altPos = getMaskSet().validPositions[lAlt], - !altPos || void 0 === altPos.alternation || (lastAlt = lAlt, alternation = getMaskSet().validPositions[lastAlt].alternation, - getTestTemplate(lastAlt).locator[altPos.alternation] === altPos.locator[altPos.alternation])); lAlt--) ; - if (void 0 !== alternation) { - lastAlt = parseInt(lastAlt); - for (var decisionPos in getMaskSet().validPositions) if (decisionPos = parseInt(decisionPos), - altPos = getMaskSet().validPositions[decisionPos], decisionPos >= lastAlt && void 0 !== altPos.alternation) { - var altNdxs; - 0 === lastAlt ? (altNdxs = [], $.each(getMaskSet().tests[lastAlt], function(ndx, test) { - void 0 !== test.locator[alternation] && (altNdxs = altNdxs.concat(test.locator[alternation].toString().split(","))); - })) : altNdxs = getMaskSet().validPositions[lastAlt].locator[alternation].toString().split(","); - var decisionTaker = void 0 !== altPos.locator[alternation] ? altPos.locator[alternation] : altNdxs[0]; - decisionTaker.length > 0 && (decisionTaker = decisionTaker.split(",")[0]); - for (var mndx = 0; mndx < altNdxs.length; mndx++) { - var validInputs = [], staticInputsBeforePos = 0, staticInputsBeforePosAlternate = 0; - if (decisionTaker < altNdxs[mndx]) { - for (var possibilityPos, possibilities, dp = decisionPos; dp >= 0; dp--) if (possibilityPos = getMaskSet().validPositions[dp], - void 0 !== possibilityPos) { - var bestMatch = selectBestMatch(dp, altNdxs[mndx]); - getMaskSet().validPositions[dp].match.def !== bestMatch.match.def && (validInputs.push(getMaskSet().validPositions[dp].input), - getMaskSet().validPositions[dp] = bestMatch, getMaskSet().validPositions[dp].input = getPlaceholder(dp), - null === getMaskSet().validPositions[dp].match.fn && staticInputsBeforePosAlternate++, - possibilityPos = bestMatch), possibilities = possibilityPos.locator[alternation], - possibilityPos.locator[alternation] = parseInt(altNdxs[mndx]); - break; - } - if (decisionTaker !== possibilityPos.locator[alternation]) { - for (i = decisionPos + 1; i < getLastValidPosition(void 0, !0) + 1; i++) validPos = getMaskSet().validPositions[i], - validPos && null != validPos.match.fn ? validInputs.push(validPos.input) : pos > i && staticInputsBeforePos++, - delete getMaskSet().validPositions[i], delete getMaskSet().tests[i]; - for (resetMaskSet(!0), opts.keepStatic = !opts.keepStatic, isValidRslt = !0; validInputs.length > 0; ) { - var input = validInputs.shift(); - if (input !== opts.skipOptionalPartCharacter && !(isValidRslt = isValid(getLastValidPosition(void 0, !0) + 1, input, !1, fromSetValid))) break; - } - if (possibilityPos.alternation = alternation, possibilityPos.locator[alternation] = possibilities, - isValidRslt) { - var targetLvp = getLastValidPosition(pos) + 1; - for (i = decisionPos + 1; i < getLastValidPosition() + 1; i++) validPos = getMaskSet().validPositions[i], - (void 0 === validPos || null == validPos.match.fn) && pos > i && staticInputsBeforePosAlternate++; - pos += staticInputsBeforePosAlternate - staticInputsBeforePos, isValidRslt = isValid(pos > targetLvp ? targetLvp : pos, c, strict, fromSetValid); - } - if (opts.keepStatic = !opts.keepStatic, isValidRslt) return isValidRslt; - resetMaskSet(), getMaskSet().validPositions = $.extend(!0, {}, validPsClone), getMaskSet().tests = $.extend(!0, {}, testsClone); - } - } - } - break; - } - } - return !1; - } - function trackbackAlternations(originalPos, newPos) { - for (var vp = getMaskSet().validPositions[newPos], targetLocator = vp.locator, tll = targetLocator.length, ps = originalPos; newPos > ps; ps++) if (void 0 === getMaskSet().validPositions[ps] && !isMask(ps, !0)) { - var tests = getTests(ps), bestMatch = tests[0], equality = -1; - $.each(tests, function(ndx, tst) { - for (var i = 0; tll > i && (void 0 !== tst.locator[i] && checkAlternationMatch(tst.locator[i].toString().split(","), targetLocator[i].toString().split(","))); i++) i > equality && (equality = i, - bestMatch = tst); - }), setValidPosition(ps, $.extend({}, bestMatch, { - input: bestMatch.match.placeholder || bestMatch.match.def - }), !0); - } - } - strict = strict === !0; - var maskPos = pos; - void 0 !== pos.begin && (maskPos = isRTL && !isSelection(pos) ? pos.end : pos.begin); - for (var result = !1, positionsClone = $.extend(!0, {}, getMaskSet().validPositions), pndx = maskPos - 1; pndx > -1 && !getMaskSet().validPositions[pndx]; pndx--) ; - var testTemplate; - for (pndx++; maskPos > pndx; pndx++) void 0 === getMaskSet().validPositions[pndx] && (opts.jitMasking === !1 || opts.jitMasking > pndx) && ((testTemplate = getTestTemplate(pndx)).match.def === opts.radixPointDefinitionSymbol || !isMask(pndx, !0) || $.inArray(opts.radixPoint, getBuffer()) < pndx && testTemplate.match.fn && testTemplate.match.fn.test(getPlaceholder(pndx), getMaskSet(), pndx, !1, opts)) && _isValid(getLastValidPosition(pndx, !0) + 1, testTemplate.match.placeholder || (null == testTemplate.match.fn ? testTemplate.match.def : "" !== getPlaceholder(pndx) ? getPlaceholder(pndx) : getBuffer()[pndx]), !0, fromSetValid); - if (isSelection(pos) && (handleRemove(void 0, Inputmask.keyCode.DELETE, pos), maskPos = getMaskSet().p), - maskPos < getMaskLength() && (result = _isValid(maskPos, c, strict, fromSetValid), - (!strict || fromSetValid === !0) && result === !1)) { - var currentPosValid = getMaskSet().validPositions[maskPos]; - if (!currentPosValid || null !== currentPosValid.match.fn || currentPosValid.match.def !== c && c !== opts.skipOptionalPartCharacter) { - if ((opts.insertMode || void 0 === getMaskSet().validPositions[seekNext(maskPos)]) && !isMask(maskPos, !0)) { - var staticChar = getTestTemplate(maskPos).match; - staticChar = staticChar.placeholder || staticChar.def, _isValid(maskPos, staticChar, strict, fromSetValid); - for (var nPos = maskPos + 1, snPos = seekNext(maskPos); snPos >= nPos; nPos++) if (result = _isValid(nPos, c, strict, fromSetValid), - result !== !1) { - trackbackAlternations(maskPos, nPos), maskPos = nPos; - break; - } - } - } else result = { - caret: seekNext(maskPos) - }; - } - return result === !1 && opts.keepStatic && (result = alternate(maskPos, c, strict, fromSetValid)), - result === !0 && (result = { - pos: maskPos - }), $.isFunction(opts.postValidation) && result !== !1 && !strict && fromSetValid !== !0 && (result = opts.postValidation(getBuffer(!0), result, opts) ? result : !1), - void 0 === result.pos && (result.pos = maskPos), result === !1 && (resetMaskSet(!0), - getMaskSet().validPositions = $.extend(!0, {}, positionsClone)), result; - } - function isMask(pos, strict) { - var test; - if (strict ? (test = getTestTemplate(pos).match, "" === test.def && (test = getTest(pos))) : test = getTest(pos), - null != test.fn) return test.fn; - if (strict !== !0 && pos > -1 && !opts.keepStatic && void 0 === getMaskSet().validPositions[pos]) { - var tests = getTests(pos); - return tests.length > 2; - } - return !1; - } - function getMaskLength() { - var maskLength; - maxLength = void 0 !== el ? el.maxLength : void 0, -1 === maxLength && (maxLength = void 0); - var pos, lvp = getLastValidPosition(), testPos = getMaskSet().validPositions[lvp], ndxIntlzr = void 0 !== testPos ? testPos.locator.slice() : void 0; - for (pos = lvp + 1; void 0 === testPos || null !== testPos.match.fn || null === testPos.match.fn && "" !== testPos.match.def; pos++) testPos = getTestTemplate(pos, ndxIntlzr, pos - 1), - ndxIntlzr = testPos.locator.slice(); - var lastTest = getTest(pos - 1); - return maskLength = "" !== lastTest.def ? pos : pos - 1, void 0 === maxLength || maxLength > maskLength ? maskLength : maxLength; - } - function seekNext(pos, newBlock) { - var maskL = getMaskLength(); - if (pos >= maskL) return maskL; - for (var position = pos; ++position < maskL && (newBlock === !0 && (getTest(position).newBlockMarker !== !0 || !isMask(position)) || newBlock !== !0 && !isMask(position) && (opts.nojumps !== !0 || opts.nojumpsThreshold > position)); ) ; - return position; - } - function seekPrevious(pos, newBlock) { - var position = pos; - if (0 >= position) return 0; - for (;--position > 0 && (newBlock === !0 && getTest(position).newBlockMarker !== !0 || newBlock !== !0 && !isMask(position)); ) ; - return position; - } - function getBufferElement(position) { - return void 0 === getMaskSet().validPositions[position] ? getPlaceholder(position) : getMaskSet().validPositions[position].input; - } - function writeBuffer(input, buffer, caretPos, event, triggerInputEvent) { - if (event && $.isFunction(opts.onBeforeWrite)) { - var result = opts.onBeforeWrite(event, buffer, caretPos, opts); - if (result) { - if (result.refreshFromBuffer) { - var refresh = result.refreshFromBuffer; - refreshFromBuffer(refresh === !0 ? refresh : refresh.start, refresh.end, result.buffer || buffer), - buffer = getBuffer(!0); - } - void 0 !== caretPos && (caretPos = void 0 !== result.caret ? result.caret : caretPos); - } - } - input.inputmask._valueSet(buffer.join("")), void 0 === caretPos || void 0 !== event && "blur" === event.type || caret(input, caretPos), - triggerInputEvent === !0 && (skipInputEvent = !0, $(input).trigger("input")); - } - function getPlaceholder(pos, test) { - if (test = test || getTest(pos), void 0 !== test.placeholder) return test.placeholder; - if (null === test.fn) { - if (pos > -1 && !opts.keepStatic && void 0 === getMaskSet().validPositions[pos]) { - var prevTest, tests = getTests(pos), staticAlternations = []; - if (tests.length > 2) for (var i = 0; i < tests.length; i++) if (tests[i].match.optionality !== !0 && tests[i].match.optionalQuantifier !== !0 && (null === tests[i].match.fn || void 0 === prevTest || tests[i].match.fn.test(prevTest.match.def, getMaskSet(), pos, !0, opts) !== !1) && (staticAlternations.push(tests[i]), - null === tests[i].match.fn && (prevTest = tests[i]), staticAlternations.length > 1)) return opts.placeholder.charAt(pos % opts.placeholder.length); - } - return test.def; - } - return opts.placeholder.charAt(pos % opts.placeholder.length); - } - function checkVal(input, writeOut, strict, nptvl) { - function isTemplateMatch() { - var isMatch = !1, charCodeNdx = getBufferTemplate().slice(initialNdx, seekNext(initialNdx)).join("").indexOf(charCodes); - if (-1 !== charCodeNdx && !isMask(initialNdx)) { - isMatch = !0; - for (var bufferTemplateArr = getBufferTemplate().slice(initialNdx, initialNdx + charCodeNdx), i = 0; i < bufferTemplateArr.length; i++) if (" " !== bufferTemplateArr[i]) { - isMatch = !1; - break; - } - } - return isMatch; - } - var result, inputValue = nptvl.slice(), charCodes = "", initialNdx = 0; - if (resetMaskSet(), getMaskSet().p = seekNext(-1), !strict) if (opts.autoUnmask !== !0) { - var staticInput = getBufferTemplate().slice(0, seekNext(-1)).join(""), matches = inputValue.join("").match(new RegExp("^" + Inputmask.escapeRegex(staticInput), "g")); - matches && matches.length > 0 && (inputValue.splice(0, matches.length * staticInput.length), - initialNdx = seekNext(initialNdx)); - } else initialNdx = seekNext(initialNdx); - $.each(inputValue, function(ndx, charCode) { - if (void 0 !== charCode) { - var keypress = new $.Event("keypress"); - keypress.which = charCode.charCodeAt(0), charCodes += charCode; - var lvp = getLastValidPosition(void 0, !0), lvTest = getMaskSet().validPositions[lvp], nextTest = getTestTemplate(lvp + 1, lvTest ? lvTest.locator.slice() : void 0, lvp); - if (!isTemplateMatch() || strict || opts.autoUnmask) { - var pos = strict ? ndx : null == nextTest.match.fn && nextTest.match.optionality && lvp + 1 < getMaskSet().p ? lvp + 1 : getMaskSet().p; - result = keypressEvent.call(input, keypress, !0, !1, strict, pos), initialNdx = pos + 1, - charCodes = ""; - } else result = keypressEvent.call(input, keypress, !0, !1, !0, lvp + 1); - if (!strict && $.isFunction(opts.onBeforeWrite) && (result = opts.onBeforeWrite(keypress, getBuffer(), result.forwardPosition, opts), - result && result.refreshFromBuffer)) { - var refresh = result.refreshFromBuffer; - refreshFromBuffer(refresh === !0 ? refresh : refresh.start, refresh.end, result.buffer), - resetMaskSet(!0), result.caret && (getMaskSet().p = result.caret); - } - } - }), writeOut && writeBuffer(input, getBuffer(), document.activeElement === input ? seekNext(getLastValidPosition(0)) : void 0, new $.Event("checkval")); - } - function unmaskedvalue(input) { - if (input && void 0 === input.inputmask) return input.value; - var umValue = [], vps = getMaskSet().validPositions; - for (var pndx in vps) vps[pndx].match && null != vps[pndx].match.fn && umValue.push(vps[pndx].input); - var unmaskedValue = 0 === umValue.length ? null : (isRTL ? umValue.reverse() : umValue).join(""); - if (null !== unmaskedValue) { - var bufferValue = (isRTL ? getBuffer().slice().reverse() : getBuffer()).join(""); - $.isFunction(opts.onUnMask) && (unmaskedValue = opts.onUnMask(bufferValue, unmaskedValue, opts) || unmaskedValue); - } - return unmaskedValue; - } - function caret(input, begin, end, notranslate) { - function translatePosition(pos) { - if (notranslate !== !0 && isRTL && "number" == typeof pos && (!opts.greedy || "" !== opts.placeholder)) { - var bffrLght = getBuffer().join("").length; - pos = bffrLght - pos; - } - return pos; - } - var range; - if ("number" != typeof begin) return input.setSelectionRange ? (begin = input.selectionStart, - end = input.selectionEnd) : window.getSelection ? (range = window.getSelection().getRangeAt(0), - (range.commonAncestorContainer.parentNode === input || range.commonAncestorContainer === input) && (begin = range.startOffset, - end = range.endOffset)) : document.selection && document.selection.createRange && (range = document.selection.createRange(), - begin = 0 - range.duplicate().moveStart("character", -input.inputmask._valueGet().length), - end = begin + range.text.length), { - begin: translatePosition(begin), - end: translatePosition(end) - }; - begin = translatePosition(begin), end = translatePosition(end), end = "number" == typeof end ? end : begin; - var scrollCalc = parseInt(((input.ownerDocument.defaultView || window).getComputedStyle ? (input.ownerDocument.defaultView || window).getComputedStyle(input, null) : input.currentStyle).fontSize) * end; - if (input.scrollLeft = scrollCalc > input.scrollWidth ? scrollCalc : 0, mobile || opts.insertMode !== !1 || begin !== end || end++, - input.setSelectionRange) input.selectionStart = begin, input.selectionEnd = end; else if (window.getSelection) { - if (range = document.createRange(), void 0 === input.firstChild || null === input.firstChild) { - var textNode = document.createTextNode(""); - input.appendChild(textNode); - } - range.setStart(input.firstChild, begin < input.inputmask._valueGet().length ? begin : input.inputmask._valueGet().length), - range.setEnd(input.firstChild, end < input.inputmask._valueGet().length ? end : input.inputmask._valueGet().length), - range.collapse(!0); - var sel = window.getSelection(); - sel.removeAllRanges(), sel.addRange(range); - } else input.createTextRange && (range = input.createTextRange(), range.collapse(!0), - range.moveEnd("character", end), range.moveStart("character", begin), range.select()); - } - function determineLastRequiredPosition(returnDefinition) { - var pos, testPos, buffer = getBuffer(), bl = buffer.length, lvp = getLastValidPosition(), positions = {}, lvTest = getMaskSet().validPositions[lvp], ndxIntlzr = void 0 !== lvTest ? lvTest.locator.slice() : void 0; - for (pos = lvp + 1; pos < buffer.length; pos++) testPos = getTestTemplate(pos, ndxIntlzr, pos - 1), - ndxIntlzr = testPos.locator.slice(), positions[pos] = $.extend(!0, {}, testPos); - var lvTestAlt = lvTest && void 0 !== lvTest.alternation ? lvTest.locator[lvTest.alternation] : void 0; - for (pos = bl - 1; pos > lvp && (testPos = positions[pos], (testPos.match.optionality || testPos.match.optionalQuantifier || lvTestAlt && (lvTestAlt !== positions[pos].locator[lvTest.alternation] && null != testPos.match.fn || null === testPos.match.fn && testPos.locator[lvTest.alternation] && checkAlternationMatch(testPos.locator[lvTest.alternation].toString().split(","), lvTestAlt.toString().split(",")) && "" !== getTests(pos)[0].def)) && buffer[pos] === getPlaceholder(pos, testPos.match)); pos--) bl--; - return returnDefinition ? { - l: bl, - def: positions[bl] ? positions[bl].match : void 0 - } : bl; - } - function clearOptionalTail(buffer) { - for (var rl = determineLastRequiredPosition(), lmib = buffer.length - 1; lmib > rl && !isMask(lmib); lmib--) ; - return buffer.splice(rl, lmib + 1 - rl), buffer; - } - function isComplete(buffer) { - if ($.isFunction(opts.isComplete)) return opts.isComplete(buffer, opts); - if ("*" === opts.repeat) return void 0; - var complete = !1, lrp = determineLastRequiredPosition(!0), aml = seekPrevious(lrp.l); - if (void 0 === lrp.def || lrp.def.newBlockMarker || lrp.def.optionality || lrp.def.optionalQuantifier) { - complete = !0; - for (var i = 0; aml >= i; i++) { - var test = getTestTemplate(i).match; - if (null !== test.fn && void 0 === getMaskSet().validPositions[i] && test.optionality !== !0 && test.optionalQuantifier !== !0 || null === test.fn && buffer[i] !== getPlaceholder(i, test)) { - complete = !1; - break; - } - } - } - return complete; - } - function patchValueProperty(npt) { - function patchValhook(type) { - if ($.valHooks && (void 0 === $.valHooks[type] || $.valHooks[type].inputmaskpatch !== !0)) { - var valhookGet = $.valHooks[type] && $.valHooks[type].get ? $.valHooks[type].get : function(elem) { - return elem.value; - }, valhookSet = $.valHooks[type] && $.valHooks[type].set ? $.valHooks[type].set : function(elem, value) { - return elem.value = value, elem; - }; - $.valHooks[type] = { - get: function(elem) { - if (elem.inputmask) { - if (elem.inputmask.opts.autoUnmask) return elem.inputmask.unmaskedvalue(); - var result = valhookGet(elem); - return -1 !== getLastValidPosition(void 0, void 0, elem.inputmask.maskset.validPositions) || opts.nullable !== !0 ? result : ""; - } - return valhookGet(elem); - }, - set: function(elem, value) { - var result, $elem = $(elem); - return result = valhookSet(elem, value), elem.inputmask && $elem.trigger("setvalue"), - result; - }, - inputmaskpatch: !0 - }; - } - } - function getter() { - return this.inputmask ? this.inputmask.opts.autoUnmask ? this.inputmask.unmaskedvalue() : -1 !== getLastValidPosition() || opts.nullable !== !0 ? document.activeElement === this && opts.clearMaskOnLostFocus ? (isRTL ? clearOptionalTail(getBuffer().slice()).reverse() : clearOptionalTail(getBuffer().slice())).join("") : valueGet.call(this) : "" : valueGet.call(this); - } - function setter(value) { - valueSet.call(this, value), this.inputmask && $(this).trigger("setvalue"); - } - function installNativeValueSetFallback(npt) { - EventRuler.on(npt, "mouseenter", function(event) { - var $input = $(this), input = this, value = input.inputmask._valueGet(); - value !== getBuffer().join("") && $input.trigger("setvalue"); - }); - } - var valueGet, valueSet; - if (!npt.inputmask.__valueGet) { - if (Object.getOwnPropertyDescriptor) { - "function" != typeof Object.getPrototypeOf && (Object.getPrototypeOf = "object" == typeof "test".__proto__ ? function(object) { - return object.__proto__; - } : function(object) { - return object.constructor.prototype; - }); - var valueProperty = Object.getPrototypeOf ? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(npt), "value") : void 0; - valueProperty && valueProperty.get && valueProperty.set ? (valueGet = valueProperty.get, - valueSet = valueProperty.set, Object.defineProperty(npt, "value", { - get: getter, - set: setter, - configurable: !0 - })) : "INPUT" !== npt.tagName && (valueGet = function() { - return this.textContent; - }, valueSet = function(value) { - this.textContent = value; - }, Object.defineProperty(npt, "value", { - get: getter, - set: setter, - configurable: !0 - })); - } else document.__lookupGetter__ && npt.__lookupGetter__("value") && (valueGet = npt.__lookupGetter__("value"), - valueSet = npt.__lookupSetter__("value"), npt.__defineGetter__("value", getter), - npt.__defineSetter__("value", setter)); - npt.inputmask.__valueGet = valueGet, npt.inputmask._valueGet = function(overruleRTL) { - return isRTL && overruleRTL !== !0 ? valueGet.call(this.el).split("").reverse().join("") : valueGet.call(this.el); - }, npt.inputmask.__valueSet = valueSet, npt.inputmask._valueSet = function(value, overruleRTL) { - valueSet.call(this.el, null === value || void 0 === value ? "" : overruleRTL !== !0 && isRTL ? value.split("").reverse().join("") : value); - }, void 0 === valueGet && (valueGet = function() { - return this.value; - }, valueSet = function(value) { - this.value = value; - }, patchValhook(npt.type), installNativeValueSetFallback(npt)); - } - } - function handleRemove(input, k, pos, strict) { - function generalize() { - if (opts.keepStatic) { - resetMaskSet(!0); - var lastAlt, validInputs = [], positionsClone = $.extend(!0, {}, getMaskSet().validPositions); - for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) { - var validPos = getMaskSet().validPositions[lastAlt]; - if (validPos && (null != validPos.match.fn && validInputs.push(validPos.input), - delete getMaskSet().validPositions[lastAlt], void 0 !== validPos.alternation && validPos.locator[validPos.alternation] === getTestTemplate(lastAlt).locator[validPos.alternation])) break; - } - if (lastAlt > -1) for (;validInputs.length > 0; ) { - getMaskSet().p = seekNext(getLastValidPosition()); - var keypress = new $.Event("keypress"); - keypress.which = validInputs.pop().charCodeAt(0), keypressEvent.call(input, keypress, !0, !1, !1, getMaskSet().p); - } else getMaskSet().validPositions = $.extend(!0, {}, positionsClone); - } - } - if ((opts.numericInput || isRTL) && (k === Inputmask.keyCode.BACKSPACE ? k = Inputmask.keyCode.DELETE : k === Inputmask.keyCode.DELETE && (k = Inputmask.keyCode.BACKSPACE), - isRTL)) { - var pend = pos.end; - pos.end = pos.begin, pos.begin = pend; - } - k === Inputmask.keyCode.BACKSPACE && (pos.end - pos.begin < 1 || opts.insertMode === !1) ? (pos.begin = seekPrevious(pos.begin), - void 0 === getMaskSet().validPositions[pos.begin] || getMaskSet().validPositions[pos.begin].input !== opts.groupSeparator && getMaskSet().validPositions[pos.begin].input !== opts.radixPoint || pos.begin--) : k === Inputmask.keyCode.DELETE && pos.begin === pos.end && (pos.end = isMask(pos.end) ? pos.end + 1 : seekNext(pos.end) + 1, - void 0 === getMaskSet().validPositions[pos.begin] || getMaskSet().validPositions[pos.begin].input !== opts.groupSeparator && getMaskSet().validPositions[pos.begin].input !== opts.radixPoint || pos.end++), - stripValidPositions(pos.begin, pos.end, !1, strict), strict !== !0 && generalize(); - var lvp = getLastValidPosition(pos.begin); - lvp < pos.begin ? (-1 === lvp && resetMaskSet(), getMaskSet().p = seekNext(lvp)) : strict !== !0 && (getMaskSet().p = pos.begin); - } - function keydownEvent(e) { - var input = this, $input = $(input), k = e.keyCode, pos = caret(input); - if (k === Inputmask.keyCode.BACKSPACE || k === Inputmask.keyCode.DELETE || iphone && k === Inputmask.keyCode.BACKSPACE_SAFARI || e.ctrlKey && k === Inputmask.keyCode.X && !isInputEventSupported("cut")) e.preventDefault(), - handleRemove(input, k, pos), writeBuffer(input, getBuffer(), getMaskSet().p, e, undoValue !== getBuffer().join("")), - input.inputmask._valueGet() === getBufferTemplate().join("") ? $input.trigger("cleared") : isComplete(getBuffer()) === !0 && $input.trigger("complete"), - opts.showTooltip && (input.title = opts.tooltip || getMaskSet().mask); else if (k === Inputmask.keyCode.END || k === Inputmask.keyCode.PAGE_DOWN) { - e.preventDefault(); - var caretPos = seekNext(getLastValidPosition()); - opts.insertMode || caretPos !== getMaskLength() || e.shiftKey || caretPos--, caret(input, e.shiftKey ? pos.begin : caretPos, caretPos, !0); - } else k === Inputmask.keyCode.HOME && !e.shiftKey || k === Inputmask.keyCode.PAGE_UP ? (e.preventDefault(), - caret(input, 0, e.shiftKey ? pos.begin : 0, !0)) : (opts.undoOnEscape && k === Inputmask.keyCode.ESCAPE || 90 === k && e.ctrlKey) && e.altKey !== !0 ? (checkVal(input, !0, !1, undoValue.split("")), - $input.trigger("click")) : k !== Inputmask.keyCode.INSERT || e.shiftKey || e.ctrlKey ? opts.tabThrough === !0 && k === Inputmask.keyCode.TAB ? (e.shiftKey === !0 ? (null === getTest(pos.begin).fn && (pos.begin = seekNext(pos.begin)), - pos.end = seekPrevious(pos.begin, !0), pos.begin = seekPrevious(pos.end, !0)) : (pos.begin = seekNext(pos.begin, !0), - pos.end = seekNext(pos.begin, !0), pos.end < getMaskLength() && pos.end--), pos.begin < getMaskLength() && (e.preventDefault(), - caret(input, pos.begin, pos.end))) : opts.insertMode !== !1 || e.shiftKey || (k === Inputmask.keyCode.RIGHT ? setTimeout(function() { - var caretPos = caret(input); - caret(input, caretPos.begin); - }, 0) : k === Inputmask.keyCode.LEFT && setTimeout(function() { - var caretPos = caret(input); - caret(input, isRTL ? caretPos.begin + 1 : caretPos.begin - 1); - }, 0)) : (opts.insertMode = !opts.insertMode, caret(input, opts.insertMode || pos.begin !== getMaskLength() ? pos.begin : pos.begin - 1)); - opts.onKeyDown.call(this, e, getBuffer(), caret(input).begin, opts), ignorable = -1 !== $.inArray(k, opts.ignorables); - } - function keypressEvent(e, checkval, writeOut, strict, ndx) { - var input = this, $input = $(input), k = e.which || e.charCode || e.keyCode; - if (!(checkval === !0 || e.ctrlKey && e.altKey) && (e.ctrlKey || e.metaKey || ignorable)) return k === Inputmask.keyCode.ENTER && undoValue !== getBuffer().join("") && (undoValue = getBuffer().join(""), - setTimeout(function() { - $input.trigger("change"); - }, 0)), !0; - if (k) { - 46 === k && e.shiftKey === !1 && "," === opts.radixPoint && (k = 44); - var forwardPosition, pos = checkval ? { - begin: ndx, - end: ndx - } : caret(input), c = String.fromCharCode(k); - getMaskSet().writeOutBuffer = !0; - var valResult = isValid(pos, c, strict); - if (valResult !== !1) { - var p = valResult.pos; - if (resetMaskSet(!0), void 0 !== valResult.caret) forwardPosition = valResult.caret; else { - var vps = getMaskSet().validPositions; - forwardPosition = !opts.keepStatic && (void 0 !== vps[p + 1] && getTests(p + 1, vps[p].locator.slice(), p).length > 1 || void 0 !== vps[p].alternation) ? p + 1 : seekNext(p); - } - getMaskSet().p = forwardPosition; - } - if (writeOut !== !1) { - var self = this; - if (setTimeout(function() { - opts.onKeyValidation.call(self, k, valResult, opts); - }, 0), getMaskSet().writeOutBuffer && valResult !== !1) { - var buffer = getBuffer(); - writeBuffer(input, buffer, opts.numericInput && void 0 === valResult.caret ? seekPrevious(forwardPosition) : forwardPosition, e, checkval !== !0), - checkval !== !0 && setTimeout(function() { - isComplete(buffer) === !0 && $input.trigger("complete"); - }, 0); - } - } - if (opts.showTooltip && (input.title = opts.tooltip || getMaskSet().mask), e.preventDefault(), - checkval) return valResult.forwardPosition = forwardPosition, valResult; - } - } - function pasteEvent(e) { - var tempValue, input = this, ev = e.originalEvent || e, $input = $(input), inputValue = input.inputmask._valueGet(!0), caretPos = caret(input); - isRTL && (tempValue = caretPos.end, caretPos.end = caretPos.begin, caretPos.begin = tempValue); - var valueBeforeCaret = inputValue.substr(0, caretPos.begin), valueAfterCaret = inputValue.substr(caretPos.end, inputValue.length); - valueBeforeCaret === (isRTL ? getBufferTemplate().reverse() : getBufferTemplate()).slice(0, caretPos.begin).join("") && (valueBeforeCaret = ""), - valueAfterCaret === (isRTL ? getBufferTemplate().reverse() : getBufferTemplate()).slice(caretPos.end).join("") && (valueAfterCaret = ""), - isRTL && (tempValue = valueBeforeCaret, valueBeforeCaret = valueAfterCaret, valueAfterCaret = tempValue), - window.clipboardData && window.clipboardData.getData ? inputValue = valueBeforeCaret + window.clipboardData.getData("Text") + valueAfterCaret : ev.clipboardData && ev.clipboardData.getData && (inputValue = valueBeforeCaret + ev.clipboardData.getData("text/plain") + valueAfterCaret); - var pasteValue = inputValue; - if ($.isFunction(opts.onBeforePaste)) { - if (pasteValue = opts.onBeforePaste(inputValue, opts), pasteValue === !1) return e.preventDefault(); - pasteValue || (pasteValue = inputValue); - } - return checkVal(input, !1, !1, isRTL ? pasteValue.split("").reverse() : pasteValue.toString().split("")), - writeBuffer(input, getBuffer(), seekNext(getLastValidPosition()), e, !0), isComplete(getBuffer()) === !0 && $input.trigger("complete"), - e.preventDefault(); - } - function inputFallBackEvent(e) { - var input = this, inputValue = input.inputmask._valueGet(); - if (getBuffer().join("") !== inputValue) { - var caretPos = caret(input); - if (inputValue = inputValue.replace(new RegExp("(" + Inputmask.escapeRegex(getBufferTemplate().join("")) + ")*"), ""), - iemobile) { - var inputChar = inputValue.replace(getBuffer().join(""), ""); - if (1 === inputChar.length) { - var keypress = new $.Event("keypress"); - return keypress.which = inputChar.charCodeAt(0), keypressEvent.call(input, keypress, !0, !0, !1, getMaskSet().validPositions[caretPos.begin - 1] ? caretPos.begin : caretPos.begin - 1), - !1; - } - } - if (caretPos.begin > inputValue.length && (caret(input, inputValue.length), caretPos = caret(input)), - getBuffer().length - inputValue.length !== 1 || inputValue.charAt(caretPos.begin) === getBuffer()[caretPos.begin] || inputValue.charAt(caretPos.begin + 1) === getBuffer()[caretPos.begin] || isMask(caretPos.begin)) { - for (var lvp = getLastValidPosition() + 1, bufferTemplate = getBuffer().slice(lvp).join(""); null === inputValue.match(Inputmask.escapeRegex(bufferTemplate) + "$"); ) bufferTemplate = bufferTemplate.slice(1); - inputValue = inputValue.replace(bufferTemplate, ""), inputValue = inputValue.split(""), - checkVal(input, !0, !1, inputValue), isComplete(getBuffer()) === !0 && $(input).trigger("complete"); - } else e.keyCode = Inputmask.keyCode.BACKSPACE, keydownEvent.call(input, e); - e.preventDefault(); - } - } - function setValueEvent(e) { - var input = this, value = input.inputmask._valueGet(); - checkVal(input, !0, !1, ($.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(value, opts) || value : value).split("")), - undoValue = getBuffer().join(""), (opts.clearMaskOnLostFocus || opts.clearIncomplete) && input.inputmask._valueGet() === getBufferTemplate().join("") && input.inputmask._valueSet(""); - } - function focusEvent(e) { - var input = this, nptValue = input.inputmask._valueGet(); - opts.showMaskOnFocus && (!opts.showMaskOnHover || opts.showMaskOnHover && "" === nptValue) ? input.inputmask._valueGet() !== getBuffer().join("") && writeBuffer(input, getBuffer(), seekNext(getLastValidPosition())) : mouseEnter === !1 && caret(input, seekNext(getLastValidPosition())), - opts.positionCaretOnTab === !0 && setTimeout(function() { - caret(input, seekNext(getLastValidPosition())); - }, 0), undoValue = getBuffer().join(""); - } - function mouseleaveEvent(e) { - var input = this; - if (mouseEnter = !1, opts.clearMaskOnLostFocus && document.activeElement !== input) { - var buffer = getBuffer().slice(), nptValue = input.inputmask._valueGet(); - nptValue !== input.getAttribute("placeholder") && "" !== nptValue && (-1 === getLastValidPosition() && nptValue === getBufferTemplate().join("") ? buffer = [] : clearOptionalTail(buffer), - writeBuffer(input, buffer)); - } - } - function clickEvent(e) { - function doRadixFocus(clickPos) { - if (opts.radixFocus && "" !== opts.radixPoint) { - var vps = getMaskSet().validPositions; - if (void 0 === vps[clickPos] || vps[clickPos].input === getPlaceholder(clickPos)) { - if (clickPos < seekNext(-1)) return !0; - var radixPos = $.inArray(opts.radixPoint, getBuffer()); - if (-1 !== radixPos) { - for (var vp in vps) if (vp > radixPos && vps[vp].input !== getPlaceholder(vp)) return !1; - return !0; - } - } - } - return !1; - } - var input = this; - setTimeout(function() { - if (document.activeElement === input) { - var selectedCaret = caret(input); - if (selectedCaret.begin === selectedCaret.end) if (doRadixFocus(selectedCaret.begin)) caret(input, opts.numericInput ? seekNext($.inArray(opts.radixPoint, getBuffer())) : $.inArray(opts.radixPoint, getBuffer())); else { - var clickPosition = selectedCaret.begin, lvclickPosition = getLastValidPosition(clickPosition, !0), lastPosition = seekNext(lvclickPosition); - if (lastPosition > clickPosition) caret(input, isMask(clickPosition) || isMask(clickPosition - 1) ? clickPosition : seekNext(clickPosition)); else { - var placeholder = getPlaceholder(lastPosition); - ("" !== placeholder && getBuffer()[lastPosition] !== placeholder || !isMask(lastPosition, !0) && getTest(lastPosition).def === placeholder) && (lastPosition = seekNext(lastPosition)), - caret(input, lastPosition); - } - } - } - }, 0); - } - function dblclickEvent(e) { - var input = this; - setTimeout(function() { - caret(input, 0, seekNext(getLastValidPosition())); - }, 0); - } - function cutEvent(e) { - var input = this, $input = $(input), pos = caret(input), ev = e.originalEvent || e, clipboardData = window.clipboardData || ev.clipboardData, clipData = isRTL ? getBuffer().slice(pos.end, pos.begin) : getBuffer().slice(pos.begin, pos.end); - clipboardData.setData("text", isRTL ? clipData.reverse().join("") : clipData.join("")), - document.execCommand && document.execCommand("copy"), handleRemove(input, Inputmask.keyCode.DELETE, pos), - writeBuffer(input, getBuffer(), getMaskSet().p, e, undoValue !== getBuffer().join("")), - input.inputmask._valueGet() === getBufferTemplate().join("") && $input.trigger("cleared"), - opts.showTooltip && (input.title = opts.tooltip || getMaskSet().mask); - } - function blurEvent(e) { - var $input = $(this), input = this; - if (input.inputmask) { - var nptValue = input.inputmask._valueGet(), buffer = getBuffer().slice(); - undoValue !== buffer.join("") && setTimeout(function() { - $input.trigger("change"), undoValue = buffer.join(""); - }, 0), "" !== nptValue && (opts.clearMaskOnLostFocus && (-1 === getLastValidPosition() && nptValue === getBufferTemplate().join("") ? buffer = [] : clearOptionalTail(buffer)), - isComplete(buffer) === !1 && (setTimeout(function() { - $input.trigger("incomplete"); - }, 0), opts.clearIncomplete && (resetMaskSet(), buffer = opts.clearMaskOnLostFocus ? [] : getBufferTemplate().slice())), - writeBuffer(input, buffer, void 0, e)); - } - } - function mouseenterEvent(e) { - var input = this; - mouseEnter = !0, document.activeElement !== input && opts.showMaskOnHover && input.inputmask._valueGet() !== getBuffer().join("") && writeBuffer(input, getBuffer()); - } - function submitEvent(e) { - undoValue !== getBuffer().join("") && $el.trigger("change"), opts.clearMaskOnLostFocus && -1 === getLastValidPosition() && el.inputmask._valueGet && el.inputmask._valueGet() === getBufferTemplate().join("") && el.inputmask._valueSet(""), - opts.removeMaskOnSubmit && (el.inputmask._valueSet(el.inputmask.unmaskedvalue(), !0), - setTimeout(function() { - writeBuffer(el, getBuffer()); - }, 0)); - } - function resetEvent(e) { - setTimeout(function() { - $el.trigger("setvalue"); - }, 0); - } - function mask(elem) { - if (el = elem, $el = $(el), opts.showTooltip && (el.title = opts.tooltip || getMaskSet().mask), - ("rtl" === el.dir || opts.rightAlign) && (el.style.textAlign = "right"), ("rtl" === el.dir || opts.numericInput) && (el.dir = "ltr", - el.removeAttribute("dir"), el.inputmask.isRTL = !0, isRTL = !0), EventRuler.off(el), - patchValueProperty(el), isElementTypeSupported(el, opts) && (EventRuler.on(el, "submit", submitEvent), - EventRuler.on(el, "reset", resetEvent), EventRuler.on(el, "mouseenter", mouseenterEvent), - EventRuler.on(el, "blur", blurEvent), EventRuler.on(el, "focus", focusEvent), EventRuler.on(el, "mouseleave", mouseleaveEvent), - EventRuler.on(el, "click", clickEvent), EventRuler.on(el, "dblclick", dblclickEvent), - EventRuler.on(el, "paste", pasteEvent), EventRuler.on(el, "dragdrop", pasteEvent), - EventRuler.on(el, "drop", pasteEvent), EventRuler.on(el, "cut", cutEvent), EventRuler.on(el, "complete", opts.oncomplete), - EventRuler.on(el, "incomplete", opts.onincomplete), EventRuler.on(el, "cleared", opts.oncleared), - EventRuler.on(el, "keydown", keydownEvent), EventRuler.on(el, "keypress", keypressEvent), - EventRuler.on(el, "input", inputFallBackEvent)), EventRuler.on(el, "setvalue", setValueEvent), - "" !== el.inputmask._valueGet() || opts.clearMaskOnLostFocus === !1 || document.activeElement === el) { - var initialValue = $.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(el.inputmask._valueGet(), opts) || el.inputmask._valueGet() : el.inputmask._valueGet(); - checkVal(el, !0, !1, initialValue.split("")); - var buffer = getBuffer().slice(); - undoValue = buffer.join(""), isComplete(buffer) === !1 && opts.clearIncomplete && resetMaskSet(), - opts.clearMaskOnLostFocus && document.activeElement !== el && (-1 === getLastValidPosition() ? buffer = [] : clearOptionalTail(buffer)), - writeBuffer(el, buffer), document.activeElement === el && caret(el, seekNext(getLastValidPosition())); - } - } - var undoValue, el, $el, maxLength, valueBuffer, isRTL = !1, skipKeyPressEvent = !1, skipInputEvent = !1, ignorable = !1, mouseEnter = !0, EventRuler = { - on: function(input, eventName, eventHandler) { - var ev = function(e) { - if (void 0 === this.inputmask && "FORM" !== this.nodeName) { - var imOpts = $.data(this, "_inputmask_opts"); - imOpts ? new Inputmask(imOpts).mask(this) : EventRuler.off(this); - } else { - if ("setvalue" === e.type || !(this.disabled || this.readOnly && !("keydown" === e.type && e.ctrlKey && 67 === e.keyCode || opts.tabThrough === !1 && e.keyCode === Inputmask.keyCode.TAB))) { - switch (e.type) { - case "input": - if (skipInputEvent === !0) return skipInputEvent = !1, e.preventDefault(); - break; - - case "keydown": - skipKeyPressEvent = !1, skipInputEvent = !1; - break; - - case "keypress": - if (skipKeyPressEvent === !0) return e.preventDefault(); - skipKeyPressEvent = !0; - break; - - case "click": - if (iemobile) { - var that = this; - return setTimeout(function() { - eventHandler.apply(that, arguments); - }, 0), !1; - } - } - var returnVal = eventHandler.apply(this, arguments); - return returnVal === !1 && (e.preventDefault(), e.stopPropagation()), returnVal; - } - e.preventDefault(); - } - }; - input.inputmask.events[eventName] = input.inputmask.events[eventName] || [], input.inputmask.events[eventName].push(ev), - -1 !== $.inArray(eventName, [ "submit", "reset" ]) ? null != input.form && $(input.form).on(eventName, ev) : $(input).on(eventName, ev); - }, - off: function(input, event) { - if (input.inputmask && input.inputmask.events) { - var events; - event ? (events = [], events[event] = input.inputmask.events[event]) : events = input.inputmask.events, - $.each(events, function(eventName, evArr) { - for (;evArr.length > 0; ) { - var ev = evArr.pop(); - -1 !== $.inArray(eventName, [ "submit", "reset" ]) ? null != input.form && $(input.form).off(eventName, ev) : $(input).off(eventName, ev); - } - delete input.inputmask.events[eventName]; - }); - } - } - }; - if (void 0 !== actionObj) switch (actionObj.action) { - case "isComplete": - return el = actionObj.el, isComplete(getBuffer()); - - case "unmaskedvalue": - return el = actionObj.el, void 0 !== el && void 0 !== el.inputmask ? (maskset = el.inputmask.maskset, - opts = el.inputmask.opts, isRTL = el.inputmask.isRTL) : (valueBuffer = actionObj.value, - opts.numericInput && (isRTL = !0), valueBuffer = ($.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(valueBuffer, opts) || valueBuffer : valueBuffer).split(""), - checkVal(void 0, !1, !1, isRTL ? valueBuffer.reverse() : valueBuffer), $.isFunction(opts.onBeforeWrite) && opts.onBeforeWrite(void 0, getBuffer(), 0, opts)), - unmaskedvalue(el); - - case "mask": - el = actionObj.el, maskset = el.inputmask.maskset, opts = el.inputmask.opts, isRTL = el.inputmask.isRTL, - undoValue = getBuffer().join(""), mask(el); - break; - - case "format": - return opts.numericInput && (isRTL = !0), valueBuffer = ($.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(actionObj.value, opts) || actionObj.value : actionObj.value).split(""), - checkVal(void 0, !1, !1, isRTL ? valueBuffer.reverse() : valueBuffer), $.isFunction(opts.onBeforeWrite) && opts.onBeforeWrite(void 0, getBuffer(), 0, opts), - actionObj.metadata ? { - value: isRTL ? getBuffer().slice().reverse().join("") : getBuffer().join(""), - metadata: maskScope({ - action: "getmetadata" - }, maskset, opts) - } : isRTL ? getBuffer().slice().reverse().join("") : getBuffer().join(""); - - case "isValid": - opts.numericInput && (isRTL = !0), actionObj.value ? (valueBuffer = actionObj.value.split(""), - checkVal(void 0, !1, !0, isRTL ? valueBuffer.reverse() : valueBuffer)) : actionObj.value = getBuffer().join(""); - for (var buffer = getBuffer(), rl = determineLastRequiredPosition(), lmib = buffer.length - 1; lmib > rl && !isMask(lmib); lmib--) ; - return buffer.splice(rl, lmib + 1 - rl), isComplete(buffer) && actionObj.value === getBuffer().join(""); - - case "getemptymask": - return getBufferTemplate().join(""); - - case "remove": - el = actionObj.el, $el = $(el), maskset = el.inputmask.maskset, opts = el.inputmask.opts, - el.inputmask._valueSet(unmaskedvalue(el)), EventRuler.off(el); - var valueProperty; - Object.getOwnPropertyDescriptor && Object.getPrototypeOf ? (valueProperty = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(el), "value"), - valueProperty && el.inputmask.__valueGet && Object.defineProperty(el, "value", { - get: el.inputmask.__valueGet, - set: el.inputmask.__valueSet, - configurable: !0 - })) : document.__lookupGetter__ && el.__lookupGetter__("value") && el.inputmask.__valueGet && (el.__defineGetter__("value", el.inputmask.__valueGet), - el.__defineSetter__("value", el.inputmask.__valueSet)), el.inputmask = void 0; - break; - - case "getmetadata": - if ($.isArray(maskset.metadata)) { - for (var alternation, lvp = getLastValidPosition(void 0, !0), firstAlt = lvp; firstAlt >= 0; firstAlt--) if (getMaskSet().validPositions[firstAlt] && void 0 !== getMaskSet().validPositions[firstAlt].alternation) { - alternation = getMaskSet().validPositions[firstAlt].alternation; - break; - } - return void 0 !== alternation ? maskset.metadata[getMaskSet().validPositions[firstAlt].locator[alternation]] : []; - } - return maskset.metadata; - } - } - Inputmask.prototype = { - defaults: { - placeholder: "_", - optionalmarker: { - start: "[", - end: "]" - }, - quantifiermarker: { - start: "{", - end: "}" - }, - groupmarker: { - start: "(", - end: ")" - }, - alternatormarker: "|", - escapeChar: "\\", - mask: null, - oncomplete: $.noop, - onincomplete: $.noop, - oncleared: $.noop, - repeat: 0, - greedy: !0, - autoUnmask: !1, - removeMaskOnSubmit: !1, - clearMaskOnLostFocus: !0, - insertMode: !0, - clearIncomplete: !1, - aliases: {}, - alias: null, - onKeyDown: $.noop, - onBeforeMask: null, - onBeforePaste: function(pastedValue, opts) { - return $.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(pastedValue, opts) : pastedValue; - }, - onBeforeWrite: null, - onUnMask: null, - showMaskOnFocus: !0, - showMaskOnHover: !0, - onKeyValidation: $.noop, - skipOptionalPartCharacter: " ", - showTooltip: !1, - tooltip: void 0, - numericInput: !1, - rightAlign: !1, - undoOnEscape: !0, - radixPoint: "", - radixPointDefinitionSymbol: void 0, - groupSeparator: "", - radixFocus: !1, - nojumps: !1, - nojumpsThreshold: 0, - keepStatic: null, - positionCaretOnTab: !1, - tabThrough: !1, - supportsInputType: [ "text", "tel", "password" ], - definitions: { - "9": { - validator: "[0-9]", - cardinality: 1, - definitionSymbol: "*" - }, - a: { - validator: "[A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]", - cardinality: 1, - definitionSymbol: "*" - }, - "*": { - validator: "[0-9A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]", - cardinality: 1 - } - }, - ignorables: [ 8, 9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123 ], - isComplete: null, - canClearPosition: $.noop, - postValidation: null, - staticDefinitionSymbol: void 0, - jitMasking: !1, - nullable: !0 - }, - masksCache: {}, - mask: function(elems) { - var that = this; - return "string" == typeof elems && (elems = document.getElementById(elems) || document.querySelectorAll(elems)), - elems = elems.nodeName ? [ elems ] : elems, $.each(elems, function(ndx, el) { - var scopedOpts = $.extend(!0, {}, that.opts); - importAttributeOptions(el, scopedOpts, $.extend(!0, {}, that.userOptions)); - var maskset = generateMaskSet(scopedOpts, that.noMasksCache); - void 0 !== maskset && (void 0 !== el.inputmask && el.inputmask.remove(), el.inputmask = new Inputmask(), - el.inputmask.opts = scopedOpts, el.inputmask.noMasksCache = that.noMasksCache, el.inputmask.userOptions = $.extend(!0, {}, that.userOptions), - el.inputmask.el = el, el.inputmask.maskset = maskset, el.inputmask.isRTL = !1, $.data(el, "_inputmask_opts", scopedOpts), - maskScope({ - action: "mask", - el: el - })); - }), elems && elems[0] ? elems[0].inputmask || this : this; - }, - option: function(options, noremask) { - return "string" == typeof options ? this.opts[options] : "object" == typeof options ? ($.extend(this.userOptions, options), - this.el && noremask !== !0 && this.mask(this.el), this) : void 0; - }, - unmaskedvalue: function(value) { - return maskScope({ - action: "unmaskedvalue", - el: this.el, - value: value - }, this.el && this.el.inputmask ? this.el.inputmask.maskset : generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - remove: function() { - return this.el ? (maskScope({ - action: "remove", - el: this.el - }), this.el.inputmask = void 0, this.el) : void 0; - }, - getemptymask: function() { - return maskScope({ - action: "getemptymask" - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - hasMaskedValue: function() { - return !this.opts.autoUnmask; - }, - isComplete: function() { - return maskScope({ - action: "isComplete", - el: this.el - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - getmetadata: function() { - return maskScope({ - action: "getmetadata" - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - isValid: function(value) { - return maskScope({ - action: "isValid", - value: value - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - format: function(value, metadata) { - return maskScope({ - action: "format", - value: value, - metadata: metadata - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - } - }, Inputmask.extendDefaults = function(options) { - $.extend(!0, Inputmask.prototype.defaults, options); - }, Inputmask.extendDefinitions = function(definition) { - $.extend(!0, Inputmask.prototype.defaults.definitions, definition); - }, Inputmask.extendAliases = function(alias) { - $.extend(!0, Inputmask.prototype.defaults.aliases, alias); - }, Inputmask.format = function(value, options, metadata) { - return Inputmask(options).format(value, metadata); - }, Inputmask.unmask = function(value, options) { - return Inputmask(options).unmaskedvalue(value); - }, Inputmask.isValid = function(value, options) { - return Inputmask(options).isValid(value); - }, Inputmask.remove = function(elems) { - $.each(elems, function(ndx, el) { - el.inputmask && el.inputmask.remove(); - }); - }, Inputmask.escapeRegex = function(str) { - var specials = [ "/", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}", "\\", "$", "^" ]; - return str.replace(new RegExp("(\\" + specials.join("|\\") + ")", "gim"), "\\$1"); - }, Inputmask.keyCode = { - ALT: 18, - BACKSPACE: 8, - BACKSPACE_SAFARI: 127, - CAPS_LOCK: 20, - COMMA: 188, - COMMAND: 91, - COMMAND_LEFT: 91, - COMMAND_RIGHT: 93, - CONTROL: 17, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - INSERT: 45, - LEFT: 37, - MENU: 93, - NUMPAD_ADD: 107, - NUMPAD_DECIMAL: 110, - NUMPAD_DIVIDE: 111, - NUMPAD_ENTER: 108, - NUMPAD_MULTIPLY: 106, - NUMPAD_SUBTRACT: 109, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SHIFT: 16, - SPACE: 32, - TAB: 9, - UP: 38, - WINDOWS: 91, - X: 88 - }; - var ua = navigator.userAgent, mobile = /mobile/i.test(ua), iemobile = /iemobile/i.test(ua), iphone = /iphone/i.test(ua) && !iemobile; - /android.*safari.*/i.test(ua) && !iemobile; - return window.Inputmask = Inputmask, Inputmask; -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.numeric.extensions.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.numeric.extensions.js deleted file mode 100644 index 06d97700f..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.numeric.extensions.js +++ /dev/null @@ -1,379 +0,0 @@ -/*! -* inputmask.numeric.extensions.js -* https://github.com/RobinHerbots/jquery.inputmask -* Copyright (c) 2010 - 2016 Robin Herbots -* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -* Version: 3.3.1 -*/ -!function(factory) { - "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib.jquery"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask); -}(function($, Inputmask) { - return Inputmask.extendAliases({ - numeric: { - mask: function(opts) { - function autoEscape(txt) { - for (var escapedTxt = "", i = 0; i < txt.length; i++) escapedTxt += opts.definitions[txt.charAt(i)] || opts.optionalmarker.start === txt.charAt(i) || opts.optionalmarker.end === txt.charAt(i) || opts.quantifiermarker.start === txt.charAt(i) || opts.quantifiermarker.end === txt.charAt(i) || opts.groupmarker.start === txt.charAt(i) || opts.groupmarker.end === txt.charAt(i) || opts.alternatormarker === txt.charAt(i) ? "\\" + txt.charAt(i) : txt.charAt(i); - return escapedTxt; - } - if (0 !== opts.repeat && isNaN(opts.integerDigits) && (opts.integerDigits = opts.repeat), - opts.repeat = 0, opts.groupSeparator === opts.radixPoint && ("." === opts.radixPoint ? opts.groupSeparator = "," : "," === opts.radixPoint ? opts.groupSeparator = "." : opts.groupSeparator = ""), - " " === opts.groupSeparator && (opts.skipOptionalPartCharacter = void 0), opts.autoGroup = opts.autoGroup && "" !== opts.groupSeparator, - opts.autoGroup && ("string" == typeof opts.groupSize && isFinite(opts.groupSize) && (opts.groupSize = parseInt(opts.groupSize)), - isFinite(opts.integerDigits))) { - var seps = Math.floor(opts.integerDigits / opts.groupSize), mod = opts.integerDigits % opts.groupSize; - opts.integerDigits = parseInt(opts.integerDigits) + (0 === mod ? seps - 1 : seps), - opts.integerDigits < 1 && (opts.integerDigits = "*"); - } - opts.placeholder.length > 1 && (opts.placeholder = opts.placeholder.charAt(0)), - opts.radixFocus = opts.radixFocus && "" !== opts.placeholder && opts.integerOptional === !0, - opts.definitions[";"] = opts.definitions["~"], opts.definitions[";"].definitionSymbol = "~", - opts.numericInput === !0 && (opts.radixFocus = !1, opts.digitsOptional = !1, isNaN(opts.digits) && (opts.digits = 2), - opts.decimalProtect = !1); - var mask = autoEscape(opts.prefix); - return mask += "[+]", mask += opts.integerOptional === !0 ? "~{1," + opts.integerDigits + "}" : "~{" + opts.integerDigits + "}", - void 0 !== opts.digits && (isNaN(opts.digits) || parseInt(opts.digits) > 0) && (opts.decimalProtect && (opts.radixPointDefinitionSymbol = ":"), - mask += opts.digitsOptional ? "[" + (opts.decimalProtect ? ":" : opts.radixPoint) + ";{1," + opts.digits + "}]" : (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}"), - mask += "[-]", mask += autoEscape(opts.suffix), opts.greedy = !1, null !== opts.min && (opts.min = opts.min.toString().replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - "," === opts.radixPoint && (opts.min = opts.min.replace(opts.radixPoint, "."))), - null !== opts.max && (opts.max = opts.max.toString().replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - "," === opts.radixPoint && (opts.max = opts.max.replace(opts.radixPoint, "."))), - mask; - }, - placeholder: "", - greedy: !1, - digits: "*", - digitsOptional: !0, - radixPoint: ".", - radixFocus: !0, - groupSize: 3, - groupSeparator: "", - autoGroup: !1, - allowPlus: !0, - allowMinus: !0, - negationSymbol: { - front: "-", - back: "" - }, - integerDigits: "+", - integerOptional: !0, - prefix: "", - suffix: "", - rightAlign: !0, - decimalProtect: !0, - min: null, - max: null, - step: 1, - insertMode: !0, - autoUnmask: !1, - unmaskAsNumber: !1, - postFormat: function(buffer, pos, opts) { - opts.numericInput === !0 && (buffer = buffer.reverse(), isFinite(pos) && (pos = buffer.join("").length - pos - 1)); - var i, l, suffixStripped = !1; - buffer.length >= opts.suffix.length && buffer.join("").indexOf(opts.suffix) === buffer.length - opts.suffix.length && (buffer.length = buffer.length - opts.suffix.length, - suffixStripped = !0), pos = pos >= buffer.length ? buffer.length - 1 : pos < opts.prefix.length ? opts.prefix.length : pos; - var needsRefresh = !1, charAtPos = buffer[pos], cbuf = buffer.slice(); - charAtPos === opts.groupSeparator && (cbuf.splice(pos--, 1), charAtPos = cbuf[pos]), - charAtPos !== opts.radixPoint && charAtPos !== opts.negationSymbol.front && charAtPos !== opts.negationSymbol.back && (cbuf[pos] = "?"); - var bufVal = cbuf.join(""), bufValOrigin = bufVal; - if (bufVal.length > 0 && opts.autoGroup || -1 !== bufVal.indexOf(opts.groupSeparator)) { - var escapedGroupSeparator = Inputmask.escapeRegex(opts.groupSeparator); - needsRefresh = 0 === bufVal.indexOf(opts.groupSeparator), bufVal = bufVal.replace(new RegExp(escapedGroupSeparator, "g"), ""); - var radixSplit = bufVal.split(opts.radixPoint); - if (bufVal = "" === opts.radixPoint ? bufVal : radixSplit[0], bufVal !== opts.prefix + "?0" && bufVal.length >= opts.groupSize + opts.prefix.length) for (var reg = new RegExp("([-+]?[\\d?]+)([\\d?]{" + opts.groupSize + "})"); reg.test(bufVal) && "" !== opts.groupSeparator; ) bufVal = bufVal.replace(reg, "$1" + opts.groupSeparator + "$2"), - bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator); - "" !== opts.radixPoint && radixSplit.length > 1 && (bufVal += opts.radixPoint + radixSplit[1]); - } - for (needsRefresh = bufValOrigin !== bufVal, buffer.length = bufVal.length, i = 0, - l = bufVal.length; l > i; i++) buffer[i] = bufVal.charAt(i); - var newPos = $.inArray("?", buffer); - if (-1 === newPos && (newPos = $.inArray(charAtPos, buffer)), buffer[newPos] = charAtPos, - !needsRefresh && suffixStripped) for (i = 0, l = opts.suffix.length; l > i; i++) buffer.push(opts.suffix.charAt(i)); - return newPos = opts.numericInput && isFinite(pos) ? buffer.join("").length - newPos - 1 : newPos, - opts.numericInput && (buffer = buffer.reverse(), $.inArray(opts.radixPoint, buffer) < newPos && buffer.join("").length - opts.suffix.length !== newPos && (newPos -= 1)), - { - pos: newPos, - refreshFromBuffer: needsRefresh, - buffer: buffer - }; - }, - onBeforeWrite: function(e, buffer, caretPos, opts) { - var rslt; - if (e && ("blur" === e.type || "checkval" === e.type || "keydown" === e.type)) { - var maskedValue = opts.numericInput ? buffer.slice().reverse().join("") : buffer.join(""), processValue = maskedValue.replace(opts.prefix, ""); - processValue = processValue.replace(opts.suffix, ""), processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - "," === opts.radixPoint && (processValue = processValue.replace(opts.radixPoint, ".")); - var isNegative = processValue.match(new RegExp("[-" + Inputmask.escapeRegex(opts.negationSymbol.front) + "]", "g")); - if (isNegative = null !== isNegative && 1 === isNegative.length, processValue = processValue.replace(new RegExp("[-" + Inputmask.escapeRegex(opts.negationSymbol.front) + "]", "g"), ""), - processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.negationSymbol.back) + "$"), ""), - isNaN(opts.placeholder) && (processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.placeholder), "g"), "")), - processValue = processValue === opts.negationSymbol.front ? processValue + "0" : processValue, - "" !== processValue && isFinite(processValue)) { - var floatValue = parseFloat(processValue), signedFloatValue = isNegative ? -1 * floatValue : floatValue; - if (null !== opts.min && isFinite(opts.min) && signedFloatValue < parseFloat(opts.min) ? (floatValue = Math.abs(opts.min), - isNegative = opts.min < 0, maskedValue = void 0) : null !== opts.max && isFinite(opts.max) && signedFloatValue > parseFloat(opts.max) && (floatValue = Math.abs(opts.max), - isNegative = opts.max < 0, maskedValue = void 0), processValue = floatValue.toString().replace(".", opts.radixPoint).split(""), - isFinite(opts.digits)) { - var radixPosition = $.inArray(opts.radixPoint, processValue), rpb = $.inArray(opts.radixPoint, maskedValue); - -1 === radixPosition && (processValue.push(opts.radixPoint), radixPosition = processValue.length - 1); - for (var i = 1; i <= opts.digits; i++) opts.digitsOptional || void 0 !== processValue[radixPosition + i] && processValue[radixPosition + i] !== opts.placeholder.charAt(0) ? -1 !== rpb && void 0 !== maskedValue[rpb + i] && (processValue[radixPosition + i] = processValue[radixPosition + i] || maskedValue[rpb + i]) : processValue[radixPosition + i] = "0"; - processValue[processValue.length - 1] === opts.radixPoint && delete processValue[processValue.length - 1]; - } - if (floatValue.toString() !== processValue && floatValue.toString() + "." !== processValue || isNegative) return !isNegative || 0 === floatValue && "blur" === e.type || (processValue.unshift(opts.negationSymbol.front), - processValue.push(opts.negationSymbol.back)), processValue = (opts.prefix + processValue.join("")).split(""), - opts.numericInput && (processValue = processValue.reverse()), rslt = opts.postFormat(processValue, opts.numericInput ? caretPos : caretPos - 1, opts), - rslt.buffer && (rslt.refreshFromBuffer = rslt.buffer.join("") !== buffer.join("")), - rslt; - } - } - return opts.autoGroup ? (rslt = opts.postFormat(buffer, opts.numericInput ? caretPos : caretPos - 1, opts), - rslt.caret = caretPos <= opts.prefix.length ? rslt.pos : rslt.pos + 1, rslt) : void 0; - }, - regex: { - integerPart: function(opts) { - return new RegExp("[" + Inputmask.escapeRegex(opts.negationSymbol.front) + "+]?\\d+"); - }, - integerNPart: function(opts) { - return new RegExp("[\\d" + Inputmask.escapeRegex(opts.groupSeparator) + Inputmask.escapeRegex(opts.placeholder.charAt(0)) + "]+"); - } - }, - signHandler: function(chrs, maskset, pos, strict, opts) { - if (!strict && opts.allowMinus && "-" === chrs || opts.allowPlus && "+" === chrs) { - var matchRslt = maskset.buffer.join("").match(opts.regex.integerPart(opts)); - if (matchRslt && matchRslt[0].length > 0) return maskset.buffer[matchRslt.index] === ("-" === chrs ? "+" : opts.negationSymbol.front) ? "-" === chrs ? "" !== opts.negationSymbol.back ? { - pos: matchRslt.index, - c: opts.negationSymbol.front, - remove: matchRslt.index, - caret: pos, - insert: { - pos: maskset.buffer.length - opts.suffix.length - 1, - c: opts.negationSymbol.back - } - } : { - pos: matchRslt.index, - c: opts.negationSymbol.front, - remove: matchRslt.index, - caret: pos - } : "" !== opts.negationSymbol.back ? { - pos: matchRslt.index, - c: "+", - remove: [ matchRslt.index, maskset.buffer.length - opts.suffix.length - 1 ], - caret: pos - } : { - pos: matchRslt.index, - c: "+", - remove: matchRslt.index, - caret: pos - } : maskset.buffer[matchRslt.index] === ("-" === chrs ? opts.negationSymbol.front : "+") ? "-" === chrs && "" !== opts.negationSymbol.back ? { - remove: [ matchRslt.index, maskset.buffer.length - opts.suffix.length - 1 ], - caret: pos - 1 - } : { - remove: matchRslt.index, - caret: pos - 1 - } : "-" === chrs ? "" !== opts.negationSymbol.back ? { - pos: matchRslt.index, - c: opts.negationSymbol.front, - caret: pos + 1, - insert: { - pos: maskset.buffer.length - opts.suffix.length, - c: opts.negationSymbol.back - } - } : { - pos: matchRslt.index, - c: opts.negationSymbol.front, - caret: pos + 1 - } : { - pos: matchRslt.index, - c: chrs, - caret: pos + 1 - }; - } - return !1; - }, - radixHandler: function(chrs, maskset, pos, strict, opts) { - if (!strict && opts.numericInput !== !0 && chrs === opts.radixPoint && void 0 !== opts.digits && (isNaN(opts.digits) || parseInt(opts.digits) > 0)) { - var radixPos = $.inArray(opts.radixPoint, maskset.buffer), integerValue = maskset.buffer.join("").match(opts.regex.integerPart(opts)); - if (-1 !== radixPos && maskset.validPositions[radixPos]) return maskset.validPositions[radixPos - 1] ? { - caret: radixPos + 1 - } : { - pos: integerValue.index, - c: integerValue[0], - caret: radixPos + 1 - }; - if (!integerValue || "0" === integerValue[0] && integerValue.index + 1 !== pos) return maskset.buffer[integerValue ? integerValue.index : pos] = "0", - { - pos: (integerValue ? integerValue.index : pos) + 1, - c: opts.radixPoint - }; - } - return !1; - }, - leadingZeroHandler: function(chrs, maskset, pos, strict, opts, isSelection) { - if (!strict) if (opts.numericInput === !0) { - var buffer = maskset.buffer.slice("").reverse(), char = buffer[opts.prefix.length]; - if ("0" === char && void 0 === maskset.validPositions[pos - 1]) return { - pos: pos, - remove: buffer.length - opts.prefix.length - 1 - }; - } else { - var radixPosition = $.inArray(opts.radixPoint, maskset.buffer), matchRslt = maskset.buffer.slice(0, -1 !== radixPosition ? radixPosition : void 0).join("").match(opts.regex.integerNPart(opts)); - if (matchRslt && (-1 === radixPosition || radixPosition >= pos)) { - var decimalPart = -1 === radixPosition ? 0 : parseInt(maskset.buffer.slice(radixPosition + 1).join("")); - if (0 === matchRslt[0].indexOf("" !== opts.placeholder ? opts.placeholder.charAt(0) : "0") && (matchRslt.index + 1 === pos || isSelection !== !0 && 0 === decimalPart)) return maskset.buffer.splice(matchRslt.index, 1), - { - pos: matchRslt.index, - remove: matchRslt.index - }; - if ("0" === chrs && pos <= matchRslt.index && matchRslt[0] !== opts.groupSeparator) return !1; - } - } - return !0; - }, - definitions: { - "~": { - validator: function(chrs, maskset, pos, strict, opts, isSelection) { - var isValid = opts.signHandler(chrs, maskset, pos, strict, opts); - if (!isValid && (isValid = opts.radixHandler(chrs, maskset, pos, strict, opts), - !isValid && (isValid = strict ? new RegExp("[0-9" + Inputmask.escapeRegex(opts.groupSeparator) + "]").test(chrs) : new RegExp("[0-9]").test(chrs), - isValid === !0 && (isValid = opts.leadingZeroHandler(chrs, maskset, pos, strict, opts, isSelection), - isValid === !0)))) { - var radixPosition = $.inArray(opts.radixPoint, maskset.buffer); - isValid = -1 !== radixPosition && (opts.digitsOptional === !1 || maskset.validPositions[pos]) && opts.numericInput !== !0 && pos > radixPosition && !strict ? { - pos: pos, - remove: pos - } : { - pos: pos - }; - } - return isValid; - }, - cardinality: 1 - }, - "+": { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.signHandler(chrs, maskset, pos, strict, opts); - return !isValid && (strict && opts.allowMinus && chrs === opts.negationSymbol.front || opts.allowMinus && "-" === chrs || opts.allowPlus && "+" === chrs) && (isValid = strict || "-" !== chrs ? !0 : "" !== opts.negationSymbol.back ? { - pos: pos, - c: "-" === chrs ? opts.negationSymbol.front : "+", - caret: pos + 1, - insert: { - pos: maskset.buffer.length, - c: opts.negationSymbol.back - } - } : { - pos: pos, - c: "-" === chrs ? opts.negationSymbol.front : "+", - caret: pos + 1 - }), isValid; - }, - cardinality: 1, - placeholder: "" - }, - "-": { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.signHandler(chrs, maskset, pos, strict, opts); - return !isValid && strict && opts.allowMinus && chrs === opts.negationSymbol.back && (isValid = !0), - isValid; - }, - cardinality: 1, - placeholder: "" - }, - ":": { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.signHandler(chrs, maskset, pos, strict, opts); - if (!isValid) { - var radix = "[" + Inputmask.escapeRegex(opts.radixPoint) + "]"; - isValid = new RegExp(radix).test(chrs), isValid && maskset.validPositions[pos] && maskset.validPositions[pos].match.placeholder === opts.radixPoint && (isValid = { - caret: pos + 1 - }); - } - return isValid ? { - c: opts.radixPoint - } : isValid; - }, - cardinality: 1, - placeholder: function(opts) { - return opts.radixPoint; - } - } - }, - onUnMask: function(maskedValue, unmaskedValue, opts) { - var processValue = maskedValue.replace(opts.prefix, ""); - return processValue = processValue.replace(opts.suffix, ""), processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - opts.unmaskAsNumber ? ("" !== opts.radixPoint && -1 !== processValue.indexOf(opts.radixPoint) && (processValue = processValue.replace(Inputmask.escapeRegex.call(this, opts.radixPoint), ".")), - Number(processValue)) : processValue; - }, - isComplete: function(buffer, opts) { - var maskedValue = buffer.join(""), bufClone = buffer.slice(); - if (opts.postFormat(bufClone, 0, opts), bufClone.join("") !== maskedValue) return !1; - var processValue = maskedValue.replace(opts.prefix, ""); - return processValue = processValue.replace(opts.suffix, ""), processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - "," === opts.radixPoint && (processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".")), - isFinite(processValue); - }, - onBeforeMask: function(initialValue, opts) { - if ("" !== opts.radixPoint && isFinite(initialValue)) initialValue = initialValue.toString().replace(".", opts.radixPoint); else { - var kommaMatches = initialValue.match(/,/g), dotMatches = initialValue.match(/\./g); - dotMatches && kommaMatches ? dotMatches.length > kommaMatches.length ? (initialValue = initialValue.replace(/\./g, ""), - initialValue = initialValue.replace(",", opts.radixPoint)) : kommaMatches.length > dotMatches.length ? (initialValue = initialValue.replace(/,/g, ""), - initialValue = initialValue.replace(".", opts.radixPoint)) : initialValue = initialValue.indexOf(".") < initialValue.indexOf(",") ? initialValue.replace(/\./g, "") : initialValue = initialValue.replace(/,/g, "") : initialValue = initialValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""); - } - if (0 === opts.digits && (-1 !== initialValue.indexOf(".") ? initialValue = initialValue.substring(0, initialValue.indexOf(".")) : -1 !== initialValue.indexOf(",") && (initialValue = initialValue.substring(0, initialValue.indexOf(",")))), - "" !== opts.radixPoint && isFinite(opts.digits) && -1 !== initialValue.indexOf(opts.radixPoint)) { - var valueParts = initialValue.split(opts.radixPoint), decPart = valueParts[1].match(new RegExp("\\d*"))[0]; - if (parseInt(opts.digits) < decPart.toString().length) { - var digitsFactor = Math.pow(10, parseInt(opts.digits)); - initialValue = initialValue.replace(Inputmask.escapeRegex(opts.radixPoint), "."), - initialValue = Math.round(parseFloat(initialValue) * digitsFactor) / digitsFactor, - initialValue = initialValue.toString().replace(".", opts.radixPoint); - } - } - return initialValue.toString(); - }, - canClearPosition: function(maskset, position, lvp, strict, opts) { - var positionInput = maskset.validPositions[position].input, canClear = positionInput !== opts.radixPoint || null !== maskset.validPositions[position].match.fn && opts.decimalProtect === !1 || isFinite(positionInput) || position === lvp || positionInput === opts.groupSeparator || positionInput === opts.negationSymbol.front || positionInput === opts.negationSymbol.back; - return canClear; - }, - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey) switch (e.keyCode) { - case Inputmask.keyCode.UP: - $input.val(parseFloat(this.inputmask.unmaskedvalue()) + parseInt(opts.step)), $input.trigger("setvalue"); - break; - - case Inputmask.keyCode.DOWN: - $input.val(parseFloat(this.inputmask.unmaskedvalue()) - parseInt(opts.step)), $input.trigger("setvalue"); - } - } - }, - currency: { - prefix: "$ ", - groupSeparator: ",", - alias: "numeric", - placeholder: "0", - autoGroup: !0, - digits: 2, - digitsOptional: !1, - clearMaskOnLostFocus: !1 - }, - decimal: { - alias: "numeric" - }, - integer: { - alias: "numeric", - digits: 0, - radixPoint: "" - }, - percentage: { - alias: "numeric", - digits: 2, - radixPoint: ".", - placeholder: "0", - autoGroup: !1, - min: 0, - max: 100, - suffix: " %", - allowPlus: !1, - allowMinus: !1 - } - }), Inputmask; -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.phone.extensions.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.phone.extensions.js deleted file mode 100644 index e1204cc02..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.phone.extensions.js +++ /dev/null @@ -1,52 +0,0 @@ -/*! -* inputmask.phone.extensions.js -* https://github.com/RobinHerbots/jquery.inputmask -* Copyright (c) 2010 - 2016 Robin Herbots -* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -* Version: 3.3.1 -*/ -!function(factory) { - "function" == typeof define && define.amd ? define([ "jquery", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask); -}(function($, Inputmask) { - return Inputmask.extendAliases({ - phone: { - url: "phone-codes/phone-codes.js", - countrycode: "", - phoneCodeCache: {}, - mask: function(opts) { - if (void 0 === opts.phoneCodeCache[opts.url]) { - var maskList = []; - opts.definitions["#"] = opts.definitions[9], $.ajax({ - url: opts.url, - async: !1, - type: "get", - dataType: "json", - success: function(response) { - maskList = response; - }, - error: function(xhr, ajaxOptions, thrownError) { - alert(thrownError + " - " + opts.url); - } - }), opts.phoneCodeCache[opts.url] = maskList.sort(function(a, b) { - return (a.mask || a) < (b.mask || b) ? -1 : 1; - }); - } - return opts.phoneCodeCache[opts.url]; - }, - keepStatic: !1, - nojumps: !0, - nojumpsThreshold: 1, - onBeforeMask: function(value, opts) { - var processedValue = value.replace(/^0{1,2}/, "").replace(/[\s]/g, ""); - return (processedValue.indexOf(opts.countrycode) > 1 || -1 === processedValue.indexOf(opts.countrycode)) && (processedValue = "+" + opts.countrycode + processedValue), - processedValue; - } - }, - phonebe: { - alias: "phone", - url: "phone-codes/phone-be.js", - countrycode: "32", - nojumpsThreshold: 4 - } - }), Inputmask; -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.regex.extensions.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.regex.extensions.js deleted file mode 100644 index 9f2faeaa5..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/inputmask.regex.extensions.js +++ /dev/null @@ -1,115 +0,0 @@ -/*! -* inputmask.regex.extensions.js -* https://github.com/RobinHerbots/jquery.inputmask -* Copyright (c) 2010 - 2016 Robin Herbots -* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -* Version: 3.3.1 -*/ -!function(factory) { - "function" == typeof define && define.amd ? define([ "inputmask.dependencyLib", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("./inputmask.dependencyLib.jquery"), require("./inputmask")) : factory(window.dependencyLib || jQuery, window.Inputmask); -}(function($, Inputmask) { - return Inputmask.extendAliases({ - Regex: { - mask: "r", - greedy: !1, - repeat: "*", - regex: null, - regexTokens: null, - tokenizer: /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g, - quantifierFilter: /[0-9]+[^,]/, - isComplete: function(buffer, opts) { - return new RegExp(opts.regex).test(buffer.join("")); - }, - definitions: { - r: { - validator: function(chrs, maskset, pos, strict, opts) { - function RegexToken(isGroup, isQuantifier) { - this.matches = [], this.isGroup = isGroup || !1, this.isQuantifier = isQuantifier || !1, - this.quantifier = { - min: 1, - max: 1 - }, this.repeaterPart = void 0; - } - function analyseRegex() { - var match, m, currentToken = new RegexToken(), opengroups = []; - for (opts.regexTokens = []; match = opts.tokenizer.exec(opts.regex); ) switch (m = match[0], - m.charAt(0)) { - case "(": - opengroups.push(new RegexToken(!0)); - break; - - case ")": - groupToken = opengroups.pop(), opengroups.length > 0 ? opengroups[opengroups.length - 1].matches.push(groupToken) : currentToken.matches.push(groupToken); - break; - - case "{": - case "+": - case "*": - var quantifierToken = new RegexToken(!1, !0); - m = m.replace(/[{}]/g, ""); - var mq = m.split(","), mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), mq1 = 1 === mq.length ? mq0 : isNaN(mq[1]) ? mq[1] : parseInt(mq[1]); - if (quantifierToken.quantifier = { - min: mq0, - max: mq1 - }, opengroups.length > 0) { - var matches = opengroups[opengroups.length - 1].matches; - match = matches.pop(), match.isGroup || (groupToken = new RegexToken(!0), groupToken.matches.push(match), - match = groupToken), matches.push(match), matches.push(quantifierToken); - } else match = currentToken.matches.pop(), match.isGroup || (groupToken = new RegexToken(!0), - groupToken.matches.push(match), match = groupToken), currentToken.matches.push(match), - currentToken.matches.push(quantifierToken); - break; - - default: - opengroups.length > 0 ? opengroups[opengroups.length - 1].matches.push(m) : currentToken.matches.push(m); - } - currentToken.matches.length > 0 && opts.regexTokens.push(currentToken); - } - function validateRegexToken(token, fromGroup) { - var isvalid = !1; - fromGroup && (regexPart += "(", openGroupCount++); - for (var mndx = 0; mndx < token.matches.length; mndx++) { - var matchToken = token.matches[mndx]; - if (matchToken.isGroup === !0) isvalid = validateRegexToken(matchToken, !0); else if (matchToken.isQuantifier === !0) { - var crrntndx = $.inArray(matchToken, token.matches), matchGroup = token.matches[crrntndx - 1], regexPartBak = regexPart; - if (isNaN(matchToken.quantifier.max)) { - for (;matchToken.repeaterPart && matchToken.repeaterPart !== regexPart && matchToken.repeaterPart.length > regexPart.length && !(isvalid = validateRegexToken(matchGroup, !0)); ) ; - isvalid = isvalid || validateRegexToken(matchGroup, !0), isvalid && (matchToken.repeaterPart = regexPart), - regexPart = regexPartBak + matchToken.quantifier.max; - } else { - for (var i = 0, qm = matchToken.quantifier.max - 1; qm > i && !(isvalid = validateRegexToken(matchGroup, !0)); i++) ; - regexPart = regexPartBak + "{" + matchToken.quantifier.min + "," + matchToken.quantifier.max + "}"; - } - } else if (void 0 !== matchToken.matches) for (var k = 0; k < matchToken.length && !(isvalid = validateRegexToken(matchToken[k], fromGroup)); k++) ; else { - var testExp; - if ("[" == matchToken.charAt(0)) { - testExp = regexPart, testExp += matchToken; - for (var j = 0; openGroupCount > j; j++) testExp += ")"; - var exp = new RegExp("^(" + testExp + ")$"); - isvalid = exp.test(bufferStr); - } else for (var l = 0, tl = matchToken.length; tl > l; l++) if ("\\" !== matchToken.charAt(l)) { - testExp = regexPart, testExp += matchToken.substr(0, l + 1), testExp = testExp.replace(/\|$/, ""); - for (var j = 0; openGroupCount > j; j++) testExp += ")"; - var exp = new RegExp("^(" + testExp + ")$"); - if (isvalid = exp.test(bufferStr)) break; - } - regexPart += matchToken; - } - if (isvalid) break; - } - return fromGroup && (regexPart += ")", openGroupCount--), isvalid; - } - var bufferStr, groupToken, cbuffer = maskset.buffer.slice(), regexPart = "", isValid = !1, openGroupCount = 0; - null === opts.regexTokens && analyseRegex(), cbuffer.splice(pos, 0, chrs), bufferStr = cbuffer.join(""); - for (var i = 0; i < opts.regexTokens.length; i++) { - var regexToken = opts.regexTokens[i]; - if (isValid = validateRegexToken(regexToken, regexToken.isGroup)) break; - } - return isValid; - }, - cardinality: 1 - } - } - } - }), Inputmask; -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/jquery.inputmask.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/jquery.inputmask.js deleted file mode 100644 index 8b40189ed..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/inputmask/jquery.inputmask.js +++ /dev/null @@ -1,60 +0,0 @@ -/*! -* jquery.inputmask.js -* https://github.com/RobinHerbots/jquery.inputmask -* Copyright (c) 2010 - 2016 Robin Herbots -* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -* Version: 3.3.1 -*/ -!function(factory) { - "function" == typeof define && define.amd ? define([ "jquery", "inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery"), require("./inputmask")) : factory(jQuery, window.Inputmask); -}(function($, Inputmask) { - return void 0 === $.fn.inputmask && ($.fn.inputmask = function(fn, options) { - var nptmask, input = this[0]; - if (void 0 === options && (options = {}), "string" == typeof fn) switch (fn) { - case "unmaskedvalue": - return input && input.inputmask ? input.inputmask.unmaskedvalue() : $(input).val(); - - case "remove": - return this.each(function() { - this.inputmask && this.inputmask.remove(); - }); - - case "getemptymask": - return input && input.inputmask ? input.inputmask.getemptymask() : ""; - - case "hasMaskedValue": - return input && input.inputmask ? input.inputmask.hasMaskedValue() : !1; - - case "isComplete": - return input && input.inputmask ? input.inputmask.isComplete() : !0; - - case "getmetadata": - return input && input.inputmask ? input.inputmask.getmetadata() : void 0; - - case "setvalue": - $(input).val(options), input && void 0 !== input.inputmask && $(input).triggerHandler("setvalue"); - break; - - case "option": - if ("string" != typeof options) return this.each(function() { - return void 0 !== this.inputmask ? this.inputmask.option(options) : void 0; - }); - if (input && void 0 !== input.inputmask) return input.inputmask.option(options); - break; - - default: - return options.alias = fn, nptmask = new Inputmask(options), this.each(function() { - nptmask.mask(this); - }); - } else { - if ("object" == typeof fn) return nptmask = new Inputmask(fn), void 0 === fn.mask && void 0 === fn.alias ? this.each(function() { - return void 0 !== this.inputmask ? this.inputmask.option(fn) : void nptmask.mask(this); - }) : this.each(function() { - nptmask.mask(this); - }); - if (void 0 === fn) return this.each(function() { - nptmask = new Inputmask(options), nptmask.mask(this); - }); - } - }), $.fn.inputmask; -}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/jquery.inputmask.bundle.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/jquery.inputmask.bundle.js deleted file mode 100644 index 2717851a3..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-inputmask/jquery.inputmask.bundle.js +++ /dev/null @@ -1,2617 +0,0 @@ -/*! -* jquery.inputmask.bundle.js -* https://github.com/RobinHerbots/jquery.inputmask -* Copyright (c) 2010 - 2016 Robin Herbots -* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php) -* Version: 3.3.1 -*/ -!function($) { - function Inputmask(alias, options) { - return this instanceof Inputmask ? ($.isPlainObject(alias) ? options = alias : (options = options || {}, - options.alias = alias), this.el = void 0, this.opts = $.extend(!0, {}, this.defaults, options), - this.noMasksCache = options && void 0 !== options.definitions, this.userOptions = options || {}, - this.events = {}, void resolveAlias(this.opts.alias, options, this.opts)) : new Inputmask(alias, options); - } - function isInputEventSupported(eventName) { - var el = document.createElement("input"), evName = "on" + eventName, isSupported = evName in el; - return isSupported || (el.setAttribute(evName, "return;"), isSupported = "function" == typeof el[evName]), - el = null, isSupported; - } - function isElementTypeSupported(input, opts) { - var elementType = input.getAttribute("type"), isSupported = "INPUT" === input.tagName && -1 !== $.inArray(elementType, opts.supportsInputType) || input.isContentEditable || "TEXTAREA" === input.tagName; - if (!isSupported && "INPUT" === input.tagName) { - var el = document.createElement("input"); - el.setAttribute("type", elementType), isSupported = "text" === el.type, el = null; - } - return isSupported; - } - function resolveAlias(aliasStr, options, opts) { - var aliasDefinition = opts.aliases[aliasStr]; - return aliasDefinition ? (aliasDefinition.alias && resolveAlias(aliasDefinition.alias, void 0, opts), - $.extend(!0, opts, aliasDefinition), $.extend(!0, opts, options), !0) : (null === opts.mask && (opts.mask = aliasStr), - !1); - } - function importAttributeOptions(npt, opts, userOptions) { - function importOption(option, optionData) { - optionData = void 0 !== optionData ? optionData : npt.getAttribute("data-inputmask-" + option), - null !== optionData && ("string" == typeof optionData && (0 === option.indexOf("on") ? optionData = window[optionData] : "false" === optionData ? optionData = !1 : "true" === optionData && (optionData = !0)), - userOptions[option] = optionData); - } - var option, dataoptions, optionData, p, attrOptions = npt.getAttribute("data-inputmask"); - if (attrOptions && "" !== attrOptions && (attrOptions = attrOptions.replace(new RegExp("'", "g"), '"'), - dataoptions = JSON.parse("{" + attrOptions + "}")), dataoptions) { - optionData = void 0; - for (p in dataoptions) if ("alias" === p.toLowerCase()) { - optionData = dataoptions[p]; - break; - } - } - importOption("alias", optionData), userOptions.alias && resolveAlias(userOptions.alias, userOptions, opts); - for (option in opts) { - if (dataoptions) { - optionData = void 0; - for (p in dataoptions) if (p.toLowerCase() === option.toLowerCase()) { - optionData = dataoptions[p]; - break; - } - } - importOption(option, optionData); - } - return $.extend(!0, opts, userOptions), opts; - } - function generateMaskSet(opts, nocache) { - function analyseMask(mask) { - function MaskToken(isGroup, isOptional, isQuantifier, isAlternator) { - this.matches = [], this.isGroup = isGroup || !1, this.isOptional = isOptional || !1, - this.isQuantifier = isQuantifier || !1, this.isAlternator = isAlternator || !1, - this.quantifier = { - min: 1, - max: 1 - }; - } - function insertTestDefinition(mtoken, element, position) { - var maskdef = opts.definitions[element]; - position = void 0 !== position ? position : mtoken.matches.length; - var prevMatch = mtoken.matches[position - 1]; - if (maskdef && !escaped) { - maskdef.placeholder = $.isFunction(maskdef.placeholder) ? maskdef.placeholder(opts) : maskdef.placeholder; - for (var prevalidators = maskdef.prevalidator, prevalidatorsL = prevalidators ? prevalidators.length : 0, i = 1; i < maskdef.cardinality; i++) { - var prevalidator = prevalidatorsL >= i ? prevalidators[i - 1] : [], validator = prevalidator.validator, cardinality = prevalidator.cardinality; - mtoken.matches.splice(position++, 0, { - fn: validator ? "string" == typeof validator ? new RegExp(validator) : new function() { - this.test = validator; - }() : new RegExp("."), - cardinality: cardinality ? cardinality : 1, - optionality: mtoken.isOptional, - newBlockMarker: void 0 === prevMatch || prevMatch.def !== (maskdef.definitionSymbol || element), - casing: maskdef.casing, - def: maskdef.definitionSymbol || element, - placeholder: maskdef.placeholder, - mask: element - }), prevMatch = mtoken.matches[position - 1]; - } - mtoken.matches.splice(position++, 0, { - fn: maskdef.validator ? "string" == typeof maskdef.validator ? new RegExp(maskdef.validator) : new function() { - this.test = maskdef.validator; - }() : new RegExp("."), - cardinality: maskdef.cardinality, - optionality: mtoken.isOptional, - newBlockMarker: void 0 === prevMatch || prevMatch.def !== (maskdef.definitionSymbol || element), - casing: maskdef.casing, - def: maskdef.definitionSymbol || element, - placeholder: maskdef.placeholder, - mask: element - }); - } else mtoken.matches.splice(position++, 0, { - fn: null, - cardinality: 0, - optionality: mtoken.isOptional, - newBlockMarker: void 0 === prevMatch || prevMatch.def !== element, - casing: null, - def: opts.staticDefinitionSymbol || element, - placeholder: void 0 !== opts.staticDefinitionSymbol ? element : void 0, - mask: element - }), escaped = !1; - } - function verifyGroupMarker(lastMatch, isOpenGroup) { - lastMatch.isGroup && (lastMatch.isGroup = !1, insertTestDefinition(lastMatch, opts.groupmarker.start, 0), - isOpenGroup !== !0 && insertTestDefinition(lastMatch, opts.groupmarker.end)); - } - function maskCurrentToken(m, currentToken, lastMatch, extraCondition) { - currentToken.matches.length > 0 && (void 0 === extraCondition || extraCondition) && (lastMatch = currentToken.matches[currentToken.matches.length - 1], - verifyGroupMarker(lastMatch)), insertTestDefinition(currentToken, m); - } - function defaultCase() { - if (openenings.length > 0) { - if (currentOpeningToken = openenings[openenings.length - 1], maskCurrentToken(m, currentOpeningToken, lastMatch, !currentOpeningToken.isAlternator), - currentOpeningToken.isAlternator) { - alternator = openenings.pop(); - for (var mndx = 0; mndx < alternator.matches.length; mndx++) alternator.matches[mndx].isGroup = !1; - openenings.length > 0 ? (currentOpeningToken = openenings[openenings.length - 1], - currentOpeningToken.matches.push(alternator)) : currentToken.matches.push(alternator); - } - } else maskCurrentToken(m, currentToken, lastMatch); - } - function reverseTokens(maskToken) { - function reverseStatic(st) { - return st === opts.optionalmarker.start ? st = opts.optionalmarker.end : st === opts.optionalmarker.end ? st = opts.optionalmarker.start : st === opts.groupmarker.start ? st = opts.groupmarker.end : st === opts.groupmarker.end && (st = opts.groupmarker.start), - st; - } - maskToken.matches = maskToken.matches.reverse(); - for (var match in maskToken.matches) { - var intMatch = parseInt(match); - if (maskToken.matches[match].isQuantifier && maskToken.matches[intMatch + 1] && maskToken.matches[intMatch + 1].isGroup) { - var qt = maskToken.matches[match]; - maskToken.matches.splice(match, 1), maskToken.matches.splice(intMatch + 1, 0, qt); - } - void 0 !== maskToken.matches[match].matches ? maskToken.matches[match] = reverseTokens(maskToken.matches[match]) : maskToken.matches[match] = reverseStatic(maskToken.matches[match]); - } - return maskToken; - } - for (var match, m, openingToken, currentOpeningToken, alternator, lastMatch, groupToken, tokenizer = /(?:[?*+]|\{[0-9\+\*]+(?:,[0-9\+\*]*)?\})|[^.?*+^${[]()|\\]+|./g, escaped = !1, currentToken = new MaskToken(), openenings = [], maskTokens = []; match = tokenizer.exec(mask); ) if (m = match[0], - escaped) defaultCase(); else switch (m.charAt(0)) { - case opts.escapeChar: - escaped = !0; - break; - - case opts.optionalmarker.end: - case opts.groupmarker.end: - if (openingToken = openenings.pop(), void 0 !== openingToken) if (openenings.length > 0) { - if (currentOpeningToken = openenings[openenings.length - 1], currentOpeningToken.matches.push(openingToken), - currentOpeningToken.isAlternator) { - alternator = openenings.pop(); - for (var mndx = 0; mndx < alternator.matches.length; mndx++) alternator.matches[mndx].isGroup = !1; - openenings.length > 0 ? (currentOpeningToken = openenings[openenings.length - 1], - currentOpeningToken.matches.push(alternator)) : currentToken.matches.push(alternator); - } - } else currentToken.matches.push(openingToken); else defaultCase(); - break; - - case opts.optionalmarker.start: - openenings.push(new MaskToken(!1, !0)); - break; - - case opts.groupmarker.start: - openenings.push(new MaskToken(!0)); - break; - - case opts.quantifiermarker.start: - var quantifier = new MaskToken(!1, !1, !0); - m = m.replace(/[{}]/g, ""); - var mq = m.split(","), mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), mq1 = 1 === mq.length ? mq0 : isNaN(mq[1]) ? mq[1] : parseInt(mq[1]); - if (("*" === mq1 || "+" === mq1) && (mq0 = "*" === mq1 ? 0 : 1), quantifier.quantifier = { - min: mq0, - max: mq1 - }, openenings.length > 0) { - var matches = openenings[openenings.length - 1].matches; - match = matches.pop(), match.isGroup || (groupToken = new MaskToken(!0), groupToken.matches.push(match), - match = groupToken), matches.push(match), matches.push(quantifier); - } else match = currentToken.matches.pop(), match.isGroup || (groupToken = new MaskToken(!0), - groupToken.matches.push(match), match = groupToken), currentToken.matches.push(match), - currentToken.matches.push(quantifier); - break; - - case opts.alternatormarker: - openenings.length > 0 ? (currentOpeningToken = openenings[openenings.length - 1], - lastMatch = currentOpeningToken.matches.pop()) : lastMatch = currentToken.matches.pop(), - lastMatch.isAlternator ? openenings.push(lastMatch) : (alternator = new MaskToken(!1, !1, !1, !0), - alternator.matches.push(lastMatch), openenings.push(alternator)); - break; - - default: - defaultCase(); - } - for (;openenings.length > 0; ) openingToken = openenings.pop(), verifyGroupMarker(openingToken, !0), - currentToken.matches.push(openingToken); - return currentToken.matches.length > 0 && (lastMatch = currentToken.matches[currentToken.matches.length - 1], - verifyGroupMarker(lastMatch), maskTokens.push(currentToken)), opts.numericInput && reverseTokens(maskTokens[0]), - maskTokens; - } - function generateMask(mask, metadata) { - if (null === mask || "" === mask) return void 0; - if (1 === mask.length && opts.greedy === !1 && 0 !== opts.repeat && (opts.placeholder = ""), - opts.repeat > 0 || "*" === opts.repeat || "+" === opts.repeat) { - var repeatStart = "*" === opts.repeat ? 0 : "+" === opts.repeat ? 1 : opts.repeat; - mask = opts.groupmarker.start + mask + opts.groupmarker.end + opts.quantifiermarker.start + repeatStart + "," + opts.repeat + opts.quantifiermarker.end; - } - var masksetDefinition; - return void 0 === Inputmask.prototype.masksCache[mask] || nocache === !0 ? (masksetDefinition = { - mask: mask, - maskToken: analyseMask(mask), - validPositions: {}, - _buffer: void 0, - buffer: void 0, - tests: {}, - metadata: metadata - }, nocache !== !0 && (Inputmask.prototype.masksCache[opts.numericInput ? mask.split("").reverse().join("") : mask] = masksetDefinition, - masksetDefinition = $.extend(!0, {}, Inputmask.prototype.masksCache[opts.numericInput ? mask.split("").reverse().join("") : mask]))) : masksetDefinition = $.extend(!0, {}, Inputmask.prototype.masksCache[opts.numericInput ? mask.split("").reverse().join("") : mask]), - masksetDefinition; - } - function preProcessMask(mask) { - return mask = mask.toString(); - } - var ms; - if ($.isFunction(opts.mask) && (opts.mask = opts.mask(opts)), $.isArray(opts.mask)) { - if (opts.mask.length > 1) { - opts.keepStatic = null === opts.keepStatic ? !0 : opts.keepStatic; - var altMask = "("; - return $.each(opts.numericInput ? opts.mask.reverse() : opts.mask, function(ndx, msk) { - altMask.length > 1 && (altMask += ")|("), altMask += preProcessMask(void 0 === msk.mask || $.isFunction(msk.mask) ? msk : msk.mask); - }), altMask += ")", generateMask(altMask, opts.mask); - } - opts.mask = opts.mask.pop(); - } - return opts.mask && (ms = void 0 === opts.mask.mask || $.isFunction(opts.mask.mask) ? generateMask(preProcessMask(opts.mask), opts.mask) : generateMask(preProcessMask(opts.mask.mask), opts.mask)), - ms; - } - function maskScope(actionObj, maskset, opts) { - function getMaskTemplate(baseOnInput, minimalPos, includeInput) { - minimalPos = minimalPos || 0; - var ndxIntlzr, test, testPos, maskTemplate = [], pos = 0, lvp = getLastValidPosition(); - do { - if (baseOnInput === !0 && getMaskSet().validPositions[pos]) { - var validPos = getMaskSet().validPositions[pos]; - test = validPos.match, ndxIntlzr = validPos.locator.slice(), maskTemplate.push(includeInput === !0 ? validPos.input : getPlaceholder(pos, test)); - } else testPos = getTestTemplate(pos, ndxIntlzr, pos - 1), test = testPos.match, - ndxIntlzr = testPos.locator.slice(), (opts.jitMasking === !1 || lvp > pos || isFinite(opts.jitMasking) && opts.jitMasking > pos) && maskTemplate.push(getPlaceholder(pos, test)); - pos++; - } while ((void 0 === maxLength || maxLength > pos - 1) && null !== test.fn || null === test.fn && "" !== test.def || minimalPos >= pos); - return "" === maskTemplate[maskTemplate.length - 1] && maskTemplate.pop(), maskTemplate; - } - function getMaskSet() { - return maskset; - } - function resetMaskSet(soft) { - var maskset = getMaskSet(); - maskset.buffer = void 0, soft !== !0 && (maskset.tests = {}, maskset._buffer = void 0, - maskset.validPositions = {}, maskset.p = 0); - } - function getLastValidPosition(closestTo, strict, validPositions) { - var before = -1, after = -1, valids = validPositions || getMaskSet().validPositions; - void 0 === closestTo && (closestTo = -1); - for (var posNdx in valids) { - var psNdx = parseInt(posNdx); - valids[psNdx] && (strict || null !== valids[psNdx].match.fn) && (closestTo >= psNdx && (before = psNdx), - psNdx >= closestTo && (after = psNdx)); - } - return -1 !== before && closestTo - before > 1 || closestTo > after ? before : after; - } - function setValidPosition(pos, validTest, fromSetValid, isSelection) { - if (isSelection || opts.insertMode && void 0 !== getMaskSet().validPositions[pos] && void 0 === fromSetValid) { - var i, positionsClone = $.extend(!0, {}, getMaskSet().validPositions), lvp = getLastValidPosition(); - for (i = pos; lvp >= i; i++) delete getMaskSet().validPositions[i]; - getMaskSet().validPositions[pos] = validTest; - var j, valid = !0, vps = getMaskSet().validPositions, needsValidation = !1; - for (i = j = pos; lvp >= i; i++) { - var t = positionsClone[i]; - if (void 0 !== t) for (var posMatch = j, prevPosMatch = -1; posMatch < getMaskLength() && (null == t.match.fn && vps[i] && (vps[i].match.optionalQuantifier === !0 || vps[i].match.optionality === !0) || null != t.match.fn); ) { - if (null === t.match.fn || !opts.keepStatic && vps[i] && (void 0 !== vps[i + 1] && getTests(i + 1, vps[i].locator.slice(), i).length > 1 || void 0 !== vps[i].alternation) ? posMatch++ : posMatch = seekNext(j), - needsValidation === !1 && positionsClone[posMatch] && positionsClone[posMatch].match.def === t.match.def) { - getMaskSet().validPositions[posMatch] = $.extend(!0, {}, positionsClone[posMatch]), - getMaskSet().validPositions[posMatch].input = t.input, j = posMatch, valid = !0; - break; - } - if (positionCanMatchDefinition(posMatch, t.match.def)) { - var result = isValid(posMatch, t.input, !0, !0); - if (valid = result !== !1, j = result.caret || result.insert ? getLastValidPosition() : posMatch, - needsValidation = !0, valid) break; - } else { - if (valid = null == t.match.fn, prevPosMatch === posMatch) break; - prevPosMatch = posMatch; - } - } - if (!valid) break; - } - if (!valid) return getMaskSet().validPositions = $.extend(!0, {}, positionsClone), - resetMaskSet(!0), !1; - } else getMaskSet().validPositions[pos] = validTest; - return resetMaskSet(!0), !0; - } - function stripValidPositions(start, end, nocheck, strict) { - function IsEnclosedStatic(pos) { - var posMatch = getMaskSet().validPositions[pos]; - if (void 0 !== posMatch && null === posMatch.match.fn) { - var prevMatch = getMaskSet().validPositions[pos - 1], nextMatch = getMaskSet().validPositions[pos + 1]; - return void 0 !== prevMatch && void 0 !== nextMatch; - } - return !1; - } - var i, startPos = start, positionsClone = $.extend(!0, {}, getMaskSet().validPositions), needsValidation = !1; - for (getMaskSet().p = start, i = end - 1; i >= startPos; i--) void 0 !== getMaskSet().validPositions[i] && (nocheck === !0 || !IsEnclosedStatic(i) && opts.canClearPosition(getMaskSet(), i, getLastValidPosition(), strict, opts) !== !1) && delete getMaskSet().validPositions[i]; - for (resetMaskSet(!0), i = startPos + 1; i <= getLastValidPosition(); ) { - for (;void 0 !== getMaskSet().validPositions[startPos]; ) startPos++; - var s = getMaskSet().validPositions[startPos]; - if (startPos > i && (i = startPos + 1), void 0 === getMaskSet().validPositions[i] && isMask(i) || void 0 !== s) i++; else { - var t = getTestTemplate(i); - needsValidation === !1 && positionsClone[startPos] && positionsClone[startPos].match.def === t.match.def ? (getMaskSet().validPositions[startPos] = $.extend(!0, {}, positionsClone[startPos]), - getMaskSet().validPositions[startPos].input = t.input, delete getMaskSet().validPositions[i], - i++) : positionCanMatchDefinition(startPos, t.match.def) ? isValid(startPos, t.input || getPlaceholder(i), !0) !== !1 && (delete getMaskSet().validPositions[i], - i++, needsValidation = !0) : isMask(i) || (i++, startPos--), startPos++; - } - } - resetMaskSet(!0); - } - function getTestTemplate(pos, ndxIntlzr, tstPs) { - var testPos = getMaskSet().validPositions[pos]; - if (void 0 === testPos) for (var testPositions = getTests(pos, ndxIntlzr, tstPs), lvp = getLastValidPosition(), lvTest = getMaskSet().validPositions[lvp] || getTests(0)[0], lvTestAltArr = void 0 !== lvTest.alternation ? lvTest.locator[lvTest.alternation].toString().split(",") : [], ndx = 0; ndx < testPositions.length && (testPos = testPositions[ndx], - !(testPos.match && (opts.greedy && testPos.match.optionalQuantifier !== !0 || (testPos.match.optionality === !1 || testPos.match.newBlockMarker === !1) && testPos.match.optionalQuantifier !== !0) && (void 0 === lvTest.alternation || lvTest.alternation !== testPos.alternation || void 0 !== testPos.locator[lvTest.alternation] && checkAlternationMatch(testPos.locator[lvTest.alternation].toString().split(","), lvTestAltArr)))); ndx++) ; - return testPos; - } - function getTest(pos) { - return getMaskSet().validPositions[pos] ? getMaskSet().validPositions[pos].match : getTests(pos)[0].match; - } - function positionCanMatchDefinition(pos, def) { - for (var valid = !1, tests = getTests(pos), tndx = 0; tndx < tests.length; tndx++) if (tests[tndx].match && tests[tndx].match.def === def) { - valid = !0; - break; - } - return valid; - } - function selectBestMatch(pos, alternateNdx) { - var bestMatch, indexPos; - return (getMaskSet().tests[pos] || getMaskSet().validPositions[pos]) && $.each(getMaskSet().tests[pos] || [ getMaskSet().validPositions[pos] ], function(ndx, lmnt) { - var ndxPos = lmnt.alternation ? lmnt.locator[lmnt.alternation].toString().indexOf(alternateNdx) : -1; - (void 0 === indexPos || indexPos > ndxPos) && -1 !== ndxPos && (bestMatch = lmnt, - indexPos = ndxPos); - }), bestMatch; - } - function getTests(pos, ndxIntlzr, tstPs) { - function resolveTestFromToken(maskToken, ndxInitializer, loopNdx, quantifierRecurse) { - function handleMatch(match, loopNdx, quantifierRecurse) { - function isFirstMatch(latestMatch, tokenGroup) { - var firstMatch = 0 === $.inArray(latestMatch, tokenGroup.matches); - return firstMatch || $.each(tokenGroup.matches, function(ndx, match) { - return match.isQuantifier === !0 && (firstMatch = isFirstMatch(latestMatch, tokenGroup.matches[ndx - 1])) ? !1 : void 0; - }), firstMatch; - } - function resolveNdxInitializer(pos, alternateNdx) { - var bestMatch = selectBestMatch(pos, alternateNdx); - return bestMatch ? bestMatch.locator.slice(bestMatch.alternation + 1) : []; - } - if (testPos > 1e4) throw "Inputmask: There is probably an error in your mask definition or in the code. Create an issue on github with an example of the mask you are using. " + getMaskSet().mask; - if (testPos === pos && void 0 === match.matches) return matches.push({ - match: match, - locator: loopNdx.reverse(), - cd: cacheDependency - }), !0; - if (void 0 !== match.matches) { - if (match.isGroup && quantifierRecurse !== match) { - if (match = handleMatch(maskToken.matches[$.inArray(match, maskToken.matches) + 1], loopNdx)) return !0; - } else if (match.isOptional) { - var optionalToken = match; - if (match = resolveTestFromToken(match, ndxInitializer, loopNdx, quantifierRecurse)) { - if (latestMatch = matches[matches.length - 1].match, !isFirstMatch(latestMatch, optionalToken)) return !0; - insertStop = !0, testPos = pos; - } - } else if (match.isAlternator) { - var maltMatches, alternateToken = match, malternateMatches = [], currentMatches = matches.slice(), loopNdxCnt = loopNdx.length, altIndex = ndxInitializer.length > 0 ? ndxInitializer.shift() : -1; - if (-1 === altIndex || "string" == typeof altIndex) { - var amndx, currentPos = testPos, ndxInitializerClone = ndxInitializer.slice(), altIndexArr = []; - if ("string" == typeof altIndex) altIndexArr = altIndex.split(","); else for (amndx = 0; amndx < alternateToken.matches.length; amndx++) altIndexArr.push(amndx); - for (var ndx = 0; ndx < altIndexArr.length; ndx++) { - if (amndx = parseInt(altIndexArr[ndx]), matches = [], ndxInitializer = resolveNdxInitializer(testPos, amndx), - match = handleMatch(alternateToken.matches[amndx] || maskToken.matches[amndx], [ amndx ].concat(loopNdx), quantifierRecurse) || match, - match !== !0 && void 0 !== match && altIndexArr[altIndexArr.length - 1] < alternateToken.matches.length) { - var ntndx = $.inArray(match, maskToken.matches) + 1; - maskToken.matches.length > ntndx && (match = handleMatch(maskToken.matches[ntndx], [ ntndx ].concat(loopNdx.slice(1, loopNdx.length)), quantifierRecurse), - match && (altIndexArr.push(ntndx.toString()), $.each(matches, function(ndx, lmnt) { - lmnt.alternation = loopNdx.length - 1; - }))); - } - maltMatches = matches.slice(), testPos = currentPos, matches = []; - for (var i = 0; i < ndxInitializerClone.length; i++) ndxInitializer[i] = ndxInitializerClone[i]; - for (var ndx1 = 0; ndx1 < maltMatches.length; ndx1++) { - var altMatch = maltMatches[ndx1]; - altMatch.alternation = altMatch.alternation || loopNdxCnt; - for (var ndx2 = 0; ndx2 < malternateMatches.length; ndx2++) { - var altMatch2 = malternateMatches[ndx2]; - if (altMatch.match.def === altMatch2.match.def && ("string" != typeof altIndex || -1 !== $.inArray(altMatch.locator[altMatch.alternation].toString(), altIndexArr))) { - altMatch.match.mask === altMatch2.match.mask && (maltMatches.splice(ndx1, 1), ndx1--), - -1 === altMatch2.locator[altMatch.alternation].toString().indexOf(altMatch.locator[altMatch.alternation]) && (altMatch2.locator[altMatch.alternation] = altMatch2.locator[altMatch.alternation] + "," + altMatch.locator[altMatch.alternation], - altMatch2.alternation = altMatch.alternation); - break; - } - } - } - malternateMatches = malternateMatches.concat(maltMatches); - } - "string" == typeof altIndex && (malternateMatches = $.map(malternateMatches, function(lmnt, ndx) { - if (isFinite(ndx)) { - var mamatch, alternation = lmnt.alternation, altLocArr = lmnt.locator[alternation].toString().split(","); - lmnt.locator[alternation] = void 0, lmnt.alternation = void 0; - for (var alndx = 0; alndx < altLocArr.length; alndx++) mamatch = -1 !== $.inArray(altLocArr[alndx], altIndexArr), - mamatch && (void 0 !== lmnt.locator[alternation] ? (lmnt.locator[alternation] += ",", - lmnt.locator[alternation] += altLocArr[alndx]) : lmnt.locator[alternation] = parseInt(altLocArr[alndx]), - lmnt.alternation = alternation); - if (void 0 !== lmnt.locator[alternation]) return lmnt; - } - })), matches = currentMatches.concat(malternateMatches), testPos = pos, insertStop = matches.length > 0; - } else match = handleMatch(alternateToken.matches[altIndex] || maskToken.matches[altIndex], [ altIndex ].concat(loopNdx), quantifierRecurse); - if (match) return !0; - } else if (match.isQuantifier && quantifierRecurse !== maskToken.matches[$.inArray(match, maskToken.matches) - 1]) for (var qt = match, qndx = ndxInitializer.length > 0 ? ndxInitializer.shift() : 0; qndx < (isNaN(qt.quantifier.max) ? qndx + 1 : qt.quantifier.max) && pos >= testPos; qndx++) { - var tokenGroup = maskToken.matches[$.inArray(qt, maskToken.matches) - 1]; - if (match = handleMatch(tokenGroup, [ qndx ].concat(loopNdx), tokenGroup)) { - if (latestMatch = matches[matches.length - 1].match, latestMatch.optionalQuantifier = qndx > qt.quantifier.min - 1, - isFirstMatch(latestMatch, tokenGroup)) { - if (qndx > qt.quantifier.min - 1) { - insertStop = !0, testPos = pos; - break; - } - return !0; - } - return !0; - } - } else if (match = resolveTestFromToken(match, ndxInitializer, loopNdx, quantifierRecurse)) return !0; - } else testPos++; - } - for (var tndx = ndxInitializer.length > 0 ? ndxInitializer.shift() : 0; tndx < maskToken.matches.length; tndx++) if (maskToken.matches[tndx].isQuantifier !== !0) { - var match = handleMatch(maskToken.matches[tndx], [ tndx ].concat(loopNdx), quantifierRecurse); - if (match && testPos === pos) return match; - if (testPos > pos) break; - } - } - function mergeLocators(tests) { - var locator = []; - return $.isArray(tests) || (tests = [ tests ]), void 0 === tests[0].alternation ? locator = tests[0].locator.slice() : $.each(tests, function(ndx, tst) { - if ("" !== tst.def) if (0 === locator.length) locator = tst.locator.slice(); else for (var i = 0; i < locator.length; i++) tst.locator[i] && -1 === locator[i].toString().indexOf(tst.locator[i]) && (locator[i] += "," + tst.locator[i]); - }), locator; - } - var latestMatch, maskTokens = getMaskSet().maskToken, testPos = ndxIntlzr ? tstPs : 0, ndxInitializer = ndxIntlzr || [ 0 ], matches = [], insertStop = !1, cacheDependency = ndxIntlzr ? ndxIntlzr.join("") : ""; - if (pos > -1) { - if (void 0 === ndxIntlzr) { - for (var test, previousPos = pos - 1; void 0 === (test = getMaskSet().validPositions[previousPos] || getMaskSet().tests[previousPos]) && previousPos > -1; ) previousPos--; - void 0 !== test && previousPos > -1 && (ndxInitializer = mergeLocators(test), cacheDependency = ndxInitializer.join(""), - testPos = previousPos); - } - if (getMaskSet().tests[pos] && getMaskSet().tests[pos][0].cd === cacheDependency) return getMaskSet().tests[pos]; - for (var mtndx = ndxInitializer.shift(); mtndx < maskTokens.length; mtndx++) { - var match = resolveTestFromToken(maskTokens[mtndx], ndxInitializer, [ mtndx ]); - if (match && testPos === pos || testPos > pos) break; - } - } - return (0 === matches.length || insertStop) && matches.push({ - match: { - fn: null, - cardinality: 0, - optionality: !0, - casing: null, - def: "" - }, - locator: [] - }), getMaskSet().tests[pos] = $.extend(!0, [], matches), getMaskSet().tests[pos]; - } - function getBufferTemplate() { - return void 0 === getMaskSet()._buffer && (getMaskSet()._buffer = getMaskTemplate(!1, 1)), - getMaskSet()._buffer; - } - function getBuffer(noCache) { - if (void 0 === getMaskSet().buffer || noCache === !0) { - if (noCache === !0) for (var testNdx in getMaskSet().tests) void 0 === getMaskSet().validPositions[testNdx] && delete getMaskSet().tests[testNdx]; - getMaskSet().buffer = getMaskTemplate(!0, getLastValidPosition(), !0); - } - return getMaskSet().buffer; - } - function refreshFromBuffer(start, end, buffer) { - var i; - if (buffer = buffer, start === !0) resetMaskSet(), start = 0, end = buffer.length; else for (i = start; end > i; i++) delete getMaskSet().validPositions[i], - delete getMaskSet().tests[i]; - for (i = start; end > i; i++) resetMaskSet(!0), buffer[i] !== opts.skipOptionalPartCharacter && isValid(i, buffer[i], !0, !0); - } - function casing(elem, test) { - switch (test.casing) { - case "upper": - elem = elem.toUpperCase(); - break; - - case "lower": - elem = elem.toLowerCase(); - } - return elem; - } - function checkAlternationMatch(altArr1, altArr2) { - for (var altArrC = opts.greedy ? altArr2 : altArr2.slice(0, 1), isMatch = !1, alndx = 0; alndx < altArr1.length; alndx++) if (-1 !== $.inArray(altArr1[alndx], altArrC)) { - isMatch = !0; - break; - } - return isMatch; - } - function isValid(pos, c, strict, fromSetValid) { - function isSelection(posObj) { - return isRTL ? posObj.begin - posObj.end > 1 || posObj.begin - posObj.end === 1 && opts.insertMode : posObj.end - posObj.begin > 1 || posObj.end - posObj.begin === 1 && opts.insertMode; - } - function _isValid(position, c, strict, fromSetValid) { - var rslt = !1; - return $.each(getTests(position), function(ndx, tst) { - for (var test = tst.match, loopend = c ? 1 : 0, chrs = "", i = test.cardinality; i > loopend; i--) chrs += getBufferElement(position - (i - 1)); - if (c && (chrs += c), getBuffer(!0), rslt = null != test.fn ? test.fn.test(chrs, getMaskSet(), position, strict, opts, isSelection(pos)) : c !== test.def && c !== opts.skipOptionalPartCharacter || "" === test.def ? !1 : { - c: test.placeholder || test.def, - pos: position - }, rslt !== !1) { - var elem = void 0 !== rslt.c ? rslt.c : c; - elem = elem === opts.skipOptionalPartCharacter && null === test.fn ? test.placeholder || test.def : elem; - var validatedPos = position, possibleModifiedBuffer = getBuffer(); - if (void 0 !== rslt.remove && ($.isArray(rslt.remove) || (rslt.remove = [ rslt.remove ]), - $.each(rslt.remove.sort(function(a, b) { - return b - a; - }), function(ndx, lmnt) { - stripValidPositions(lmnt, lmnt + 1, !0); - })), void 0 !== rslt.insert && ($.isArray(rslt.insert) || (rslt.insert = [ rslt.insert ]), - $.each(rslt.insert.sort(function(a, b) { - return a - b; - }), function(ndx, lmnt) { - isValid(lmnt.pos, lmnt.c, !1, fromSetValid); - })), rslt.refreshFromBuffer) { - var refresh = rslt.refreshFromBuffer; - if (strict = !0, refreshFromBuffer(refresh === !0 ? refresh : refresh.start, refresh.end, possibleModifiedBuffer), - void 0 === rslt.pos && void 0 === rslt.c) return rslt.pos = getLastValidPosition(), - !1; - if (validatedPos = void 0 !== rslt.pos ? rslt.pos : position, validatedPos !== position) return rslt = $.extend(rslt, isValid(validatedPos, elem, !0, fromSetValid)), - !1; - } else if (rslt !== !0 && void 0 !== rslt.pos && rslt.pos !== position && (validatedPos = rslt.pos, - refreshFromBuffer(position, validatedPos, getBuffer().slice()), validatedPos !== position)) return rslt = $.extend(rslt, isValid(validatedPos, elem, !0)), - !1; - return rslt !== !0 && void 0 === rslt.pos && void 0 === rslt.c ? !1 : (ndx > 0 && resetMaskSet(!0), - setValidPosition(validatedPos, $.extend({}, tst, { - input: casing(elem, test) - }), fromSetValid, isSelection(pos)) || (rslt = !1), !1); - } - }), rslt; - } - function alternate(pos, c, strict, fromSetValid) { - for (var lastAlt, alternation, isValidRslt, altPos, i, validPos, validPsClone = $.extend(!0, {}, getMaskSet().validPositions), testsClone = $.extend(!0, {}, getMaskSet().tests), lAlt = getLastValidPosition(); lAlt >= 0 && (altPos = getMaskSet().validPositions[lAlt], - !altPos || void 0 === altPos.alternation || (lastAlt = lAlt, alternation = getMaskSet().validPositions[lastAlt].alternation, - getTestTemplate(lastAlt).locator[altPos.alternation] === altPos.locator[altPos.alternation])); lAlt--) ; - if (void 0 !== alternation) { - lastAlt = parseInt(lastAlt); - for (var decisionPos in getMaskSet().validPositions) if (decisionPos = parseInt(decisionPos), - altPos = getMaskSet().validPositions[decisionPos], decisionPos >= lastAlt && void 0 !== altPos.alternation) { - var altNdxs; - 0 === lastAlt ? (altNdxs = [], $.each(getMaskSet().tests[lastAlt], function(ndx, test) { - void 0 !== test.locator[alternation] && (altNdxs = altNdxs.concat(test.locator[alternation].toString().split(","))); - })) : altNdxs = getMaskSet().validPositions[lastAlt].locator[alternation].toString().split(","); - var decisionTaker = void 0 !== altPos.locator[alternation] ? altPos.locator[alternation] : altNdxs[0]; - decisionTaker.length > 0 && (decisionTaker = decisionTaker.split(",")[0]); - for (var mndx = 0; mndx < altNdxs.length; mndx++) { - var validInputs = [], staticInputsBeforePos = 0, staticInputsBeforePosAlternate = 0; - if (decisionTaker < altNdxs[mndx]) { - for (var possibilityPos, possibilities, dp = decisionPos; dp >= 0; dp--) if (possibilityPos = getMaskSet().validPositions[dp], - void 0 !== possibilityPos) { - var bestMatch = selectBestMatch(dp, altNdxs[mndx]); - getMaskSet().validPositions[dp].match.def !== bestMatch.match.def && (validInputs.push(getMaskSet().validPositions[dp].input), - getMaskSet().validPositions[dp] = bestMatch, getMaskSet().validPositions[dp].input = getPlaceholder(dp), - null === getMaskSet().validPositions[dp].match.fn && staticInputsBeforePosAlternate++, - possibilityPos = bestMatch), possibilities = possibilityPos.locator[alternation], - possibilityPos.locator[alternation] = parseInt(altNdxs[mndx]); - break; - } - if (decisionTaker !== possibilityPos.locator[alternation]) { - for (i = decisionPos + 1; i < getLastValidPosition(void 0, !0) + 1; i++) validPos = getMaskSet().validPositions[i], - validPos && null != validPos.match.fn ? validInputs.push(validPos.input) : pos > i && staticInputsBeforePos++, - delete getMaskSet().validPositions[i], delete getMaskSet().tests[i]; - for (resetMaskSet(!0), opts.keepStatic = !opts.keepStatic, isValidRslt = !0; validInputs.length > 0; ) { - var input = validInputs.shift(); - if (input !== opts.skipOptionalPartCharacter && !(isValidRslt = isValid(getLastValidPosition(void 0, !0) + 1, input, !1, fromSetValid))) break; - } - if (possibilityPos.alternation = alternation, possibilityPos.locator[alternation] = possibilities, - isValidRslt) { - var targetLvp = getLastValidPosition(pos) + 1; - for (i = decisionPos + 1; i < getLastValidPosition() + 1; i++) validPos = getMaskSet().validPositions[i], - (void 0 === validPos || null == validPos.match.fn) && pos > i && staticInputsBeforePosAlternate++; - pos += staticInputsBeforePosAlternate - staticInputsBeforePos, isValidRslt = isValid(pos > targetLvp ? targetLvp : pos, c, strict, fromSetValid); - } - if (opts.keepStatic = !opts.keepStatic, isValidRslt) return isValidRslt; - resetMaskSet(), getMaskSet().validPositions = $.extend(!0, {}, validPsClone), getMaskSet().tests = $.extend(!0, {}, testsClone); - } - } - } - break; - } - } - return !1; - } - function trackbackAlternations(originalPos, newPos) { - for (var vp = getMaskSet().validPositions[newPos], targetLocator = vp.locator, tll = targetLocator.length, ps = originalPos; newPos > ps; ps++) if (void 0 === getMaskSet().validPositions[ps] && !isMask(ps, !0)) { - var tests = getTests(ps), bestMatch = tests[0], equality = -1; - $.each(tests, function(ndx, tst) { - for (var i = 0; tll > i && (void 0 !== tst.locator[i] && checkAlternationMatch(tst.locator[i].toString().split(","), targetLocator[i].toString().split(","))); i++) i > equality && (equality = i, - bestMatch = tst); - }), setValidPosition(ps, $.extend({}, bestMatch, { - input: bestMatch.match.placeholder || bestMatch.match.def - }), !0); - } - } - strict = strict === !0; - var maskPos = pos; - void 0 !== pos.begin && (maskPos = isRTL && !isSelection(pos) ? pos.end : pos.begin); - for (var result = !1, positionsClone = $.extend(!0, {}, getMaskSet().validPositions), pndx = maskPos - 1; pndx > -1 && !getMaskSet().validPositions[pndx]; pndx--) ; - var testTemplate; - for (pndx++; maskPos > pndx; pndx++) void 0 === getMaskSet().validPositions[pndx] && (opts.jitMasking === !1 || opts.jitMasking > pndx) && ((testTemplate = getTestTemplate(pndx)).match.def === opts.radixPointDefinitionSymbol || !isMask(pndx, !0) || $.inArray(opts.radixPoint, getBuffer()) < pndx && testTemplate.match.fn && testTemplate.match.fn.test(getPlaceholder(pndx), getMaskSet(), pndx, !1, opts)) && _isValid(getLastValidPosition(pndx, !0) + 1, testTemplate.match.placeholder || (null == testTemplate.match.fn ? testTemplate.match.def : "" !== getPlaceholder(pndx) ? getPlaceholder(pndx) : getBuffer()[pndx]), !0, fromSetValid); - if (isSelection(pos) && (handleRemove(void 0, Inputmask.keyCode.DELETE, pos), maskPos = getMaskSet().p), - maskPos < getMaskLength() && (result = _isValid(maskPos, c, strict, fromSetValid), - (!strict || fromSetValid === !0) && result === !1)) { - var currentPosValid = getMaskSet().validPositions[maskPos]; - if (!currentPosValid || null !== currentPosValid.match.fn || currentPosValid.match.def !== c && c !== opts.skipOptionalPartCharacter) { - if ((opts.insertMode || void 0 === getMaskSet().validPositions[seekNext(maskPos)]) && !isMask(maskPos, !0)) { - var staticChar = getTestTemplate(maskPos).match; - staticChar = staticChar.placeholder || staticChar.def, _isValid(maskPos, staticChar, strict, fromSetValid); - for (var nPos = maskPos + 1, snPos = seekNext(maskPos); snPos >= nPos; nPos++) if (result = _isValid(nPos, c, strict, fromSetValid), - result !== !1) { - trackbackAlternations(maskPos, nPos), maskPos = nPos; - break; - } - } - } else result = { - caret: seekNext(maskPos) - }; - } - return result === !1 && opts.keepStatic && (result = alternate(maskPos, c, strict, fromSetValid)), - result === !0 && (result = { - pos: maskPos - }), $.isFunction(opts.postValidation) && result !== !1 && !strict && fromSetValid !== !0 && (result = opts.postValidation(getBuffer(!0), result, opts) ? result : !1), - void 0 === result.pos && (result.pos = maskPos), result === !1 && (resetMaskSet(!0), - getMaskSet().validPositions = $.extend(!0, {}, positionsClone)), result; - } - function isMask(pos, strict) { - var test; - if (strict ? (test = getTestTemplate(pos).match, "" === test.def && (test = getTest(pos))) : test = getTest(pos), - null != test.fn) return test.fn; - if (strict !== !0 && pos > -1 && !opts.keepStatic && void 0 === getMaskSet().validPositions[pos]) { - var tests = getTests(pos); - return tests.length > 2; - } - return !1; - } - function getMaskLength() { - var maskLength; - maxLength = void 0 !== el ? el.maxLength : void 0, -1 === maxLength && (maxLength = void 0); - var pos, lvp = getLastValidPosition(), testPos = getMaskSet().validPositions[lvp], ndxIntlzr = void 0 !== testPos ? testPos.locator.slice() : void 0; - for (pos = lvp + 1; void 0 === testPos || null !== testPos.match.fn || null === testPos.match.fn && "" !== testPos.match.def; pos++) testPos = getTestTemplate(pos, ndxIntlzr, pos - 1), - ndxIntlzr = testPos.locator.slice(); - var lastTest = getTest(pos - 1); - return maskLength = "" !== lastTest.def ? pos : pos - 1, void 0 === maxLength || maxLength > maskLength ? maskLength : maxLength; - } - function seekNext(pos, newBlock) { - var maskL = getMaskLength(); - if (pos >= maskL) return maskL; - for (var position = pos; ++position < maskL && (newBlock === !0 && (getTest(position).newBlockMarker !== !0 || !isMask(position)) || newBlock !== !0 && !isMask(position) && (opts.nojumps !== !0 || opts.nojumpsThreshold > position)); ) ; - return position; - } - function seekPrevious(pos, newBlock) { - var position = pos; - if (0 >= position) return 0; - for (;--position > 0 && (newBlock === !0 && getTest(position).newBlockMarker !== !0 || newBlock !== !0 && !isMask(position)); ) ; - return position; - } - function getBufferElement(position) { - return void 0 === getMaskSet().validPositions[position] ? getPlaceholder(position) : getMaskSet().validPositions[position].input; - } - function writeBuffer(input, buffer, caretPos, event, triggerInputEvent) { - if (event && $.isFunction(opts.onBeforeWrite)) { - var result = opts.onBeforeWrite(event, buffer, caretPos, opts); - if (result) { - if (result.refreshFromBuffer) { - var refresh = result.refreshFromBuffer; - refreshFromBuffer(refresh === !0 ? refresh : refresh.start, refresh.end, result.buffer || buffer), - buffer = getBuffer(!0); - } - void 0 !== caretPos && (caretPos = void 0 !== result.caret ? result.caret : caretPos); - } - } - input.inputmask._valueSet(buffer.join("")), void 0 === caretPos || void 0 !== event && "blur" === event.type || caret(input, caretPos), - triggerInputEvent === !0 && (skipInputEvent = !0, $(input).trigger("input")); - } - function getPlaceholder(pos, test) { - if (test = test || getTest(pos), void 0 !== test.placeholder) return test.placeholder; - if (null === test.fn) { - if (pos > -1 && !opts.keepStatic && void 0 === getMaskSet().validPositions[pos]) { - var prevTest, tests = getTests(pos), staticAlternations = []; - if (tests.length > 2) for (var i = 0; i < tests.length; i++) if (tests[i].match.optionality !== !0 && tests[i].match.optionalQuantifier !== !0 && (null === tests[i].match.fn || void 0 === prevTest || tests[i].match.fn.test(prevTest.match.def, getMaskSet(), pos, !0, opts) !== !1) && (staticAlternations.push(tests[i]), - null === tests[i].match.fn && (prevTest = tests[i]), staticAlternations.length > 1)) return opts.placeholder.charAt(pos % opts.placeholder.length); - } - return test.def; - } - return opts.placeholder.charAt(pos % opts.placeholder.length); - } - function checkVal(input, writeOut, strict, nptvl) { - function isTemplateMatch() { - var isMatch = !1, charCodeNdx = getBufferTemplate().slice(initialNdx, seekNext(initialNdx)).join("").indexOf(charCodes); - if (-1 !== charCodeNdx && !isMask(initialNdx)) { - isMatch = !0; - for (var bufferTemplateArr = getBufferTemplate().slice(initialNdx, initialNdx + charCodeNdx), i = 0; i < bufferTemplateArr.length; i++) if (" " !== bufferTemplateArr[i]) { - isMatch = !1; - break; - } - } - return isMatch; - } - var result, inputValue = nptvl.slice(), charCodes = "", initialNdx = 0; - if (resetMaskSet(), getMaskSet().p = seekNext(-1), !strict) if (opts.autoUnmask !== !0) { - var staticInput = getBufferTemplate().slice(0, seekNext(-1)).join(""), matches = inputValue.join("").match(new RegExp("^" + Inputmask.escapeRegex(staticInput), "g")); - matches && matches.length > 0 && (inputValue.splice(0, matches.length * staticInput.length), - initialNdx = seekNext(initialNdx)); - } else initialNdx = seekNext(initialNdx); - $.each(inputValue, function(ndx, charCode) { - if (void 0 !== charCode) { - var keypress = new $.Event("keypress"); - keypress.which = charCode.charCodeAt(0), charCodes += charCode; - var lvp = getLastValidPosition(void 0, !0), lvTest = getMaskSet().validPositions[lvp], nextTest = getTestTemplate(lvp + 1, lvTest ? lvTest.locator.slice() : void 0, lvp); - if (!isTemplateMatch() || strict || opts.autoUnmask) { - var pos = strict ? ndx : null == nextTest.match.fn && nextTest.match.optionality && lvp + 1 < getMaskSet().p ? lvp + 1 : getMaskSet().p; - result = keypressEvent.call(input, keypress, !0, !1, strict, pos), initialNdx = pos + 1, - charCodes = ""; - } else result = keypressEvent.call(input, keypress, !0, !1, !0, lvp + 1); - if (!strict && $.isFunction(opts.onBeforeWrite) && (result = opts.onBeforeWrite(keypress, getBuffer(), result.forwardPosition, opts), - result && result.refreshFromBuffer)) { - var refresh = result.refreshFromBuffer; - refreshFromBuffer(refresh === !0 ? refresh : refresh.start, refresh.end, result.buffer), - resetMaskSet(!0), result.caret && (getMaskSet().p = result.caret); - } - } - }), writeOut && writeBuffer(input, getBuffer(), document.activeElement === input ? seekNext(getLastValidPosition(0)) : void 0, new $.Event("checkval")); - } - function unmaskedvalue(input) { - if (input && void 0 === input.inputmask) return input.value; - var umValue = [], vps = getMaskSet().validPositions; - for (var pndx in vps) vps[pndx].match && null != vps[pndx].match.fn && umValue.push(vps[pndx].input); - var unmaskedValue = 0 === umValue.length ? null : (isRTL ? umValue.reverse() : umValue).join(""); - if (null !== unmaskedValue) { - var bufferValue = (isRTL ? getBuffer().slice().reverse() : getBuffer()).join(""); - $.isFunction(opts.onUnMask) && (unmaskedValue = opts.onUnMask(bufferValue, unmaskedValue, opts) || unmaskedValue); - } - return unmaskedValue; - } - function caret(input, begin, end, notranslate) { - function translatePosition(pos) { - if (notranslate !== !0 && isRTL && "number" == typeof pos && (!opts.greedy || "" !== opts.placeholder)) { - var bffrLght = getBuffer().join("").length; - pos = bffrLght - pos; - } - return pos; - } - var range; - if ("number" != typeof begin) return input.setSelectionRange ? (begin = input.selectionStart, - end = input.selectionEnd) : window.getSelection ? (range = window.getSelection().getRangeAt(0), - (range.commonAncestorContainer.parentNode === input || range.commonAncestorContainer === input) && (begin = range.startOffset, - end = range.endOffset)) : document.selection && document.selection.createRange && (range = document.selection.createRange(), - begin = 0 - range.duplicate().moveStart("character", -input.inputmask._valueGet().length), - end = begin + range.text.length), { - begin: translatePosition(begin), - end: translatePosition(end) - }; - begin = translatePosition(begin), end = translatePosition(end), end = "number" == typeof end ? end : begin; - var scrollCalc = parseInt(((input.ownerDocument.defaultView || window).getComputedStyle ? (input.ownerDocument.defaultView || window).getComputedStyle(input, null) : input.currentStyle).fontSize) * end; - if (input.scrollLeft = scrollCalc > input.scrollWidth ? scrollCalc : 0, mobile || opts.insertMode !== !1 || begin !== end || end++, - input.setSelectionRange) input.selectionStart = begin, input.selectionEnd = end; else if (window.getSelection) { - if (range = document.createRange(), void 0 === input.firstChild || null === input.firstChild) { - var textNode = document.createTextNode(""); - input.appendChild(textNode); - } - range.setStart(input.firstChild, begin < input.inputmask._valueGet().length ? begin : input.inputmask._valueGet().length), - range.setEnd(input.firstChild, end < input.inputmask._valueGet().length ? end : input.inputmask._valueGet().length), - range.collapse(!0); - var sel = window.getSelection(); - sel.removeAllRanges(), sel.addRange(range); - } else input.createTextRange && (range = input.createTextRange(), range.collapse(!0), - range.moveEnd("character", end), range.moveStart("character", begin), range.select()); - } - function determineLastRequiredPosition(returnDefinition) { - var pos, testPos, buffer = getBuffer(), bl = buffer.length, lvp = getLastValidPosition(), positions = {}, lvTest = getMaskSet().validPositions[lvp], ndxIntlzr = void 0 !== lvTest ? lvTest.locator.slice() : void 0; - for (pos = lvp + 1; pos < buffer.length; pos++) testPos = getTestTemplate(pos, ndxIntlzr, pos - 1), - ndxIntlzr = testPos.locator.slice(), positions[pos] = $.extend(!0, {}, testPos); - var lvTestAlt = lvTest && void 0 !== lvTest.alternation ? lvTest.locator[lvTest.alternation] : void 0; - for (pos = bl - 1; pos > lvp && (testPos = positions[pos], (testPos.match.optionality || testPos.match.optionalQuantifier || lvTestAlt && (lvTestAlt !== positions[pos].locator[lvTest.alternation] && null != testPos.match.fn || null === testPos.match.fn && testPos.locator[lvTest.alternation] && checkAlternationMatch(testPos.locator[lvTest.alternation].toString().split(","), lvTestAlt.toString().split(",")) && "" !== getTests(pos)[0].def)) && buffer[pos] === getPlaceholder(pos, testPos.match)); pos--) bl--; - return returnDefinition ? { - l: bl, - def: positions[bl] ? positions[bl].match : void 0 - } : bl; - } - function clearOptionalTail(buffer) { - for (var rl = determineLastRequiredPosition(), lmib = buffer.length - 1; lmib > rl && !isMask(lmib); lmib--) ; - return buffer.splice(rl, lmib + 1 - rl), buffer; - } - function isComplete(buffer) { - if ($.isFunction(opts.isComplete)) return opts.isComplete(buffer, opts); - if ("*" === opts.repeat) return void 0; - var complete = !1, lrp = determineLastRequiredPosition(!0), aml = seekPrevious(lrp.l); - if (void 0 === lrp.def || lrp.def.newBlockMarker || lrp.def.optionality || lrp.def.optionalQuantifier) { - complete = !0; - for (var i = 0; aml >= i; i++) { - var test = getTestTemplate(i).match; - if (null !== test.fn && void 0 === getMaskSet().validPositions[i] && test.optionality !== !0 && test.optionalQuantifier !== !0 || null === test.fn && buffer[i] !== getPlaceholder(i, test)) { - complete = !1; - break; - } - } - } - return complete; - } - function patchValueProperty(npt) { - function patchValhook(type) { - if ($.valHooks && (void 0 === $.valHooks[type] || $.valHooks[type].inputmaskpatch !== !0)) { - var valhookGet = $.valHooks[type] && $.valHooks[type].get ? $.valHooks[type].get : function(elem) { - return elem.value; - }, valhookSet = $.valHooks[type] && $.valHooks[type].set ? $.valHooks[type].set : function(elem, value) { - return elem.value = value, elem; - }; - $.valHooks[type] = { - get: function(elem) { - if (elem.inputmask) { - if (elem.inputmask.opts.autoUnmask) return elem.inputmask.unmaskedvalue(); - var result = valhookGet(elem); - return -1 !== getLastValidPosition(void 0, void 0, elem.inputmask.maskset.validPositions) || opts.nullable !== !0 ? result : ""; - } - return valhookGet(elem); - }, - set: function(elem, value) { - var result, $elem = $(elem); - return result = valhookSet(elem, value), elem.inputmask && $elem.trigger("setvalue"), - result; - }, - inputmaskpatch: !0 - }; - } - } - function getter() { - return this.inputmask ? this.inputmask.opts.autoUnmask ? this.inputmask.unmaskedvalue() : -1 !== getLastValidPosition() || opts.nullable !== !0 ? document.activeElement === this && opts.clearMaskOnLostFocus ? (isRTL ? clearOptionalTail(getBuffer().slice()).reverse() : clearOptionalTail(getBuffer().slice())).join("") : valueGet.call(this) : "" : valueGet.call(this); - } - function setter(value) { - valueSet.call(this, value), this.inputmask && $(this).trigger("setvalue"); - } - function installNativeValueSetFallback(npt) { - EventRuler.on(npt, "mouseenter", function(event) { - var $input = $(this), input = this, value = input.inputmask._valueGet(); - value !== getBuffer().join("") && $input.trigger("setvalue"); - }); - } - var valueGet, valueSet; - if (!npt.inputmask.__valueGet) { - if (Object.getOwnPropertyDescriptor) { - "function" != typeof Object.getPrototypeOf && (Object.getPrototypeOf = "object" == typeof "test".__proto__ ? function(object) { - return object.__proto__; - } : function(object) { - return object.constructor.prototype; - }); - var valueProperty = Object.getPrototypeOf ? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(npt), "value") : void 0; - valueProperty && valueProperty.get && valueProperty.set ? (valueGet = valueProperty.get, - valueSet = valueProperty.set, Object.defineProperty(npt, "value", { - get: getter, - set: setter, - configurable: !0 - })) : "INPUT" !== npt.tagName && (valueGet = function() { - return this.textContent; - }, valueSet = function(value) { - this.textContent = value; - }, Object.defineProperty(npt, "value", { - get: getter, - set: setter, - configurable: !0 - })); - } else document.__lookupGetter__ && npt.__lookupGetter__("value") && (valueGet = npt.__lookupGetter__("value"), - valueSet = npt.__lookupSetter__("value"), npt.__defineGetter__("value", getter), - npt.__defineSetter__("value", setter)); - npt.inputmask.__valueGet = valueGet, npt.inputmask._valueGet = function(overruleRTL) { - return isRTL && overruleRTL !== !0 ? valueGet.call(this.el).split("").reverse().join("") : valueGet.call(this.el); - }, npt.inputmask.__valueSet = valueSet, npt.inputmask._valueSet = function(value, overruleRTL) { - valueSet.call(this.el, null === value || void 0 === value ? "" : overruleRTL !== !0 && isRTL ? value.split("").reverse().join("") : value); - }, void 0 === valueGet && (valueGet = function() { - return this.value; - }, valueSet = function(value) { - this.value = value; - }, patchValhook(npt.type), installNativeValueSetFallback(npt)); - } - } - function handleRemove(input, k, pos, strict) { - function generalize() { - if (opts.keepStatic) { - resetMaskSet(!0); - var lastAlt, validInputs = [], positionsClone = $.extend(!0, {}, getMaskSet().validPositions); - for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) { - var validPos = getMaskSet().validPositions[lastAlt]; - if (validPos && (null != validPos.match.fn && validInputs.push(validPos.input), - delete getMaskSet().validPositions[lastAlt], void 0 !== validPos.alternation && validPos.locator[validPos.alternation] === getTestTemplate(lastAlt).locator[validPos.alternation])) break; - } - if (lastAlt > -1) for (;validInputs.length > 0; ) { - getMaskSet().p = seekNext(getLastValidPosition()); - var keypress = new $.Event("keypress"); - keypress.which = validInputs.pop().charCodeAt(0), keypressEvent.call(input, keypress, !0, !1, !1, getMaskSet().p); - } else getMaskSet().validPositions = $.extend(!0, {}, positionsClone); - } - } - if ((opts.numericInput || isRTL) && (k === Inputmask.keyCode.BACKSPACE ? k = Inputmask.keyCode.DELETE : k === Inputmask.keyCode.DELETE && (k = Inputmask.keyCode.BACKSPACE), - isRTL)) { - var pend = pos.end; - pos.end = pos.begin, pos.begin = pend; - } - k === Inputmask.keyCode.BACKSPACE && (pos.end - pos.begin < 1 || opts.insertMode === !1) ? (pos.begin = seekPrevious(pos.begin), - void 0 === getMaskSet().validPositions[pos.begin] || getMaskSet().validPositions[pos.begin].input !== opts.groupSeparator && getMaskSet().validPositions[pos.begin].input !== opts.radixPoint || pos.begin--) : k === Inputmask.keyCode.DELETE && pos.begin === pos.end && (pos.end = isMask(pos.end) ? pos.end + 1 : seekNext(pos.end) + 1, - void 0 === getMaskSet().validPositions[pos.begin] || getMaskSet().validPositions[pos.begin].input !== opts.groupSeparator && getMaskSet().validPositions[pos.begin].input !== opts.radixPoint || pos.end++), - stripValidPositions(pos.begin, pos.end, !1, strict), strict !== !0 && generalize(); - var lvp = getLastValidPosition(pos.begin); - lvp < pos.begin ? (-1 === lvp && resetMaskSet(), getMaskSet().p = seekNext(lvp)) : strict !== !0 && (getMaskSet().p = pos.begin); - } - function keydownEvent(e) { - var input = this, $input = $(input), k = e.keyCode, pos = caret(input); - if (k === Inputmask.keyCode.BACKSPACE || k === Inputmask.keyCode.DELETE || iphone && k === Inputmask.keyCode.BACKSPACE_SAFARI || e.ctrlKey && k === Inputmask.keyCode.X && !isInputEventSupported("cut")) e.preventDefault(), - handleRemove(input, k, pos), writeBuffer(input, getBuffer(), getMaskSet().p, e, undoValue !== getBuffer().join("")), - input.inputmask._valueGet() === getBufferTemplate().join("") ? $input.trigger("cleared") : isComplete(getBuffer()) === !0 && $input.trigger("complete"), - opts.showTooltip && (input.title = opts.tooltip || getMaskSet().mask); else if (k === Inputmask.keyCode.END || k === Inputmask.keyCode.PAGE_DOWN) { - e.preventDefault(); - var caretPos = seekNext(getLastValidPosition()); - opts.insertMode || caretPos !== getMaskLength() || e.shiftKey || caretPos--, caret(input, e.shiftKey ? pos.begin : caretPos, caretPos, !0); - } else k === Inputmask.keyCode.HOME && !e.shiftKey || k === Inputmask.keyCode.PAGE_UP ? (e.preventDefault(), - caret(input, 0, e.shiftKey ? pos.begin : 0, !0)) : (opts.undoOnEscape && k === Inputmask.keyCode.ESCAPE || 90 === k && e.ctrlKey) && e.altKey !== !0 ? (checkVal(input, !0, !1, undoValue.split("")), - $input.trigger("click")) : k !== Inputmask.keyCode.INSERT || e.shiftKey || e.ctrlKey ? opts.tabThrough === !0 && k === Inputmask.keyCode.TAB ? (e.shiftKey === !0 ? (null === getTest(pos.begin).fn && (pos.begin = seekNext(pos.begin)), - pos.end = seekPrevious(pos.begin, !0), pos.begin = seekPrevious(pos.end, !0)) : (pos.begin = seekNext(pos.begin, !0), - pos.end = seekNext(pos.begin, !0), pos.end < getMaskLength() && pos.end--), pos.begin < getMaskLength() && (e.preventDefault(), - caret(input, pos.begin, pos.end))) : opts.insertMode !== !1 || e.shiftKey || (k === Inputmask.keyCode.RIGHT ? setTimeout(function() { - var caretPos = caret(input); - caret(input, caretPos.begin); - }, 0) : k === Inputmask.keyCode.LEFT && setTimeout(function() { - var caretPos = caret(input); - caret(input, isRTL ? caretPos.begin + 1 : caretPos.begin - 1); - }, 0)) : (opts.insertMode = !opts.insertMode, caret(input, opts.insertMode || pos.begin !== getMaskLength() ? pos.begin : pos.begin - 1)); - opts.onKeyDown.call(this, e, getBuffer(), caret(input).begin, opts), ignorable = -1 !== $.inArray(k, opts.ignorables); - } - function keypressEvent(e, checkval, writeOut, strict, ndx) { - var input = this, $input = $(input), k = e.which || e.charCode || e.keyCode; - if (!(checkval === !0 || e.ctrlKey && e.altKey) && (e.ctrlKey || e.metaKey || ignorable)) return k === Inputmask.keyCode.ENTER && undoValue !== getBuffer().join("") && (undoValue = getBuffer().join(""), - setTimeout(function() { - $input.trigger("change"); - }, 0)), !0; - if (k) { - 46 === k && e.shiftKey === !1 && "," === opts.radixPoint && (k = 44); - var forwardPosition, pos = checkval ? { - begin: ndx, - end: ndx - } : caret(input), c = String.fromCharCode(k); - getMaskSet().writeOutBuffer = !0; - var valResult = isValid(pos, c, strict); - if (valResult !== !1) { - var p = valResult.pos; - if (resetMaskSet(!0), void 0 !== valResult.caret) forwardPosition = valResult.caret; else { - var vps = getMaskSet().validPositions; - forwardPosition = !opts.keepStatic && (void 0 !== vps[p + 1] && getTests(p + 1, vps[p].locator.slice(), p).length > 1 || void 0 !== vps[p].alternation) ? p + 1 : seekNext(p); - } - getMaskSet().p = forwardPosition; - } - if (writeOut !== !1) { - var self = this; - if (setTimeout(function() { - opts.onKeyValidation.call(self, k, valResult, opts); - }, 0), getMaskSet().writeOutBuffer && valResult !== !1) { - var buffer = getBuffer(); - writeBuffer(input, buffer, opts.numericInput && void 0 === valResult.caret ? seekPrevious(forwardPosition) : forwardPosition, e, checkval !== !0), - checkval !== !0 && setTimeout(function() { - isComplete(buffer) === !0 && $input.trigger("complete"); - }, 0); - } - } - if (opts.showTooltip && (input.title = opts.tooltip || getMaskSet().mask), e.preventDefault(), - checkval) return valResult.forwardPosition = forwardPosition, valResult; - } - } - function pasteEvent(e) { - var tempValue, input = this, ev = e.originalEvent || e, $input = $(input), inputValue = input.inputmask._valueGet(!0), caretPos = caret(input); - isRTL && (tempValue = caretPos.end, caretPos.end = caretPos.begin, caretPos.begin = tempValue); - var valueBeforeCaret = inputValue.substr(0, caretPos.begin), valueAfterCaret = inputValue.substr(caretPos.end, inputValue.length); - valueBeforeCaret === (isRTL ? getBufferTemplate().reverse() : getBufferTemplate()).slice(0, caretPos.begin).join("") && (valueBeforeCaret = ""), - valueAfterCaret === (isRTL ? getBufferTemplate().reverse() : getBufferTemplate()).slice(caretPos.end).join("") && (valueAfterCaret = ""), - isRTL && (tempValue = valueBeforeCaret, valueBeforeCaret = valueAfterCaret, valueAfterCaret = tempValue), - window.clipboardData && window.clipboardData.getData ? inputValue = valueBeforeCaret + window.clipboardData.getData("Text") + valueAfterCaret : ev.clipboardData && ev.clipboardData.getData && (inputValue = valueBeforeCaret + ev.clipboardData.getData("text/plain") + valueAfterCaret); - var pasteValue = inputValue; - if ($.isFunction(opts.onBeforePaste)) { - if (pasteValue = opts.onBeforePaste(inputValue, opts), pasteValue === !1) return e.preventDefault(); - pasteValue || (pasteValue = inputValue); - } - return checkVal(input, !1, !1, isRTL ? pasteValue.split("").reverse() : pasteValue.toString().split("")), - writeBuffer(input, getBuffer(), seekNext(getLastValidPosition()), e, !0), isComplete(getBuffer()) === !0 && $input.trigger("complete"), - e.preventDefault(); - } - function inputFallBackEvent(e) { - var input = this, inputValue = input.inputmask._valueGet(); - if (getBuffer().join("") !== inputValue) { - var caretPos = caret(input); - if (inputValue = inputValue.replace(new RegExp("(" + Inputmask.escapeRegex(getBufferTemplate().join("")) + ")*"), ""), - iemobile) { - var inputChar = inputValue.replace(getBuffer().join(""), ""); - if (1 === inputChar.length) { - var keypress = new $.Event("keypress"); - return keypress.which = inputChar.charCodeAt(0), keypressEvent.call(input, keypress, !0, !0, !1, getMaskSet().validPositions[caretPos.begin - 1] ? caretPos.begin : caretPos.begin - 1), - !1; - } - } - if (caretPos.begin > inputValue.length && (caret(input, inputValue.length), caretPos = caret(input)), - getBuffer().length - inputValue.length !== 1 || inputValue.charAt(caretPos.begin) === getBuffer()[caretPos.begin] || inputValue.charAt(caretPos.begin + 1) === getBuffer()[caretPos.begin] || isMask(caretPos.begin)) { - for (var lvp = getLastValidPosition() + 1, bufferTemplate = getBuffer().slice(lvp).join(""); null === inputValue.match(Inputmask.escapeRegex(bufferTemplate) + "$"); ) bufferTemplate = bufferTemplate.slice(1); - inputValue = inputValue.replace(bufferTemplate, ""), inputValue = inputValue.split(""), - checkVal(input, !0, !1, inputValue), isComplete(getBuffer()) === !0 && $(input).trigger("complete"); - } else e.keyCode = Inputmask.keyCode.BACKSPACE, keydownEvent.call(input, e); - e.preventDefault(); - } - } - function setValueEvent(e) { - var input = this, value = input.inputmask._valueGet(); - checkVal(input, !0, !1, ($.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(value, opts) || value : value).split("")), - undoValue = getBuffer().join(""), (opts.clearMaskOnLostFocus || opts.clearIncomplete) && input.inputmask._valueGet() === getBufferTemplate().join("") && input.inputmask._valueSet(""); - } - function focusEvent(e) { - var input = this, nptValue = input.inputmask._valueGet(); - opts.showMaskOnFocus && (!opts.showMaskOnHover || opts.showMaskOnHover && "" === nptValue) ? input.inputmask._valueGet() !== getBuffer().join("") && writeBuffer(input, getBuffer(), seekNext(getLastValidPosition())) : mouseEnter === !1 && caret(input, seekNext(getLastValidPosition())), - opts.positionCaretOnTab === !0 && setTimeout(function() { - caret(input, seekNext(getLastValidPosition())); - }, 0), undoValue = getBuffer().join(""); - } - function mouseleaveEvent(e) { - var input = this; - if (mouseEnter = !1, opts.clearMaskOnLostFocus && document.activeElement !== input) { - var buffer = getBuffer().slice(), nptValue = input.inputmask._valueGet(); - nptValue !== input.getAttribute("placeholder") && "" !== nptValue && (-1 === getLastValidPosition() && nptValue === getBufferTemplate().join("") ? buffer = [] : clearOptionalTail(buffer), - writeBuffer(input, buffer)); - } - } - function clickEvent(e) { - function doRadixFocus(clickPos) { - if (opts.radixFocus && "" !== opts.radixPoint) { - var vps = getMaskSet().validPositions; - if (void 0 === vps[clickPos] || vps[clickPos].input === getPlaceholder(clickPos)) { - if (clickPos < seekNext(-1)) return !0; - var radixPos = $.inArray(opts.radixPoint, getBuffer()); - if (-1 !== radixPos) { - for (var vp in vps) if (vp > radixPos && vps[vp].input !== getPlaceholder(vp)) return !1; - return !0; - } - } - } - return !1; - } - var input = this; - setTimeout(function() { - if (document.activeElement === input) { - var selectedCaret = caret(input); - if (selectedCaret.begin === selectedCaret.end) if (doRadixFocus(selectedCaret.begin)) caret(input, opts.numericInput ? seekNext($.inArray(opts.radixPoint, getBuffer())) : $.inArray(opts.radixPoint, getBuffer())); else { - var clickPosition = selectedCaret.begin, lvclickPosition = getLastValidPosition(clickPosition, !0), lastPosition = seekNext(lvclickPosition); - if (lastPosition > clickPosition) caret(input, isMask(clickPosition) || isMask(clickPosition - 1) ? clickPosition : seekNext(clickPosition)); else { - var placeholder = getPlaceholder(lastPosition); - ("" !== placeholder && getBuffer()[lastPosition] !== placeholder || !isMask(lastPosition, !0) && getTest(lastPosition).def === placeholder) && (lastPosition = seekNext(lastPosition)), - caret(input, lastPosition); - } - } - } - }, 0); - } - function dblclickEvent(e) { - var input = this; - setTimeout(function() { - caret(input, 0, seekNext(getLastValidPosition())); - }, 0); - } - function cutEvent(e) { - var input = this, $input = $(input), pos = caret(input), ev = e.originalEvent || e, clipboardData = window.clipboardData || ev.clipboardData, clipData = isRTL ? getBuffer().slice(pos.end, pos.begin) : getBuffer().slice(pos.begin, pos.end); - clipboardData.setData("text", isRTL ? clipData.reverse().join("") : clipData.join("")), - document.execCommand && document.execCommand("copy"), handleRemove(input, Inputmask.keyCode.DELETE, pos), - writeBuffer(input, getBuffer(), getMaskSet().p, e, undoValue !== getBuffer().join("")), - input.inputmask._valueGet() === getBufferTemplate().join("") && $input.trigger("cleared"), - opts.showTooltip && (input.title = opts.tooltip || getMaskSet().mask); - } - function blurEvent(e) { - var $input = $(this), input = this; - if (input.inputmask) { - var nptValue = input.inputmask._valueGet(), buffer = getBuffer().slice(); - undoValue !== buffer.join("") && setTimeout(function() { - $input.trigger("change"), undoValue = buffer.join(""); - }, 0), "" !== nptValue && (opts.clearMaskOnLostFocus && (-1 === getLastValidPosition() && nptValue === getBufferTemplate().join("") ? buffer = [] : clearOptionalTail(buffer)), - isComplete(buffer) === !1 && (setTimeout(function() { - $input.trigger("incomplete"); - }, 0), opts.clearIncomplete && (resetMaskSet(), buffer = opts.clearMaskOnLostFocus ? [] : getBufferTemplate().slice())), - writeBuffer(input, buffer, void 0, e)); - } - } - function mouseenterEvent(e) { - var input = this; - mouseEnter = !0, document.activeElement !== input && opts.showMaskOnHover && input.inputmask._valueGet() !== getBuffer().join("") && writeBuffer(input, getBuffer()); - } - function submitEvent(e) { - undoValue !== getBuffer().join("") && $el.trigger("change"), opts.clearMaskOnLostFocus && -1 === getLastValidPosition() && el.inputmask._valueGet && el.inputmask._valueGet() === getBufferTemplate().join("") && el.inputmask._valueSet(""), - opts.removeMaskOnSubmit && (el.inputmask._valueSet(el.inputmask.unmaskedvalue(), !0), - setTimeout(function() { - writeBuffer(el, getBuffer()); - }, 0)); - } - function resetEvent(e) { - setTimeout(function() { - $el.trigger("setvalue"); - }, 0); - } - function mask(elem) { - if (el = elem, $el = $(el), opts.showTooltip && (el.title = opts.tooltip || getMaskSet().mask), - ("rtl" === el.dir || opts.rightAlign) && (el.style.textAlign = "right"), ("rtl" === el.dir || opts.numericInput) && (el.dir = "ltr", - el.removeAttribute("dir"), el.inputmask.isRTL = !0, isRTL = !0), EventRuler.off(el), - patchValueProperty(el), isElementTypeSupported(el, opts) && (EventRuler.on(el, "submit", submitEvent), - EventRuler.on(el, "reset", resetEvent), EventRuler.on(el, "mouseenter", mouseenterEvent), - EventRuler.on(el, "blur", blurEvent), EventRuler.on(el, "focus", focusEvent), EventRuler.on(el, "mouseleave", mouseleaveEvent), - EventRuler.on(el, "click", clickEvent), EventRuler.on(el, "dblclick", dblclickEvent), - EventRuler.on(el, "paste", pasteEvent), EventRuler.on(el, "dragdrop", pasteEvent), - EventRuler.on(el, "drop", pasteEvent), EventRuler.on(el, "cut", cutEvent), EventRuler.on(el, "complete", opts.oncomplete), - EventRuler.on(el, "incomplete", opts.onincomplete), EventRuler.on(el, "cleared", opts.oncleared), - EventRuler.on(el, "keydown", keydownEvent), EventRuler.on(el, "keypress", keypressEvent), - EventRuler.on(el, "input", inputFallBackEvent)), EventRuler.on(el, "setvalue", setValueEvent), - "" !== el.inputmask._valueGet() || opts.clearMaskOnLostFocus === !1 || document.activeElement === el) { - var initialValue = $.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(el.inputmask._valueGet(), opts) || el.inputmask._valueGet() : el.inputmask._valueGet(); - checkVal(el, !0, !1, initialValue.split("")); - var buffer = getBuffer().slice(); - undoValue = buffer.join(""), isComplete(buffer) === !1 && opts.clearIncomplete && resetMaskSet(), - opts.clearMaskOnLostFocus && document.activeElement !== el && (-1 === getLastValidPosition() ? buffer = [] : clearOptionalTail(buffer)), - writeBuffer(el, buffer), document.activeElement === el && caret(el, seekNext(getLastValidPosition())); - } - } - var undoValue, el, $el, maxLength, valueBuffer, isRTL = !1, skipKeyPressEvent = !1, skipInputEvent = !1, ignorable = !1, mouseEnter = !0, EventRuler = { - on: function(input, eventName, eventHandler) { - var ev = function(e) { - if (void 0 === this.inputmask && "FORM" !== this.nodeName) { - var imOpts = $.data(this, "_inputmask_opts"); - imOpts ? new Inputmask(imOpts).mask(this) : EventRuler.off(this); - } else { - if ("setvalue" === e.type || !(this.disabled || this.readOnly && !("keydown" === e.type && e.ctrlKey && 67 === e.keyCode || opts.tabThrough === !1 && e.keyCode === Inputmask.keyCode.TAB))) { - switch (e.type) { - case "input": - if (skipInputEvent === !0) return skipInputEvent = !1, e.preventDefault(); - break; - - case "keydown": - skipKeyPressEvent = !1, skipInputEvent = !1; - break; - - case "keypress": - if (skipKeyPressEvent === !0) return e.preventDefault(); - skipKeyPressEvent = !0; - break; - - case "click": - if (iemobile) { - var that = this; - return setTimeout(function() { - eventHandler.apply(that, arguments); - }, 0), !1; - } - } - var returnVal = eventHandler.apply(this, arguments); - return returnVal === !1 && (e.preventDefault(), e.stopPropagation()), returnVal; - } - e.preventDefault(); - } - }; - input.inputmask.events[eventName] = input.inputmask.events[eventName] || [], input.inputmask.events[eventName].push(ev), - -1 !== $.inArray(eventName, [ "submit", "reset" ]) ? null != input.form && $(input.form).on(eventName, ev) : $(input).on(eventName, ev); - }, - off: function(input, event) { - if (input.inputmask && input.inputmask.events) { - var events; - event ? (events = [], events[event] = input.inputmask.events[event]) : events = input.inputmask.events, - $.each(events, function(eventName, evArr) { - for (;evArr.length > 0; ) { - var ev = evArr.pop(); - -1 !== $.inArray(eventName, [ "submit", "reset" ]) ? null != input.form && $(input.form).off(eventName, ev) : $(input).off(eventName, ev); - } - delete input.inputmask.events[eventName]; - }); - } - } - }; - if (void 0 !== actionObj) switch (actionObj.action) { - case "isComplete": - return el = actionObj.el, isComplete(getBuffer()); - - case "unmaskedvalue": - return el = actionObj.el, void 0 !== el && void 0 !== el.inputmask ? (maskset = el.inputmask.maskset, - opts = el.inputmask.opts, isRTL = el.inputmask.isRTL) : (valueBuffer = actionObj.value, - opts.numericInput && (isRTL = !0), valueBuffer = ($.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(valueBuffer, opts) || valueBuffer : valueBuffer).split(""), - checkVal(void 0, !1, !1, isRTL ? valueBuffer.reverse() : valueBuffer), $.isFunction(opts.onBeforeWrite) && opts.onBeforeWrite(void 0, getBuffer(), 0, opts)), - unmaskedvalue(el); - - case "mask": - el = actionObj.el, maskset = el.inputmask.maskset, opts = el.inputmask.opts, isRTL = el.inputmask.isRTL, - undoValue = getBuffer().join(""), mask(el); - break; - - case "format": - return opts.numericInput && (isRTL = !0), valueBuffer = ($.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(actionObj.value, opts) || actionObj.value : actionObj.value).split(""), - checkVal(void 0, !1, !1, isRTL ? valueBuffer.reverse() : valueBuffer), $.isFunction(opts.onBeforeWrite) && opts.onBeforeWrite(void 0, getBuffer(), 0, opts), - actionObj.metadata ? { - value: isRTL ? getBuffer().slice().reverse().join("") : getBuffer().join(""), - metadata: maskScope({ - action: "getmetadata" - }, maskset, opts) - } : isRTL ? getBuffer().slice().reverse().join("") : getBuffer().join(""); - - case "isValid": - opts.numericInput && (isRTL = !0), actionObj.value ? (valueBuffer = actionObj.value.split(""), - checkVal(void 0, !1, !0, isRTL ? valueBuffer.reverse() : valueBuffer)) : actionObj.value = getBuffer().join(""); - for (var buffer = getBuffer(), rl = determineLastRequiredPosition(), lmib = buffer.length - 1; lmib > rl && !isMask(lmib); lmib--) ; - return buffer.splice(rl, lmib + 1 - rl), isComplete(buffer) && actionObj.value === getBuffer().join(""); - - case "getemptymask": - return getBufferTemplate().join(""); - - case "remove": - el = actionObj.el, $el = $(el), maskset = el.inputmask.maskset, opts = el.inputmask.opts, - el.inputmask._valueSet(unmaskedvalue(el)), EventRuler.off(el); - var valueProperty; - Object.getOwnPropertyDescriptor && Object.getPrototypeOf ? (valueProperty = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(el), "value"), - valueProperty && el.inputmask.__valueGet && Object.defineProperty(el, "value", { - get: el.inputmask.__valueGet, - set: el.inputmask.__valueSet, - configurable: !0 - })) : document.__lookupGetter__ && el.__lookupGetter__("value") && el.inputmask.__valueGet && (el.__defineGetter__("value", el.inputmask.__valueGet), - el.__defineSetter__("value", el.inputmask.__valueSet)), el.inputmask = void 0; - break; - - case "getmetadata": - if ($.isArray(maskset.metadata)) { - for (var alternation, lvp = getLastValidPosition(void 0, !0), firstAlt = lvp; firstAlt >= 0; firstAlt--) if (getMaskSet().validPositions[firstAlt] && void 0 !== getMaskSet().validPositions[firstAlt].alternation) { - alternation = getMaskSet().validPositions[firstAlt].alternation; - break; - } - return void 0 !== alternation ? maskset.metadata[getMaskSet().validPositions[firstAlt].locator[alternation]] : []; - } - return maskset.metadata; - } - } - Inputmask.prototype = { - defaults: { - placeholder: "_", - optionalmarker: { - start: "[", - end: "]" - }, - quantifiermarker: { - start: "{", - end: "}" - }, - groupmarker: { - start: "(", - end: ")" - }, - alternatormarker: "|", - escapeChar: "\\", - mask: null, - oncomplete: $.noop, - onincomplete: $.noop, - oncleared: $.noop, - repeat: 0, - greedy: !0, - autoUnmask: !1, - removeMaskOnSubmit: !1, - clearMaskOnLostFocus: !0, - insertMode: !0, - clearIncomplete: !1, - aliases: {}, - alias: null, - onKeyDown: $.noop, - onBeforeMask: null, - onBeforePaste: function(pastedValue, opts) { - return $.isFunction(opts.onBeforeMask) ? opts.onBeforeMask(pastedValue, opts) : pastedValue; - }, - onBeforeWrite: null, - onUnMask: null, - showMaskOnFocus: !0, - showMaskOnHover: !0, - onKeyValidation: $.noop, - skipOptionalPartCharacter: " ", - showTooltip: !1, - tooltip: void 0, - numericInput: !1, - rightAlign: !1, - undoOnEscape: !0, - radixPoint: "", - radixPointDefinitionSymbol: void 0, - groupSeparator: "", - radixFocus: !1, - nojumps: !1, - nojumpsThreshold: 0, - keepStatic: null, - positionCaretOnTab: !1, - tabThrough: !1, - supportsInputType: [ "text", "tel", "password" ], - definitions: { - "9": { - validator: "[0-9]", - cardinality: 1, - definitionSymbol: "*" - }, - a: { - validator: "[A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]", - cardinality: 1, - definitionSymbol: "*" - }, - "*": { - validator: "[0-9A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]", - cardinality: 1 - } - }, - ignorables: [ 8, 9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123 ], - isComplete: null, - canClearPosition: $.noop, - postValidation: null, - staticDefinitionSymbol: void 0, - jitMasking: !1, - nullable: !0 - }, - masksCache: {}, - mask: function(elems) { - var that = this; - return "string" == typeof elems && (elems = document.getElementById(elems) || document.querySelectorAll(elems)), - elems = elems.nodeName ? [ elems ] : elems, $.each(elems, function(ndx, el) { - var scopedOpts = $.extend(!0, {}, that.opts); - importAttributeOptions(el, scopedOpts, $.extend(!0, {}, that.userOptions)); - var maskset = generateMaskSet(scopedOpts, that.noMasksCache); - void 0 !== maskset && (void 0 !== el.inputmask && el.inputmask.remove(), el.inputmask = new Inputmask(), - el.inputmask.opts = scopedOpts, el.inputmask.noMasksCache = that.noMasksCache, el.inputmask.userOptions = $.extend(!0, {}, that.userOptions), - el.inputmask.el = el, el.inputmask.maskset = maskset, el.inputmask.isRTL = !1, $.data(el, "_inputmask_opts", scopedOpts), - maskScope({ - action: "mask", - el: el - })); - }), elems && elems[0] ? elems[0].inputmask || this : this; - }, - option: function(options, noremask) { - return "string" == typeof options ? this.opts[options] : "object" == typeof options ? ($.extend(this.userOptions, options), - this.el && noremask !== !0 && this.mask(this.el), this) : void 0; - }, - unmaskedvalue: function(value) { - return maskScope({ - action: "unmaskedvalue", - el: this.el, - value: value - }, this.el && this.el.inputmask ? this.el.inputmask.maskset : generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - remove: function() { - return this.el ? (maskScope({ - action: "remove", - el: this.el - }), this.el.inputmask = void 0, this.el) : void 0; - }, - getemptymask: function() { - return maskScope({ - action: "getemptymask" - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - hasMaskedValue: function() { - return !this.opts.autoUnmask; - }, - isComplete: function() { - return maskScope({ - action: "isComplete", - el: this.el - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - getmetadata: function() { - return maskScope({ - action: "getmetadata" - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - isValid: function(value) { - return maskScope({ - action: "isValid", - value: value - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - }, - format: function(value, metadata) { - return maskScope({ - action: "format", - value: value, - metadata: metadata - }, this.maskset || generateMaskSet(this.opts, this.noMasksCache), this.opts); - } - }, Inputmask.extendDefaults = function(options) { - $.extend(!0, Inputmask.prototype.defaults, options); - }, Inputmask.extendDefinitions = function(definition) { - $.extend(!0, Inputmask.prototype.defaults.definitions, definition); - }, Inputmask.extendAliases = function(alias) { - $.extend(!0, Inputmask.prototype.defaults.aliases, alias); - }, Inputmask.format = function(value, options, metadata) { - return Inputmask(options).format(value, metadata); - }, Inputmask.unmask = function(value, options) { - return Inputmask(options).unmaskedvalue(value); - }, Inputmask.isValid = function(value, options) { - return Inputmask(options).isValid(value); - }, Inputmask.remove = function(elems) { - $.each(elems, function(ndx, el) { - el.inputmask && el.inputmask.remove(); - }); - }, Inputmask.escapeRegex = function(str) { - var specials = [ "/", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}", "\\", "$", "^" ]; - return str.replace(new RegExp("(\\" + specials.join("|\\") + ")", "gim"), "\\$1"); - }, Inputmask.keyCode = { - ALT: 18, - BACKSPACE: 8, - BACKSPACE_SAFARI: 127, - CAPS_LOCK: 20, - COMMA: 188, - COMMAND: 91, - COMMAND_LEFT: 91, - COMMAND_RIGHT: 93, - CONTROL: 17, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - INSERT: 45, - LEFT: 37, - MENU: 93, - NUMPAD_ADD: 107, - NUMPAD_DECIMAL: 110, - NUMPAD_DIVIDE: 111, - NUMPAD_ENTER: 108, - NUMPAD_MULTIPLY: 106, - NUMPAD_SUBTRACT: 109, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SHIFT: 16, - SPACE: 32, - TAB: 9, - UP: 38, - WINDOWS: 91, - X: 88 - }; - var ua = navigator.userAgent, mobile = /mobile/i.test(ua), iemobile = /iemobile/i.test(ua), iphone = /iphone/i.test(ua) && !iemobile; - /android.*safari.*/i.test(ua) && !iemobile; - return window.Inputmask = Inputmask, Inputmask; -}(jQuery), function($, Inputmask) { - return void 0 === $.fn.inputmask && ($.fn.inputmask = function(fn, options) { - var nptmask, input = this[0]; - if (void 0 === options && (options = {}), "string" == typeof fn) switch (fn) { - case "unmaskedvalue": - return input && input.inputmask ? input.inputmask.unmaskedvalue() : $(input).val(); - - case "remove": - return this.each(function() { - this.inputmask && this.inputmask.remove(); - }); - - case "getemptymask": - return input && input.inputmask ? input.inputmask.getemptymask() : ""; - - case "hasMaskedValue": - return input && input.inputmask ? input.inputmask.hasMaskedValue() : !1; - - case "isComplete": - return input && input.inputmask ? input.inputmask.isComplete() : !0; - - case "getmetadata": - return input && input.inputmask ? input.inputmask.getmetadata() : void 0; - - case "setvalue": - $(input).val(options), input && void 0 !== input.inputmask && $(input).triggerHandler("setvalue"); - break; - - case "option": - if ("string" != typeof options) return this.each(function() { - return void 0 !== this.inputmask ? this.inputmask.option(options) : void 0; - }); - if (input && void 0 !== input.inputmask) return input.inputmask.option(options); - break; - - default: - return options.alias = fn, nptmask = new Inputmask(options), this.each(function() { - nptmask.mask(this); - }); - } else { - if ("object" == typeof fn) return nptmask = new Inputmask(fn), void 0 === fn.mask && void 0 === fn.alias ? this.each(function() { - return void 0 !== this.inputmask ? this.inputmask.option(fn) : void nptmask.mask(this); - }) : this.each(function() { - nptmask.mask(this); - }); - if (void 0 === fn) return this.each(function() { - nptmask = new Inputmask(options), nptmask.mask(this); - }); - } - }), $.fn.inputmask; -}(jQuery, Inputmask), function($, Inputmask) { - return Inputmask.extendDefinitions({ - h: { - validator: "[01][0-9]|2[0-3]", - cardinality: 2, - prevalidator: [ { - validator: "[0-2]", - cardinality: 1 - } ] - }, - s: { - validator: "[0-5][0-9]", - cardinality: 2, - prevalidator: [ { - validator: "[0-5]", - cardinality: 1 - } ] - }, - d: { - validator: "0[1-9]|[12][0-9]|3[01]", - cardinality: 2, - prevalidator: [ { - validator: "[0-3]", - cardinality: 1 - } ] - }, - m: { - validator: "0[1-9]|1[012]", - cardinality: 2, - prevalidator: [ { - validator: "[01]", - cardinality: 1 - } ] - }, - y: { - validator: "(19|20)\\d{2}", - cardinality: 4, - prevalidator: [ { - validator: "[12]", - cardinality: 1 - }, { - validator: "(19|20)", - cardinality: 2 - }, { - validator: "(19|20)\\d", - cardinality: 3 - } ] - } - }), Inputmask.extendAliases({ - "dd/mm/yyyy": { - mask: "1/2/y", - placeholder: "dd/mm/yyyy", - regex: { - val1pre: new RegExp("[0-3]"), - val1: new RegExp("0[1-9]|[12][0-9]|3[01]"), - val2pre: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|[12][0-9]|3[01])" + escapedSeparator + "[01])"); - }, - val2: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|[12][0-9])" + escapedSeparator + "(0[1-9]|1[012]))|(30" + escapedSeparator + "(0[13-9]|1[012]))|(31" + escapedSeparator + "(0[13578]|1[02]))"); - } - }, - leapday: "29/02/", - separator: "/", - yearrange: { - minyear: 1900, - maxyear: 2099 - }, - isInYearRange: function(chrs, minyear, maxyear) { - if (isNaN(chrs)) return !1; - var enteredyear = parseInt(chrs.concat(minyear.toString().slice(chrs.length))), enteredyear2 = parseInt(chrs.concat(maxyear.toString().slice(chrs.length))); - return (isNaN(enteredyear) ? !1 : enteredyear >= minyear && maxyear >= enteredyear) || (isNaN(enteredyear2) ? !1 : enteredyear2 >= minyear && maxyear >= enteredyear2); - }, - determinebaseyear: function(minyear, maxyear, hint) { - var currentyear = new Date().getFullYear(); - if (minyear > currentyear) return minyear; - if (currentyear > maxyear) { - for (var maxYearPrefix = maxyear.toString().slice(0, 2), maxYearPostfix = maxyear.toString().slice(2, 4); maxYearPrefix + hint > maxyear; ) maxYearPrefix--; - var maxxYear = maxYearPrefix + maxYearPostfix; - return minyear > maxxYear ? minyear : maxxYear; - } - if (currentyear >= minyear && maxyear >= currentyear) { - for (var currentYearPrefix = currentyear.toString().slice(0, 2); currentYearPrefix + hint > maxyear; ) currentYearPrefix--; - var currentYearAndHint = currentYearPrefix + hint; - return minyear > currentYearAndHint ? minyear : currentYearAndHint; - } - return currentyear; - }, - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) { - var today = new Date(); - $input.val(today.getDate().toString() + (today.getMonth() + 1).toString() + today.getFullYear().toString()), - $input.trigger("setvalue"); - } - }, - getFrontValue: function(mask, buffer, opts) { - for (var start = 0, length = 0, i = 0; i < mask.length && "2" !== mask.charAt(i); i++) { - var definition = opts.definitions[mask.charAt(i)]; - definition ? (start += length, length = definition.cardinality) : length++; - } - return buffer.join("").substr(start, length); - }, - definitions: { - "1": { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.regex.val1.test(chrs); - return strict || isValid || chrs.charAt(1) !== opts.separator && -1 === "-./".indexOf(chrs.charAt(1)) || !(isValid = opts.regex.val1.test("0" + chrs.charAt(0))) ? isValid : (maskset.buffer[pos - 1] = "0", - { - refreshFromBuffer: { - start: pos - 1, - end: pos - }, - pos: pos, - c: chrs.charAt(0) - }); - }, - cardinality: 2, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - var pchrs = chrs; - isNaN(maskset.buffer[pos + 1]) || (pchrs += maskset.buffer[pos + 1]); - var isValid = 1 === pchrs.length ? opts.regex.val1pre.test(pchrs) : opts.regex.val1.test(pchrs); - if (!strict && !isValid) { - if (isValid = opts.regex.val1.test(chrs + "0")) return maskset.buffer[pos] = chrs, - maskset.buffer[++pos] = "0", { - pos: pos, - c: "0" - }; - if (isValid = opts.regex.val1.test("0" + chrs)) return maskset.buffer[pos] = "0", - pos++, { - pos: pos - }; - } - return isValid; - }, - cardinality: 1 - } ] - }, - "2": { - validator: function(chrs, maskset, pos, strict, opts) { - var frontValue = opts.getFrontValue(maskset.mask, maskset.buffer, opts); - -1 !== frontValue.indexOf(opts.placeholder[0]) && (frontValue = "01" + opts.separator); - var isValid = opts.regex.val2(opts.separator).test(frontValue + chrs); - if (!strict && !isValid && (chrs.charAt(1) === opts.separator || -1 !== "-./".indexOf(chrs.charAt(1))) && (isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs.charAt(0)))) return maskset.buffer[pos - 1] = "0", - { - refreshFromBuffer: { - start: pos - 1, - end: pos - }, - pos: pos, - c: chrs.charAt(0) - }; - if (opts.mask.indexOf("2") === opts.mask.length - 1 && isValid) { - var dayMonthValue = maskset.buffer.join("").substr(4, 4) + chrs; - if (dayMonthValue !== opts.leapday) return !0; - var year = parseInt(maskset.buffer.join("").substr(0, 4), 10); - return year % 4 === 0 ? year % 100 === 0 ? year % 400 === 0 ? !0 : !1 : !0 : !1; - } - return isValid; - }, - cardinality: 2, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - isNaN(maskset.buffer[pos + 1]) || (chrs += maskset.buffer[pos + 1]); - var frontValue = opts.getFrontValue(maskset.mask, maskset.buffer, opts); - -1 !== frontValue.indexOf(opts.placeholder[0]) && (frontValue = "01" + opts.separator); - var isValid = 1 === chrs.length ? opts.regex.val2pre(opts.separator).test(frontValue + chrs) : opts.regex.val2(opts.separator).test(frontValue + chrs); - return strict || isValid || !(isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs)) ? isValid : (maskset.buffer[pos] = "0", - pos++, { - pos: pos - }); - }, - cardinality: 1 - } ] - }, - y: { - validator: function(chrs, maskset, pos, strict, opts) { - if (opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) { - var dayMonthValue = maskset.buffer.join("").substr(0, 6); - if (dayMonthValue !== opts.leapday) return !0; - var year = parseInt(chrs, 10); - return year % 4 === 0 ? year % 100 === 0 ? year % 400 === 0 ? !0 : !1 : !0 : !1; - } - return !1; - }, - cardinality: 4, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear); - if (!strict && !isValid) { - var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 1); - if (isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) return maskset.buffer[pos++] = yearPrefix.charAt(0), - { - pos: pos - }; - if (yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 2), - isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) return maskset.buffer[pos++] = yearPrefix.charAt(0), - maskset.buffer[pos++] = yearPrefix.charAt(1), { - pos: pos - }; - } - return isValid; - }, - cardinality: 1 - }, { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear); - if (!strict && !isValid) { - var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2); - if (isValid = opts.isInYearRange(chrs[0] + yearPrefix[1] + chrs[1], opts.yearrange.minyear, opts.yearrange.maxyear)) return maskset.buffer[pos++] = yearPrefix.charAt(1), - { - pos: pos - }; - if (yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2), - opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) { - var dayMonthValue = maskset.buffer.join("").substr(0, 6); - if (dayMonthValue !== opts.leapday) isValid = !0; else { - var year = parseInt(chrs, 10); - isValid = year % 4 === 0 ? year % 100 === 0 ? year % 400 === 0 ? !0 : !1 : !0 : !1; - } - } else isValid = !1; - if (isValid) return maskset.buffer[pos - 1] = yearPrefix.charAt(0), maskset.buffer[pos++] = yearPrefix.charAt(1), - maskset.buffer[pos++] = chrs.charAt(0), { - refreshFromBuffer: { - start: pos - 3, - end: pos - }, - pos: pos - }; - } - return isValid; - }, - cardinality: 2 - }, { - validator: function(chrs, maskset, pos, strict, opts) { - return opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear); - }, - cardinality: 3 - } ] - } - }, - insertMode: !1, - autoUnmask: !1 - }, - "mm/dd/yyyy": { - placeholder: "mm/dd/yyyy", - alias: "dd/mm/yyyy", - regex: { - val2pre: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[13-9]|1[012])" + escapedSeparator + "[0-3])|(02" + escapedSeparator + "[0-2])"); - }, - val2: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "(0[1-9]|[12][0-9]))|((0[13-9]|1[012])" + escapedSeparator + "30)|((0[13578]|1[02])" + escapedSeparator + "31)"); - }, - val1pre: new RegExp("[01]"), - val1: new RegExp("0[1-9]|1[012]") - }, - leapday: "02/29/", - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) { - var today = new Date(); - $input.val((today.getMonth() + 1).toString() + today.getDate().toString() + today.getFullYear().toString()), - $input.trigger("setvalue"); - } - } - }, - "yyyy/mm/dd": { - mask: "y/1/2", - placeholder: "yyyy/mm/dd", - alias: "mm/dd/yyyy", - leapday: "/02/29", - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) { - var today = new Date(); - $input.val(today.getFullYear().toString() + (today.getMonth() + 1).toString() + today.getDate().toString()), - $input.trigger("setvalue"); - } - } - }, - "dd.mm.yyyy": { - mask: "1.2.y", - placeholder: "dd.mm.yyyy", - leapday: "29.02.", - separator: ".", - alias: "dd/mm/yyyy" - }, - "dd-mm-yyyy": { - mask: "1-2-y", - placeholder: "dd-mm-yyyy", - leapday: "29-02-", - separator: "-", - alias: "dd/mm/yyyy" - }, - "mm.dd.yyyy": { - mask: "1.2.y", - placeholder: "mm.dd.yyyy", - leapday: "02.29.", - separator: ".", - alias: "mm/dd/yyyy" - }, - "mm-dd-yyyy": { - mask: "1-2-y", - placeholder: "mm-dd-yyyy", - leapday: "02-29-", - separator: "-", - alias: "mm/dd/yyyy" - }, - "yyyy.mm.dd": { - mask: "y.1.2", - placeholder: "yyyy.mm.dd", - leapday: ".02.29", - separator: ".", - alias: "yyyy/mm/dd" - }, - "yyyy-mm-dd": { - mask: "y-1-2", - placeholder: "yyyy-mm-dd", - leapday: "-02-29", - separator: "-", - alias: "yyyy/mm/dd" - }, - datetime: { - mask: "1/2/y h:s", - placeholder: "dd/mm/yyyy hh:mm", - alias: "dd/mm/yyyy", - regex: { - hrspre: new RegExp("[012]"), - hrs24: new RegExp("2[0-4]|1[3-9]"), - hrs: new RegExp("[01][0-9]|2[0-4]"), - ampm: new RegExp("^[a|p|A|P][m|M]"), - mspre: new RegExp("[0-5]"), - ms: new RegExp("[0-5][0-9]") - }, - timeseparator: ":", - hourFormat: "24", - definitions: { - h: { - validator: function(chrs, maskset, pos, strict, opts) { - if ("24" === opts.hourFormat && 24 === parseInt(chrs, 10)) return maskset.buffer[pos - 1] = "0", - maskset.buffer[pos] = "0", { - refreshFromBuffer: { - start: pos - 1, - end: pos - }, - c: "0" - }; - var isValid = opts.regex.hrs.test(chrs); - if (!strict && !isValid && (chrs.charAt(1) === opts.timeseparator || -1 !== "-.:".indexOf(chrs.charAt(1))) && (isValid = opts.regex.hrs.test("0" + chrs.charAt(0)))) return maskset.buffer[pos - 1] = "0", - maskset.buffer[pos] = chrs.charAt(0), pos++, { - refreshFromBuffer: { - start: pos - 2, - end: pos - }, - pos: pos, - c: opts.timeseparator - }; - if (isValid && "24" !== opts.hourFormat && opts.regex.hrs24.test(chrs)) { - var tmp = parseInt(chrs, 10); - return 24 === tmp ? (maskset.buffer[pos + 5] = "a", maskset.buffer[pos + 6] = "m") : (maskset.buffer[pos + 5] = "p", - maskset.buffer[pos + 6] = "m"), tmp -= 12, 10 > tmp ? (maskset.buffer[pos] = tmp.toString(), - maskset.buffer[pos - 1] = "0") : (maskset.buffer[pos] = tmp.toString().charAt(1), - maskset.buffer[pos - 1] = tmp.toString().charAt(0)), { - refreshFromBuffer: { - start: pos - 1, - end: pos + 6 - }, - c: maskset.buffer[pos] - }; - } - return isValid; - }, - cardinality: 2, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.regex.hrspre.test(chrs); - return strict || isValid || !(isValid = opts.regex.hrs.test("0" + chrs)) ? isValid : (maskset.buffer[pos] = "0", - pos++, { - pos: pos - }); - }, - cardinality: 1 - } ] - }, - s: { - validator: "[0-5][0-9]", - cardinality: 2, - prevalidator: [ { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.regex.mspre.test(chrs); - return strict || isValid || !(isValid = opts.regex.ms.test("0" + chrs)) ? isValid : (maskset.buffer[pos] = "0", - pos++, { - pos: pos - }); - }, - cardinality: 1 - } ] - }, - t: { - validator: function(chrs, maskset, pos, strict, opts) { - return opts.regex.ampm.test(chrs + "m"); - }, - casing: "lower", - cardinality: 1 - } - }, - insertMode: !1, - autoUnmask: !1 - }, - datetime12: { - mask: "1/2/y h:s t\\m", - placeholder: "dd/mm/yyyy hh:mm xm", - alias: "datetime", - hourFormat: "12" - }, - "mm/dd/yyyy hh:mm xm": { - mask: "1/2/y h:s t\\m", - placeholder: "mm/dd/yyyy hh:mm xm", - alias: "datetime12", - regex: { - val2pre: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[13-9]|1[012])" + escapedSeparator + "[0-3])|(02" + escapedSeparator + "[0-2])"); - }, - val2: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "(0[1-9]|[12][0-9]))|((0[13-9]|1[012])" + escapedSeparator + "30)|((0[13578]|1[02])" + escapedSeparator + "31)"); - }, - val1pre: new RegExp("[01]"), - val1: new RegExp("0[1-9]|1[012]") - }, - leapday: "02/29/", - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) { - var today = new Date(); - $input.val((today.getMonth() + 1).toString() + today.getDate().toString() + today.getFullYear().toString()), - $input.trigger("setvalue"); - } - } - }, - "hh:mm t": { - mask: "h:s t\\m", - placeholder: "hh:mm xm", - alias: "datetime", - hourFormat: "12" - }, - "h:s t": { - mask: "h:s t\\m", - placeholder: "hh:mm xm", - alias: "datetime", - hourFormat: "12" - }, - "hh:mm:ss": { - mask: "h:s:s", - placeholder: "hh:mm:ss", - alias: "datetime", - autoUnmask: !1 - }, - "hh:mm": { - mask: "h:s", - placeholder: "hh:mm", - alias: "datetime", - autoUnmask: !1 - }, - date: { - alias: "dd/mm/yyyy" - }, - "mm/yyyy": { - mask: "1/y", - placeholder: "mm/yyyy", - leapday: "donotuse", - separator: "/", - alias: "mm/dd/yyyy" - }, - shamsi: { - regex: { - val2pre: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "[0-3])"); - }, - val2: function(separator) { - var escapedSeparator = Inputmask.escapeRegex.call(this, separator); - return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "(0[1-9]|[12][0-9]))|((0[1-9]|1[012])" + escapedSeparator + "30)|((0[1-6])" + escapedSeparator + "31)"); - }, - val1pre: new RegExp("[01]"), - val1: new RegExp("0[1-9]|1[012]") - }, - yearrange: { - minyear: 1300, - maxyear: 1499 - }, - mask: "y/1/2", - leapday: "/12/30", - placeholder: "yyyy/mm/dd", - alias: "mm/dd/yyyy", - clearIncomplete: !0 - } - }), Inputmask; -}(jQuery, Inputmask), function($, Inputmask) { - return Inputmask.extendDefinitions({ - A: { - validator: "[A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]", - cardinality: 1, - casing: "upper" - }, - "&": { - validator: "[0-9A-Za-z\u0410-\u044f\u0401\u0451\xc0-\xff\xb5]", - cardinality: 1, - casing: "upper" - }, - "#": { - validator: "[0-9A-Fa-f]", - cardinality: 1, - casing: "upper" - } - }), Inputmask.extendAliases({ - url: { - definitions: { - i: { - validator: ".", - cardinality: 1 - } - }, - mask: "(\\http://)|(\\http\\s://)|(ftp://)|(ftp\\s://)i{+}", - insertMode: !1, - autoUnmask: !1 - }, - ip: { - mask: "i[i[i]].i[i[i]].i[i[i]].i[i[i]]", - definitions: { - i: { - validator: function(chrs, maskset, pos, strict, opts) { - return pos - 1 > -1 && "." !== maskset.buffer[pos - 1] ? (chrs = maskset.buffer[pos - 1] + chrs, - chrs = pos - 2 > -1 && "." !== maskset.buffer[pos - 2] ? maskset.buffer[pos - 2] + chrs : "0" + chrs) : chrs = "00" + chrs, - new RegExp("25[0-5]|2[0-4][0-9]|[01][0-9][0-9]").test(chrs); - }, - cardinality: 1 - } - }, - onUnMask: function(maskedValue, unmaskedValue, opts) { - return maskedValue; - } - }, - email: { - mask: "*{1,64}[.*{1,64}][.*{1,64}][.*{1,63}]@-{1,63}.-{1,63}[.-{1,63}][.-{1,63}]", - greedy: !1, - onBeforePaste: function(pastedValue, opts) { - return pastedValue = pastedValue.toLowerCase(), pastedValue.replace("mailto:", ""); - }, - definitions: { - "*": { - validator: "[0-9A-Za-z!#$%&'*+/=?^_`{|}~-]", - cardinality: 1, - casing: "lower" - }, - "-": { - validator: "[0-9A-Za-z-]", - cardinality: 1, - casing: "lower" - } - }, - onUnMask: function(maskedValue, unmaskedValue, opts) { - return maskedValue; - } - }, - mac: { - mask: "##:##:##:##:##:##" - }, - vin: { - mask: "V{13}9{4}", - definitions: { - V: { - validator: "[A-HJ-NPR-Za-hj-npr-z\\d]", - cardinality: 1, - casing: "upper" - } - }, - clearIncomplete: !0, - autoUnmask: !0 - } - }), Inputmask; -}(jQuery, Inputmask), function($, Inputmask) { - return Inputmask.extendAliases({ - numeric: { - mask: function(opts) { - function autoEscape(txt) { - for (var escapedTxt = "", i = 0; i < txt.length; i++) escapedTxt += opts.definitions[txt.charAt(i)] || opts.optionalmarker.start === txt.charAt(i) || opts.optionalmarker.end === txt.charAt(i) || opts.quantifiermarker.start === txt.charAt(i) || opts.quantifiermarker.end === txt.charAt(i) || opts.groupmarker.start === txt.charAt(i) || opts.groupmarker.end === txt.charAt(i) || opts.alternatormarker === txt.charAt(i) ? "\\" + txt.charAt(i) : txt.charAt(i); - return escapedTxt; - } - if (0 !== opts.repeat && isNaN(opts.integerDigits) && (opts.integerDigits = opts.repeat), - opts.repeat = 0, opts.groupSeparator === opts.radixPoint && ("." === opts.radixPoint ? opts.groupSeparator = "," : "," === opts.radixPoint ? opts.groupSeparator = "." : opts.groupSeparator = ""), - " " === opts.groupSeparator && (opts.skipOptionalPartCharacter = void 0), opts.autoGroup = opts.autoGroup && "" !== opts.groupSeparator, - opts.autoGroup && ("string" == typeof opts.groupSize && isFinite(opts.groupSize) && (opts.groupSize = parseInt(opts.groupSize)), - isFinite(opts.integerDigits))) { - var seps = Math.floor(opts.integerDigits / opts.groupSize), mod = opts.integerDigits % opts.groupSize; - opts.integerDigits = parseInt(opts.integerDigits) + (0 === mod ? seps - 1 : seps), - opts.integerDigits < 1 && (opts.integerDigits = "*"); - } - opts.placeholder.length > 1 && (opts.placeholder = opts.placeholder.charAt(0)), - opts.radixFocus = opts.radixFocus && "" !== opts.placeholder && opts.integerOptional === !0, - opts.definitions[";"] = opts.definitions["~"], opts.definitions[";"].definitionSymbol = "~", - opts.numericInput === !0 && (opts.radixFocus = !1, opts.digitsOptional = !1, isNaN(opts.digits) && (opts.digits = 2), - opts.decimalProtect = !1); - var mask = autoEscape(opts.prefix); - return mask += "[+]", mask += opts.integerOptional === !0 ? "~{1," + opts.integerDigits + "}" : "~{" + opts.integerDigits + "}", - void 0 !== opts.digits && (isNaN(opts.digits) || parseInt(opts.digits) > 0) && (opts.decimalProtect && (opts.radixPointDefinitionSymbol = ":"), - mask += opts.digitsOptional ? "[" + (opts.decimalProtect ? ":" : opts.radixPoint) + ";{1," + opts.digits + "}]" : (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}"), - mask += "[-]", mask += autoEscape(opts.suffix), opts.greedy = !1, null !== opts.min && (opts.min = opts.min.toString().replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - "," === opts.radixPoint && (opts.min = opts.min.replace(opts.radixPoint, "."))), - null !== opts.max && (opts.max = opts.max.toString().replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - "," === opts.radixPoint && (opts.max = opts.max.replace(opts.radixPoint, "."))), - mask; - }, - placeholder: "", - greedy: !1, - digits: "*", - digitsOptional: !0, - radixPoint: ".", - radixFocus: !0, - groupSize: 3, - groupSeparator: "", - autoGroup: !1, - allowPlus: !0, - allowMinus: !0, - negationSymbol: { - front: "-", - back: "" - }, - integerDigits: "+", - integerOptional: !0, - prefix: "", - suffix: "", - rightAlign: !0, - decimalProtect: !0, - min: null, - max: null, - step: 1, - insertMode: !0, - autoUnmask: !1, - unmaskAsNumber: !1, - postFormat: function(buffer, pos, opts) { - opts.numericInput === !0 && (buffer = buffer.reverse(), isFinite(pos) && (pos = buffer.join("").length - pos - 1)); - var i, l, suffixStripped = !1; - buffer.length >= opts.suffix.length && buffer.join("").indexOf(opts.suffix) === buffer.length - opts.suffix.length && (buffer.length = buffer.length - opts.suffix.length, - suffixStripped = !0), pos = pos >= buffer.length ? buffer.length - 1 : pos < opts.prefix.length ? opts.prefix.length : pos; - var needsRefresh = !1, charAtPos = buffer[pos], cbuf = buffer.slice(); - charAtPos === opts.groupSeparator && (cbuf.splice(pos--, 1), charAtPos = cbuf[pos]), - charAtPos !== opts.radixPoint && charAtPos !== opts.negationSymbol.front && charAtPos !== opts.negationSymbol.back && (cbuf[pos] = "?"); - var bufVal = cbuf.join(""), bufValOrigin = bufVal; - if (bufVal.length > 0 && opts.autoGroup || -1 !== bufVal.indexOf(opts.groupSeparator)) { - var escapedGroupSeparator = Inputmask.escapeRegex(opts.groupSeparator); - needsRefresh = 0 === bufVal.indexOf(opts.groupSeparator), bufVal = bufVal.replace(new RegExp(escapedGroupSeparator, "g"), ""); - var radixSplit = bufVal.split(opts.radixPoint); - if (bufVal = "" === opts.radixPoint ? bufVal : radixSplit[0], bufVal !== opts.prefix + "?0" && bufVal.length >= opts.groupSize + opts.prefix.length) for (var reg = new RegExp("([-+]?[\\d?]+)([\\d?]{" + opts.groupSize + "})"); reg.test(bufVal) && "" !== opts.groupSeparator; ) bufVal = bufVal.replace(reg, "$1" + opts.groupSeparator + "$2"), - bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator); - "" !== opts.radixPoint && radixSplit.length > 1 && (bufVal += opts.radixPoint + radixSplit[1]); - } - for (needsRefresh = bufValOrigin !== bufVal, buffer.length = bufVal.length, i = 0, - l = bufVal.length; l > i; i++) buffer[i] = bufVal.charAt(i); - var newPos = $.inArray("?", buffer); - if (-1 === newPos && (newPos = $.inArray(charAtPos, buffer)), buffer[newPos] = charAtPos, - !needsRefresh && suffixStripped) for (i = 0, l = opts.suffix.length; l > i; i++) buffer.push(opts.suffix.charAt(i)); - return newPos = opts.numericInput && isFinite(pos) ? buffer.join("").length - newPos - 1 : newPos, - opts.numericInput && (buffer = buffer.reverse(), $.inArray(opts.radixPoint, buffer) < newPos && buffer.join("").length - opts.suffix.length !== newPos && (newPos -= 1)), - { - pos: newPos, - refreshFromBuffer: needsRefresh, - buffer: buffer - }; - }, - onBeforeWrite: function(e, buffer, caretPos, opts) { - var rslt; - if (e && ("blur" === e.type || "checkval" === e.type || "keydown" === e.type)) { - var maskedValue = opts.numericInput ? buffer.slice().reverse().join("") : buffer.join(""), processValue = maskedValue.replace(opts.prefix, ""); - processValue = processValue.replace(opts.suffix, ""), processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - "," === opts.radixPoint && (processValue = processValue.replace(opts.radixPoint, ".")); - var isNegative = processValue.match(new RegExp("[-" + Inputmask.escapeRegex(opts.negationSymbol.front) + "]", "g")); - if (isNegative = null !== isNegative && 1 === isNegative.length, processValue = processValue.replace(new RegExp("[-" + Inputmask.escapeRegex(opts.negationSymbol.front) + "]", "g"), ""), - processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.negationSymbol.back) + "$"), ""), - isNaN(opts.placeholder) && (processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.placeholder), "g"), "")), - processValue = processValue === opts.negationSymbol.front ? processValue + "0" : processValue, - "" !== processValue && isFinite(processValue)) { - var floatValue = parseFloat(processValue), signedFloatValue = isNegative ? -1 * floatValue : floatValue; - if (null !== opts.min && isFinite(opts.min) && signedFloatValue < parseFloat(opts.min) ? (floatValue = Math.abs(opts.min), - isNegative = opts.min < 0, maskedValue = void 0) : null !== opts.max && isFinite(opts.max) && signedFloatValue > parseFloat(opts.max) && (floatValue = Math.abs(opts.max), - isNegative = opts.max < 0, maskedValue = void 0), processValue = floatValue.toString().replace(".", opts.radixPoint).split(""), - isFinite(opts.digits)) { - var radixPosition = $.inArray(opts.radixPoint, processValue), rpb = $.inArray(opts.radixPoint, maskedValue); - -1 === radixPosition && (processValue.push(opts.radixPoint), radixPosition = processValue.length - 1); - for (var i = 1; i <= opts.digits; i++) opts.digitsOptional || void 0 !== processValue[radixPosition + i] && processValue[radixPosition + i] !== opts.placeholder.charAt(0) ? -1 !== rpb && void 0 !== maskedValue[rpb + i] && (processValue[radixPosition + i] = processValue[radixPosition + i] || maskedValue[rpb + i]) : processValue[radixPosition + i] = "0"; - processValue[processValue.length - 1] === opts.radixPoint && delete processValue[processValue.length - 1]; - } - if (floatValue.toString() !== processValue && floatValue.toString() + "." !== processValue || isNegative) return !isNegative || 0 === floatValue && "blur" === e.type || (processValue.unshift(opts.negationSymbol.front), - processValue.push(opts.negationSymbol.back)), processValue = (opts.prefix + processValue.join("")).split(""), - opts.numericInput && (processValue = processValue.reverse()), rslt = opts.postFormat(processValue, opts.numericInput ? caretPos : caretPos - 1, opts), - rslt.buffer && (rslt.refreshFromBuffer = rslt.buffer.join("") !== buffer.join("")), - rslt; - } - } - return opts.autoGroup ? (rslt = opts.postFormat(buffer, opts.numericInput ? caretPos : caretPos - 1, opts), - rslt.caret = caretPos <= opts.prefix.length ? rslt.pos : rslt.pos + 1, rslt) : void 0; - }, - regex: { - integerPart: function(opts) { - return new RegExp("[" + Inputmask.escapeRegex(opts.negationSymbol.front) + "+]?\\d+"); - }, - integerNPart: function(opts) { - return new RegExp("[\\d" + Inputmask.escapeRegex(opts.groupSeparator) + Inputmask.escapeRegex(opts.placeholder.charAt(0)) + "]+"); - } - }, - signHandler: function(chrs, maskset, pos, strict, opts) { - if (!strict && opts.allowMinus && "-" === chrs || opts.allowPlus && "+" === chrs) { - var matchRslt = maskset.buffer.join("").match(opts.regex.integerPart(opts)); - if (matchRslt && matchRslt[0].length > 0) return maskset.buffer[matchRslt.index] === ("-" === chrs ? "+" : opts.negationSymbol.front) ? "-" === chrs ? "" !== opts.negationSymbol.back ? { - pos: matchRslt.index, - c: opts.negationSymbol.front, - remove: matchRslt.index, - caret: pos, - insert: { - pos: maskset.buffer.length - opts.suffix.length - 1, - c: opts.negationSymbol.back - } - } : { - pos: matchRslt.index, - c: opts.negationSymbol.front, - remove: matchRslt.index, - caret: pos - } : "" !== opts.negationSymbol.back ? { - pos: matchRslt.index, - c: "+", - remove: [ matchRslt.index, maskset.buffer.length - opts.suffix.length - 1 ], - caret: pos - } : { - pos: matchRslt.index, - c: "+", - remove: matchRslt.index, - caret: pos - } : maskset.buffer[matchRslt.index] === ("-" === chrs ? opts.negationSymbol.front : "+") ? "-" === chrs && "" !== opts.negationSymbol.back ? { - remove: [ matchRslt.index, maskset.buffer.length - opts.suffix.length - 1 ], - caret: pos - 1 - } : { - remove: matchRslt.index, - caret: pos - 1 - } : "-" === chrs ? "" !== opts.negationSymbol.back ? { - pos: matchRslt.index, - c: opts.negationSymbol.front, - caret: pos + 1, - insert: { - pos: maskset.buffer.length - opts.suffix.length, - c: opts.negationSymbol.back - } - } : { - pos: matchRslt.index, - c: opts.negationSymbol.front, - caret: pos + 1 - } : { - pos: matchRslt.index, - c: chrs, - caret: pos + 1 - }; - } - return !1; - }, - radixHandler: function(chrs, maskset, pos, strict, opts) { - if (!strict && opts.numericInput !== !0 && chrs === opts.radixPoint && void 0 !== opts.digits && (isNaN(opts.digits) || parseInt(opts.digits) > 0)) { - var radixPos = $.inArray(opts.radixPoint, maskset.buffer), integerValue = maskset.buffer.join("").match(opts.regex.integerPart(opts)); - if (-1 !== radixPos && maskset.validPositions[radixPos]) return maskset.validPositions[radixPos - 1] ? { - caret: radixPos + 1 - } : { - pos: integerValue.index, - c: integerValue[0], - caret: radixPos + 1 - }; - if (!integerValue || "0" === integerValue[0] && integerValue.index + 1 !== pos) return maskset.buffer[integerValue ? integerValue.index : pos] = "0", - { - pos: (integerValue ? integerValue.index : pos) + 1, - c: opts.radixPoint - }; - } - return !1; - }, - leadingZeroHandler: function(chrs, maskset, pos, strict, opts, isSelection) { - if (!strict) if (opts.numericInput === !0) { - var buffer = maskset.buffer.slice("").reverse(), char = buffer[opts.prefix.length]; - if ("0" === char && void 0 === maskset.validPositions[pos - 1]) return { - pos: pos, - remove: buffer.length - opts.prefix.length - 1 - }; - } else { - var radixPosition = $.inArray(opts.radixPoint, maskset.buffer), matchRslt = maskset.buffer.slice(0, -1 !== radixPosition ? radixPosition : void 0).join("").match(opts.regex.integerNPart(opts)); - if (matchRslt && (-1 === radixPosition || radixPosition >= pos)) { - var decimalPart = -1 === radixPosition ? 0 : parseInt(maskset.buffer.slice(radixPosition + 1).join("")); - if (0 === matchRslt[0].indexOf("" !== opts.placeholder ? opts.placeholder.charAt(0) : "0") && (matchRslt.index + 1 === pos || isSelection !== !0 && 0 === decimalPart)) return maskset.buffer.splice(matchRslt.index, 1), - { - pos: matchRslt.index, - remove: matchRslt.index - }; - if ("0" === chrs && pos <= matchRslt.index && matchRslt[0] !== opts.groupSeparator) return !1; - } - } - return !0; - }, - definitions: { - "~": { - validator: function(chrs, maskset, pos, strict, opts, isSelection) { - var isValid = opts.signHandler(chrs, maskset, pos, strict, opts); - if (!isValid && (isValid = opts.radixHandler(chrs, maskset, pos, strict, opts), - !isValid && (isValid = strict ? new RegExp("[0-9" + Inputmask.escapeRegex(opts.groupSeparator) + "]").test(chrs) : new RegExp("[0-9]").test(chrs), - isValid === !0 && (isValid = opts.leadingZeroHandler(chrs, maskset, pos, strict, opts, isSelection), - isValid === !0)))) { - var radixPosition = $.inArray(opts.radixPoint, maskset.buffer); - isValid = -1 !== radixPosition && (opts.digitsOptional === !1 || maskset.validPositions[pos]) && opts.numericInput !== !0 && pos > radixPosition && !strict ? { - pos: pos, - remove: pos - } : { - pos: pos - }; - } - return isValid; - }, - cardinality: 1 - }, - "+": { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.signHandler(chrs, maskset, pos, strict, opts); - return !isValid && (strict && opts.allowMinus && chrs === opts.negationSymbol.front || opts.allowMinus && "-" === chrs || opts.allowPlus && "+" === chrs) && (isValid = strict || "-" !== chrs ? !0 : "" !== opts.negationSymbol.back ? { - pos: pos, - c: "-" === chrs ? opts.negationSymbol.front : "+", - caret: pos + 1, - insert: { - pos: maskset.buffer.length, - c: opts.negationSymbol.back - } - } : { - pos: pos, - c: "-" === chrs ? opts.negationSymbol.front : "+", - caret: pos + 1 - }), isValid; - }, - cardinality: 1, - placeholder: "" - }, - "-": { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.signHandler(chrs, maskset, pos, strict, opts); - return !isValid && strict && opts.allowMinus && chrs === opts.negationSymbol.back && (isValid = !0), - isValid; - }, - cardinality: 1, - placeholder: "" - }, - ":": { - validator: function(chrs, maskset, pos, strict, opts) { - var isValid = opts.signHandler(chrs, maskset, pos, strict, opts); - if (!isValid) { - var radix = "[" + Inputmask.escapeRegex(opts.radixPoint) + "]"; - isValid = new RegExp(radix).test(chrs), isValid && maskset.validPositions[pos] && maskset.validPositions[pos].match.placeholder === opts.radixPoint && (isValid = { - caret: pos + 1 - }); - } - return isValid ? { - c: opts.radixPoint - } : isValid; - }, - cardinality: 1, - placeholder: function(opts) { - return opts.radixPoint; - } - } - }, - onUnMask: function(maskedValue, unmaskedValue, opts) { - var processValue = maskedValue.replace(opts.prefix, ""); - return processValue = processValue.replace(opts.suffix, ""), processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - opts.unmaskAsNumber ? ("" !== opts.radixPoint && -1 !== processValue.indexOf(opts.radixPoint) && (processValue = processValue.replace(Inputmask.escapeRegex.call(this, opts.radixPoint), ".")), - Number(processValue)) : processValue; - }, - isComplete: function(buffer, opts) { - var maskedValue = buffer.join(""), bufClone = buffer.slice(); - if (opts.postFormat(bufClone, 0, opts), bufClone.join("") !== maskedValue) return !1; - var processValue = maskedValue.replace(opts.prefix, ""); - return processValue = processValue.replace(opts.suffix, ""), processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""), - "," === opts.radixPoint && (processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".")), - isFinite(processValue); - }, - onBeforeMask: function(initialValue, opts) { - if ("" !== opts.radixPoint && isFinite(initialValue)) initialValue = initialValue.toString().replace(".", opts.radixPoint); else { - var kommaMatches = initialValue.match(/,/g), dotMatches = initialValue.match(/\./g); - dotMatches && kommaMatches ? dotMatches.length > kommaMatches.length ? (initialValue = initialValue.replace(/\./g, ""), - initialValue = initialValue.replace(",", opts.radixPoint)) : kommaMatches.length > dotMatches.length ? (initialValue = initialValue.replace(/,/g, ""), - initialValue = initialValue.replace(".", opts.radixPoint)) : initialValue = initialValue.indexOf(".") < initialValue.indexOf(",") ? initialValue.replace(/\./g, "") : initialValue = initialValue.replace(/,/g, "") : initialValue = initialValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""); - } - if (0 === opts.digits && (-1 !== initialValue.indexOf(".") ? initialValue = initialValue.substring(0, initialValue.indexOf(".")) : -1 !== initialValue.indexOf(",") && (initialValue = initialValue.substring(0, initialValue.indexOf(",")))), - "" !== opts.radixPoint && isFinite(opts.digits) && -1 !== initialValue.indexOf(opts.radixPoint)) { - var valueParts = initialValue.split(opts.radixPoint), decPart = valueParts[1].match(new RegExp("\\d*"))[0]; - if (parseInt(opts.digits) < decPart.toString().length) { - var digitsFactor = Math.pow(10, parseInt(opts.digits)); - initialValue = initialValue.replace(Inputmask.escapeRegex(opts.radixPoint), "."), - initialValue = Math.round(parseFloat(initialValue) * digitsFactor) / digitsFactor, - initialValue = initialValue.toString().replace(".", opts.radixPoint); - } - } - return initialValue.toString(); - }, - canClearPosition: function(maskset, position, lvp, strict, opts) { - var positionInput = maskset.validPositions[position].input, canClear = positionInput !== opts.radixPoint || null !== maskset.validPositions[position].match.fn && opts.decimalProtect === !1 || isFinite(positionInput) || position === lvp || positionInput === opts.groupSeparator || positionInput === opts.negationSymbol.front || positionInput === opts.negationSymbol.back; - return canClear; - }, - onKeyDown: function(e, buffer, caretPos, opts) { - var $input = $(this); - if (e.ctrlKey) switch (e.keyCode) { - case Inputmask.keyCode.UP: - $input.val(parseFloat(this.inputmask.unmaskedvalue()) + parseInt(opts.step)), $input.trigger("setvalue"); - break; - - case Inputmask.keyCode.DOWN: - $input.val(parseFloat(this.inputmask.unmaskedvalue()) - parseInt(opts.step)), $input.trigger("setvalue"); - } - } - }, - currency: { - prefix: "$ ", - groupSeparator: ",", - alias: "numeric", - placeholder: "0", - autoGroup: !0, - digits: 2, - digitsOptional: !1, - clearMaskOnLostFocus: !1 - }, - decimal: { - alias: "numeric" - }, - integer: { - alias: "numeric", - digits: 0, - radixPoint: "" - }, - percentage: { - alias: "numeric", - digits: 2, - radixPoint: ".", - placeholder: "0", - autoGroup: !1, - min: 0, - max: 100, - suffix: " %", - allowPlus: !1, - allowMinus: !1 - } - }), Inputmask; -}(jQuery, Inputmask), function($, Inputmask) { - return Inputmask.extendAliases({ - phone: { - url: "phone-codes/phone-codes.js", - countrycode: "", - phoneCodeCache: {}, - mask: function(opts) { - if (void 0 === opts.phoneCodeCache[opts.url]) { - var maskList = []; - opts.definitions["#"] = opts.definitions[9], $.ajax({ - url: opts.url, - async: !1, - type: "get", - dataType: "json", - success: function(response) { - maskList = response; - }, - error: function(xhr, ajaxOptions, thrownError) { - alert(thrownError + " - " + opts.url); - } - }), opts.phoneCodeCache[opts.url] = maskList.sort(function(a, b) { - return (a.mask || a) < (b.mask || b) ? -1 : 1; - }); - } - return opts.phoneCodeCache[opts.url]; - }, - keepStatic: !1, - nojumps: !0, - nojumpsThreshold: 1, - onBeforeMask: function(value, opts) { - var processedValue = value.replace(/^0{1,2}/, "").replace(/[\s]/g, ""); - return (processedValue.indexOf(opts.countrycode) > 1 || -1 === processedValue.indexOf(opts.countrycode)) && (processedValue = "+" + opts.countrycode + processedValue), - processedValue; - } - }, - phonebe: { - alias: "phone", - url: "phone-codes/phone-be.js", - countrycode: "32", - nojumpsThreshold: 4 - } - }), Inputmask; -}(jQuery, Inputmask), function($, Inputmask) { - return Inputmask.extendAliases({ - Regex: { - mask: "r", - greedy: !1, - repeat: "*", - regex: null, - regexTokens: null, - tokenizer: /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g, - quantifierFilter: /[0-9]+[^,]/, - isComplete: function(buffer, opts) { - return new RegExp(opts.regex).test(buffer.join("")); - }, - definitions: { - r: { - validator: function(chrs, maskset, pos, strict, opts) { - function RegexToken(isGroup, isQuantifier) { - this.matches = [], this.isGroup = isGroup || !1, this.isQuantifier = isQuantifier || !1, - this.quantifier = { - min: 1, - max: 1 - }, this.repeaterPart = void 0; - } - function analyseRegex() { - var match, m, currentToken = new RegexToken(), opengroups = []; - for (opts.regexTokens = []; match = opts.tokenizer.exec(opts.regex); ) switch (m = match[0], - m.charAt(0)) { - case "(": - opengroups.push(new RegexToken(!0)); - break; - - case ")": - groupToken = opengroups.pop(), opengroups.length > 0 ? opengroups[opengroups.length - 1].matches.push(groupToken) : currentToken.matches.push(groupToken); - break; - - case "{": - case "+": - case "*": - var quantifierToken = new RegexToken(!1, !0); - m = m.replace(/[{}]/g, ""); - var mq = m.split(","), mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), mq1 = 1 === mq.length ? mq0 : isNaN(mq[1]) ? mq[1] : parseInt(mq[1]); - if (quantifierToken.quantifier = { - min: mq0, - max: mq1 - }, opengroups.length > 0) { - var matches = opengroups[opengroups.length - 1].matches; - match = matches.pop(), match.isGroup || (groupToken = new RegexToken(!0), groupToken.matches.push(match), - match = groupToken), matches.push(match), matches.push(quantifierToken); - } else match = currentToken.matches.pop(), match.isGroup || (groupToken = new RegexToken(!0), - groupToken.matches.push(match), match = groupToken), currentToken.matches.push(match), - currentToken.matches.push(quantifierToken); - break; - - default: - opengroups.length > 0 ? opengroups[opengroups.length - 1].matches.push(m) : currentToken.matches.push(m); - } - currentToken.matches.length > 0 && opts.regexTokens.push(currentToken); - } - function validateRegexToken(token, fromGroup) { - var isvalid = !1; - fromGroup && (regexPart += "(", openGroupCount++); - for (var mndx = 0; mndx < token.matches.length; mndx++) { - var matchToken = token.matches[mndx]; - if (matchToken.isGroup === !0) isvalid = validateRegexToken(matchToken, !0); else if (matchToken.isQuantifier === !0) { - var crrntndx = $.inArray(matchToken, token.matches), matchGroup = token.matches[crrntndx - 1], regexPartBak = regexPart; - if (isNaN(matchToken.quantifier.max)) { - for (;matchToken.repeaterPart && matchToken.repeaterPart !== regexPart && matchToken.repeaterPart.length > regexPart.length && !(isvalid = validateRegexToken(matchGroup, !0)); ) ; - isvalid = isvalid || validateRegexToken(matchGroup, !0), isvalid && (matchToken.repeaterPart = regexPart), - regexPart = regexPartBak + matchToken.quantifier.max; - } else { - for (var i = 0, qm = matchToken.quantifier.max - 1; qm > i && !(isvalid = validateRegexToken(matchGroup, !0)); i++) ; - regexPart = regexPartBak + "{" + matchToken.quantifier.min + "," + matchToken.quantifier.max + "}"; - } - } else if (void 0 !== matchToken.matches) for (var k = 0; k < matchToken.length && !(isvalid = validateRegexToken(matchToken[k], fromGroup)); k++) ; else { - var testExp; - if ("[" == matchToken.charAt(0)) { - testExp = regexPart, testExp += matchToken; - for (var j = 0; openGroupCount > j; j++) testExp += ")"; - var exp = new RegExp("^(" + testExp + ")$"); - isvalid = exp.test(bufferStr); - } else for (var l = 0, tl = matchToken.length; tl > l; l++) if ("\\" !== matchToken.charAt(l)) { - testExp = regexPart, testExp += matchToken.substr(0, l + 1), testExp = testExp.replace(/\|$/, ""); - for (var j = 0; openGroupCount > j; j++) testExp += ")"; - var exp = new RegExp("^(" + testExp + ")$"); - if (isvalid = exp.test(bufferStr)) break; - } - regexPart += matchToken; - } - if (isvalid) break; - } - return fromGroup && (regexPart += ")", openGroupCount--), isvalid; - } - var bufferStr, groupToken, cbuffer = maskset.buffer.slice(), regexPart = "", isValid = !1, openGroupCount = 0; - null === opts.regexTokens && analyseRegex(), cbuffer.splice(pos, 0, chrs), bufferStr = cbuffer.join(""); - for (var i = 0; i < opts.regexTokens.length; i++) { - var regexToken = opts.regexTokens[i]; - if (isValid = validateRegexToken(regexToken, regexToken.isGroup)) break; - } - return isValid; - }, - cardinality: 1 - } - } - } - }), Inputmask; -}(jQuery, Inputmask); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-knob/jquery.knob.min.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-knob/jquery.knob.min.js deleted file mode 100644 index 72d6ed2de..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-knob/jquery.knob.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(e){if(typeof define==="function"&&define.amd){define(["jquery"],e)}else{e(jQuery)}})(function(e){"use strict";var t={},n=Math.max,r=Math.min;t.c={};t.c.d=e(document);t.c.t=function(e){return e.originalEvent.touches.length-1};t.o=function(){var n=this;this.o=null;this.$=null;this.i=null;this.g=null;this.v=null;this.cv=null;this.x=0;this.y=0;this.w=0;this.h=0;this.$c=null;this.c=null;this.t=0;this.isInit=false;this.fgColor=null;this.pColor=null;this.dH=null;this.cH=null;this.eH=null;this.rH=null;this.scale=1;this.relative=false;this.relativeWidth=false;this.relativeHeight=false;this.$div=null;this.run=function(){var t=function(e,t){var r;for(r in t){n.o[r]=t[r]}n._carve().init();n._configure()._draw()};if(this.$.data("kontroled"))return;this.$.data("kontroled",true);this.extend();this.o=e.extend({min:this.$.data("min")!==undefined?this.$.data("min"):0,max:this.$.data("max")!==undefined?this.$.data("max"):100,stopper:true,readOnly:this.$.data("readonly")||this.$.attr("readonly")==="readonly",cursor:this.$.data("cursor")===true&&30||this.$.data("cursor")||0,thickness:this.$.data("thickness")&&Math.max(Math.min(this.$.data("thickness"),1),.01)||.35,lineCap:this.$.data("linecap")||"butt",width:this.$.data("width")||200,height:this.$.data("height")||200,displayInput:this.$.data("displayinput")==null||this.$.data("displayinput"),displayPrevious:this.$.data("displayprevious"),fgColor:this.$.data("fgcolor")||"#87CEEB",inputColor:this.$.data("inputcolor"),font:this.$.data("font")||"Arial",fontWeight:this.$.data("font-weight")||"bold",inline:false,step:this.$.data("step")||1,rotation:this.$.data("rotation"),draw:null,change:null,cancel:null,release:null,format:function(e){return e},parse:function(e){return parseFloat(e)}},this.o);this.o.flip=this.o.rotation==="anticlockwise"||this.o.rotation==="acw";if(!this.o.inputColor){this.o.inputColor=this.o.fgColor}if(this.$.is("fieldset")){this.v={};this.i=this.$.find("input");this.i.each(function(t){var r=e(this);n.i[t]=r;n.v[t]=n.o.parse(r.val());r.bind("change blur",function(){var e={};e[t]=r.val();n.val(n._validate(e))})});this.$.find("legend").remove()}else{this.i=this.$;this.v=this.o.parse(this.$.val());this.v===""&&(this.v=this.o.min);this.$.bind("change blur",function(){n.val(n._validate(n.o.parse(n.$.val())))})}!this.o.displayInput&&this.$.hide();this.$c=e(document.createElement("canvas")).attr({width:this.o.width,height:this.o.height});this.$div=e('
    ');this.$.wrap(this.$div).before(this.$c);this.$div=this.$.parent();if(typeof G_vmlCanvasManager!=="undefined"){G_vmlCanvasManager.initElement(this.$c[0])}this.c=this.$c[0].getContext?this.$c[0].getContext("2d"):null;if(!this.c){throw{name:"CanvasNotSupportedException",message:"Canvas not supported. Please use excanvas on IE8.0.",toString:function(){return this.name+": "+this.message}}}this.scale=(window.devicePixelRatio||1)/(this.c.webkitBackingStorePixelRatio||this.c.mozBackingStorePixelRatio||this.c.msBackingStorePixelRatio||this.c.oBackingStorePixelRatio||this.c.backingStorePixelRatio||1);this.relativeWidth=this.o.width%1!==0&&this.o.width.indexOf("%");this.relativeHeight=this.o.height%1!==0&&this.o.height.indexOf("%");this.relative=this.relativeWidth||this.relativeHeight;this._carve();if(this.v instanceof Object){this.cv={};this.copy(this.v,this.cv)}else{this.cv=this.v}this.$.bind("configure",t).parent().bind("configure",t);this._listen()._configure()._xy().init();this.isInit=true;this.$.val(this.o.format(this.v));this._draw();return this};this._carve=function(){if(this.relative){var e=this.relativeWidth?this.$div.parent().width()*parseInt(this.o.width)/100:this.$div.parent().width(),t=this.relativeHeight?this.$div.parent().height()*parseInt(this.o.height)/100:this.$div.parent().height();this.w=this.h=Math.min(e,t)}else{this.w=this.o.width;this.h=this.o.height}this.$div.css({width:this.w+"px",height:this.h+"px"});this.$c.attr({width:this.w,height:this.h});if(this.scale!==1){this.$c[0].width=this.$c[0].width*this.scale;this.$c[0].height=this.$c[0].height*this.scale;this.$c.width(this.w);this.$c.height(this.h)}return this};this._draw=function(){var e=true;n.g=n.c;n.clear();n.dH&&(e=n.dH());e!==false&&n.draw()};this._touch=function(e){var r=function(e){var t=n.xy2val(e.originalEvent.touches[n.t].pageX,e.originalEvent.touches[n.t].pageY);if(t==n.cv)return;if(n.cH&&n.cH(t)===false)return;n.change(n._validate(t));n._draw()};this.t=t.c.t(e);r(e);t.c.d.bind("touchmove.k",r).bind("touchend.k",function(){t.c.d.unbind("touchmove.k touchend.k");n.val(n.cv)});return this};this._mouse=function(e){var r=function(e){var t=n.xy2val(e.pageX,e.pageY);if(t==n.cv)return;if(n.cH&&n.cH(t)===false)return;n.change(n._validate(t));n._draw()};r(e);t.c.d.bind("mousemove.k",r).bind("keyup.k",function(e){if(e.keyCode===27){t.c.d.unbind("mouseup.k mousemove.k keyup.k");if(n.eH&&n.eH()===false)return;n.cancel()}}).bind("mouseup.k",function(e){t.c.d.unbind("mousemove.k mouseup.k keyup.k");n.val(n.cv)});return this};this._xy=function(){var e=this.$c.offset();this.x=e.left;this.y=e.top;return this};this._listen=function(){if(!this.o.readOnly){this.$c.bind("mousedown",function(e){e.preventDefault();n._xy()._mouse(e)}).bind("touchstart",function(e){e.preventDefault();n._xy()._touch(e)});this.listen()}else{this.$.attr("readonly","readonly")}if(this.relative){e(window).resize(function(){n._carve().init();n._draw()})}return this};this._configure=function(){if(this.o.draw)this.dH=this.o.draw;if(this.o.change)this.cH=this.o.change;if(this.o.cancel)this.eH=this.o.cancel;if(this.o.release)this.rH=this.o.release;if(this.o.displayPrevious){this.pColor=this.h2rgba(this.o.fgColor,"0.4");this.fgColor=this.h2rgba(this.o.fgColor,"0.6")}else{this.fgColor=this.o.fgColor}return this};this._clear=function(){this.$c[0].width=this.$c[0].width};this._validate=function(e){var t=~~((e<0?-.5:.5)+e/this.o.step)*this.o.step;return Math.round(t*100)/100};this.listen=function(){};this.extend=function(){};this.init=function(){};this.change=function(e){};this.val=function(e){};this.xy2val=function(e,t){};this.draw=function(){};this.clear=function(){this._clear()};this.h2rgba=function(e,t){var n;e=e.substring(1,7);n=[parseInt(e.substring(0,2),16),parseInt(e.substring(2,4),16),parseInt(e.substring(4,6),16)];return"rgba("+n[0]+","+n[1]+","+n[2]+","+t+")"};this.copy=function(e,t){for(var n in e){t[n]=e[n]}}};t.Dial=function(){t.o.call(this);this.startAngle=null;this.xy=null;this.radius=null;this.lineWidth=null;this.cursorExt=null;this.w2=null;this.PI2=2*Math.PI;this.extend=function(){this.o=e.extend({bgColor:this.$.data("bgcolor")||"#EEEEEE",angleOffset:this.$.data("angleoffset")||0,angleArc:this.$.data("anglearc")||360,inline:true},this.o)};this.val=function(e,t){if(null!=e){e=this.o.parse(e);if(t!==false&&e!=this.v&&this.rH&&this.rH(e)===false){return}this.cv=this.o.stopper?n(r(e,this.o.max),this.o.min):e;this.v=this.cv;this.$.val(this.o.format(this.v));this._draw()}else{return this.v}};this.xy2val=function(e,t){var i,s;i=Math.atan2(e-(this.x+this.w2),-(t-this.y-this.w2))-this.angleOffset;if(this.o.flip){i=this.angleArc-i-this.PI2}if(this.angleArc!=this.PI2&&i<0&&i>-.5){i=0}else if(i<0){i+=this.PI2}s=i*(this.o.max-this.o.min)/this.angleArc+this.o.min;this.o.stopper&&(s=n(r(s,this.o.max),this.o.min));return s};this.listen=function(){var t=this,i,s,o=function(e){e.preventDefault();var o=e.originalEvent,u=o.detail||o.wheelDeltaX,a=o.detail||o.wheelDeltaY,f=t._validate(t.o.parse(t.$.val()))+(u>0||a>0?t.o.step:u<0||a<0?-t.o.step:0);f=n(r(f,t.o.max),t.o.min);t.val(f,false);if(t.rH){clearTimeout(i);i=setTimeout(function(){t.rH(f);i=null},100);if(!s){s=setTimeout(function(){if(i)t.rH(f);s=null},200)}}},u,a,f=1,l={37:-t.o.step,38:t.o.step,39:t.o.step,40:-t.o.step};this.$.bind("keydown",function(i){var s=i.keyCode;if(s>=96&&s<=105){s=i.keyCode=s-48}u=parseInt(String.fromCharCode(s));if(isNaN(u)){s!==13&&s!==8&&s!==9&&s!==189&&(s!==190||t.$.val().match(/\./))&&i.preventDefault();if(e.inArray(s,[37,38,39,40])>-1){i.preventDefault();var o=t.o.parse(t.$.val())+l[s]*f;t.o.stopper&&(o=n(r(o,t.o.max),t.o.min));t.change(t._validate(o));t._draw();a=window.setTimeout(function(){f*=2},30)}}}).bind("keyup",function(e){if(isNaN(u)){if(a){window.clearTimeout(a);a=null;f=1;t.val(t.$.val())}}else{t.$.val()>t.o.max&&t.$.val(t.o.max)||t.$.val()this.o.max){this.v=this.o.min}this.$.val(this.v);this.w2=this.w/2;this.cursorExt=this.o.cursor/100;this.xy=this.w2*this.scale;this.lineWidth=this.xy*this.o.thickness;this.lineCap=this.o.lineCap;this.radius=this.xy-this.lineWidth/2;this.o.angleOffset&&(this.o.angleOffset=isNaN(this.o.angleOffset)?0:this.o.angleOffset);this.o.angleArc&&(this.o.angleArc=isNaN(this.o.angleArc)?this.PI2:this.o.angleArc);this.angleOffset=this.o.angleOffset*Math.PI/180;this.angleArc=this.o.angleArc*Math.PI/180;this.startAngle=1.5*Math.PI+this.angleOffset;this.endAngle=1.5*Math.PI+this.angleOffset+this.angleArc;var e=n(String(Math.abs(this.o.max)).length,String(Math.abs(this.o.min)).length,2)+2;this.o.displayInput&&this.i.css({width:(this.w/2+4>>0)+"px",height:(this.w/3>>0)+"px",position:"absolute","vertical-align":"middle","margin-top":(this.w/3>>0)+"px","margin-left":"-"+(this.w*3/4+2>>0)+"px",border:0,background:"none",font:this.o.fontWeight+" "+(this.w/e>>0)+"px "+this.o.font,"text-align":"center",color:this.o.inputColor||this.o.fgColor,padding:"0px","-webkit-appearance":"none"})||this.i.css({width:"0px",visibility:"hidden"})};this.change=function(e){this.cv=e;this.$.val(this.o.format(e))};this.angle=function(e){return(e-this.o.min)*this.angleArc/(this.o.max-this.o.min)};this.arc=function(e){var t,n;e=this.angle(e);if(this.o.flip){t=this.endAngle+1e-5;n=t-e-1e-5}else{t=this.startAngle-1e-5;n=t+e+1e-5}this.o.cursor&&(t=n-this.cursorExt)&&(n=n+this.cursorExt);return{s:t,e:n,d:this.o.flip&&!this.o.cursor}};this.draw=function(){var e=this.g,t=this.arc(this.cv),n,r=1;e.lineWidth=this.lineWidth;e.lineCap=this.lineCap;if(this.o.bgColor!=="none"){e.beginPath();e.strokeStyle=this.o.bgColor;e.arc(this.xy,this.xy,this.radius,this.endAngle-1e-5,this.startAngle+1e-5,true);e.stroke()}if(this.o.displayPrevious){n=this.arc(this.v);e.beginPath();e.strokeStyle=this.pColor;e.arc(this.xy,this.xy,this.radius,n.s,n.e,n.d);e.stroke();r=this.cv==this.v}e.beginPath();e.strokeStyle=r?this.o.fgColor:this.fgColor;e.arc(this.xy,this.xy,this.radius,t.s,t.e,t.d);e.stroke()};this.cancel=function(){this.val(this.v)}};e.fn.dial=e.fn.knob=function(n){return this.each(function(){var r=new t.Dial;r.o=n;r.$=e(this);r.run()}).parent()}}) \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-slimscroll/jquery.slimscroll.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-slimscroll/jquery.slimscroll.js deleted file mode 100644 index b9f0d0996..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-slimscroll/jquery.slimscroll.js +++ /dev/null @@ -1,443 +0,0 @@ -/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) - * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) - * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - * - * Version: 1.3.0 - * - */ -(function ($) { - - jQuery.fn.extend({ - slimScroll: function (options) { - - var defaults = { - - // width in pixels of the visible scroll area - width: 'auto', - - // height in pixels of the visible scroll area - height: '250px', - - // width in pixels of the scrollbar and rail - size: '7px', - - // scrollbar color, accepts any hex/color value - color: '#000', - - // scrollbar position - left/right - position: 'right', - - // distance in pixels between the side edge and the scrollbar - distance: '1px', - - // default scroll position on load - top / bottom / $('selector') - start: 'top', - - // sets scrollbar opacity - opacity: .4, - - // enables always-on mode for the scrollbar - alwaysVisible: false, - - // check if we should hide the scrollbar when user is hovering over - disableFadeOut: false, - - // sets visibility of the rail - railVisible: false, - - // sets rail color - railColor: '#333', - - // sets rail opacity - railOpacity: .2, - - // whether we should use jQuery UI Draggable to enable bar dragging - railDraggable: true, - - // defautlt CSS class of the slimscroll rail - railClass: 'slimScrollRail', - - // defautlt CSS class of the slimscroll bar - barClass: 'slimScrollBar', - - // defautlt CSS class of the slimscroll wrapper - wrapperClass: 'slimScrollDiv', - - // check if mousewheel should scroll the window if we reach top/bottom - allowPageScroll: false, - - // scroll amount applied to each mouse wheel step - wheelStep: 20, - - // scroll amount applied when user is using gestures - touchScrollStep: 200, - - // sets border radius - borderRadius: '7px', - - // sets border radius of the rail - railBorderRadius: '7px' - }; - - var o = $.extend(defaults, options); - - // do it for every element that matches selector - this.each(function () { - - var isOverPanel, isOverBar, isDragg, queueHide, touchDif, - barHeight, percentScroll, lastScroll, - divS = '
    ', - minBarHeight = 30, - releaseScroll = false; - - // used in event handlers and for better minification - var me = $(this); - - // ensure we are not binding it again - if (me.parent().hasClass(o.wrapperClass)) { - // start from last bar position - var offset = me.scrollTop(); - - // find bar and rail - bar = me.parent().find('.' + o.barClass); - rail = me.parent().find('.' + o.railClass); - - getBarHeight(); - - // check if we should scroll existing instance - if ($.isPlainObject(options)) { - // Pass height: auto to an existing slimscroll object to force a resize after contents have changed - if ('height' in options && options.height == 'auto') { - me.parent().css('height', 'auto'); - me.css('height', 'auto'); - var height = me.parent().parent().height(); - me.parent().css('height', height); - me.css('height', height); - } - - if ('scrollTo' in options) { - // jump to a static point - offset = parseInt(o.scrollTo); - } - else if ('scrollBy' in options) { - // jump by value pixels - offset += parseInt(o.scrollBy); - } - else if ('destroy' in options) { - // remove slimscroll elements - bar.remove(); - rail.remove(); - me.unwrap(); - return; - } - - // scroll content by the given offset - scrollContent(offset, false, true); - } - - return; - } - - // optionally set height to the parent's height - o.height = (o.height == 'auto') ? me.parent().height() : o.height; - - // wrap content - var wrapper = $(divS) - .addClass(o.wrapperClass) - .css({ - position: 'relative', - overflow: 'hidden', - width: o.width, - height: o.height - }); - - // update style for the div - me.css({ - overflow: 'hidden', - width: o.width, - height: o.height - }); - - // create scrollbar rail - var rail = $(divS) - .addClass(o.railClass) - .css({ - width: o.size, - height: '100%', - position: 'absolute', - top: 0, - display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none', - 'border-radius': o.railBorderRadius, - background: o.railColor, - opacity: o.railOpacity, - zIndex: 90 - }); - - // create scrollbar - var bar = $(divS) - .addClass(o.barClass) - .css({ - background: o.color, - width: o.size, - position: 'absolute', - top: 0, - opacity: o.opacity, - display: o.alwaysVisible ? 'block' : 'none', - 'border-radius': o.borderRadius, - BorderRadius: o.borderRadius, - MozBorderRadius: o.borderRadius, - WebkitBorderRadius: o.borderRadius, - zIndex: 99 - }); - - // set position - var posCss = (o.position == 'right') ? { right: o.distance } : { left: o.distance }; - rail.css(posCss); - bar.css(posCss); - - // wrap it - me.wrap(wrapper); - - // append to parent div - me.parent().append(bar); - me.parent().append(rail); - - // make it draggable and no longer dependent on the jqueryUI - if (o.railDraggable) { - bar.bind("mousedown", function (e) { - var $doc = $(document); - isDragg = true; - t = parseFloat(bar.css('top')); - pageY = e.pageY; - - $doc.bind("mousemove.slimscroll", function (e) { - currTop = t + e.pageY - pageY; - bar.css('top', currTop); - scrollContent(0, bar.position().top, false);// scroll content - }); - - $doc.bind("mouseup.slimscroll", function (e) { - isDragg = false; hideBar(); - $doc.unbind('.slimscroll'); - }); - return false; - }).bind("selectstart.slimscroll", function (e) { - e.stopPropagation(); - e.preventDefault(); - return false; - }); - } - - // on rail over - rail.hover(function () { - showBar(); - }, function () { - hideBar(); - }); - - // on bar over - bar.hover(function () { - isOverBar = true; - }, function () { - isOverBar = false; - }); - - // show on parent mouseover - me.hover(function () { - isOverPanel = true; - showBar(); - hideBar(); - }, function () { - isOverPanel = false; - hideBar(); - }); - - // support for mobile - me.bind('touchstart', function (e, b) { - if (e.originalEvent.touches.length) { - // record where touch started - touchDif = e.originalEvent.touches[0].pageY; - } - }); - - me.bind('touchmove', function (e) { - // prevent scrolling the page if necessary - if (!releaseScroll) { - e.originalEvent.preventDefault(); - } - if (e.originalEvent.touches.length) { - // see how far user swiped - var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep; - // scroll content - scrollContent(diff, true); - touchDif = e.originalEvent.touches[0].pageY; - } - }); - - // set up initial height - getBarHeight(); - - // check start position - if (o.start === 'bottom') { - // scroll content to bottom - bar.css({ top: me.outerHeight() - bar.outerHeight() }); - scrollContent(0, true); - } - else if (o.start !== 'top') { - // assume jQuery selector - scrollContent($(o.start).position().top, null, true); - - // make sure bar stays hidden - if (!o.alwaysVisible) { bar.hide(); } - } - - // attach scroll events - attachWheel(); - - function _onWheel(e) { - // use mouse wheel only when mouse is over - if (!isOverPanel) { return; } - - var e = e || window.event; - - var delta = 0; - if (e.wheelDelta) { delta = -e.wheelDelta / 120; } - if (e.detail) { delta = e.detail / 3; } - - var target = e.target || e.srcTarget || e.srcElement; - /* console.log($(target).closest('.' + o.wrapperClass).attr("class")); - console.log(me.parent().attr("class"));*/ - if ($(target).closest('.' + o.wrapperClass).is(me.parent())) { - // scroll content - - scrollContent(delta, true); - } - - // stop window scroll - if (e.preventDefault && !releaseScroll) { e.preventDefault(); } - if (!releaseScroll) { e.returnValue = false; } - } - - function scrollContent(y, isWheel, isJump) { - - releaseScroll = false; - var delta = y; - var maxTop = me.outerHeight() - bar.outerHeight(); - - if (isWheel) { - // move bar with mouse wheel - delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight(); - - // move bar, make sure it doesn't go out - delta = Math.min(Math.max(delta, 0), maxTop); - - // if scrolling down, make sure a fractional change to the - // scroll position isn't rounded away when the scrollbar's CSS is set - // this flooring of delta would happened automatically when - // bar.css is set below, but we floor here for clarity - delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta); - - // scroll the scrollbar - bar.css({ top: delta + 'px' }); - } - - // calculate actual scroll amount - percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight()); - delta = percentScroll * (me[0].scrollHeight - me.outerHeight()); - - if (isJump) { - delta = y; - var offsetTop = delta / me[0].scrollHeight * me.outerHeight(); - offsetTop = Math.min(Math.max(offsetTop, 0), maxTop); - bar.css({ top: offsetTop + 'px' }); - } - - // scroll content - me.scrollTop(delta); - - // fire scrolling event - me.trigger('slimscrolling', ~~delta); - - // ensure bar is visible - showBar(); - - // trigger hide when scroll is stopped - hideBar(); - } - - function attachWheel() { - if (window.addEventListener) { - this.addEventListener('DOMMouseScroll', _onWheel, false); - this.addEventListener('mousewheel', _onWheel, false); - //this.addEventListener('MozMousePixelScroll', _onWheel, false ); - } - else { - document.attachEvent("onmousewheel", _onWheel) - } - } - - function getBarHeight() { - // calculate scrollbar height and make sure it is not too small - barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight); - bar.css({ height: barHeight + 'px' }); - - // hide scrollbar if content is not long enough - var display = barHeight == me.outerHeight() ? 'none' : 'block'; - bar.css({ display: display }); - } - - function showBar() { - // recalculate bar height - getBarHeight(); - clearTimeout(queueHide); - - // when bar reached top or bottom - if (percentScroll == ~~percentScroll) { - //release wheel - releaseScroll = o.allowPageScroll; - - // publish approporiate event - if (lastScroll != percentScroll) { - var msg = (~~percentScroll == 0) ? 'top' : 'bottom'; - me.trigger('slimscroll', msg); - } - } - else { - releaseScroll = false; - } - lastScroll = percentScroll; - - // show only when required - if (barHeight >= me.outerHeight()) { - //allow window scroll - releaseScroll = true; - return; - } - bar.stop(true, true).fadeIn('fast'); - if (o.railVisible) { rail.stop(true, true).fadeIn('fast'); } - } - - function hideBar() { - // only hide when options allow it - if (!o.alwaysVisible) { - queueHide = setTimeout(function () { - if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg) { - bar.fadeOut('slow'); - rail.fadeOut('slow'); - } - }, 1000); - } - } - - }); - - // maintain chainability - return this; - } - }); - - jQuery.fn.extend({ - slimscroll: jQuery.fn.slimScroll - }); - -})(jQuery); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.css b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.css deleted file mode 100644 index 4f1d9df43..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.css +++ /dev/null @@ -1,61 +0,0 @@ -.spinner.input-group .input-group-addon .spin-up, -.spinner.input-group .input-group-addon .spin-down { - height: 10px; - width: 10px; - overflow: hidden; - display: block; - text-align: center; - color: #999; -} -.spinner.input-group .input-group-addon .spin-up:hover, -.spinner.input-group .input-group-addon .spin-down:hover { - color: #555; -} -.spinner.input-group .input-group-addon .spin-up .fa, -.spinner.input-group .input-group-addon .spin-down .fa { - margin-top: -8px; - vertical-align: middle; -} -.spinner.input-group .input-group-addon .spin-up .glyphicon, -.spinner.input-group .input-group-addon .spin-down .glyphicon { - font-size: 10px; - top: -2px; -} -.spinner.input-group .input-group-addon a.spin-up, -.spinner.input-group .input-group-addon a.spin-down { - text-decoration: none; -} -.spinner.input-group .input-group-addon button.spin-up, -.spinner.input-group .input-group-addon button.spin-down { - background: none; - border: none; - padding: 0; -} -.spinner.input-group.input-group-sm .input-group-addon .spin-up, -.spinner.input-group.input-group-sm .input-group-addon .spin-down { - height: 8px; -} -.spinner.input-group.input-group-sm .input-group-addon .spin-up .fa, -.spinner.input-group.input-group-sm .input-group-addon .spin-down .fa { - margin-top: -12px; -} -.spinner.input-group.input-group-sm .input-group-addon .spin-up .glyphicon, -.spinner.input-group.input-group-sm .input-group-addon .spin-down .glyphicon { - font-size: 8px; - top: -5px; -} -.spinner.input-group.input-group-lg .input-group-addon .spin-up, -.spinner.input-group.input-group-lg .input-group-addon .spin-down { - height: 12px; - width: 12px; -} -.spinner.input-group.input-group-lg .input-group-addon .spin-up .fa, -.spinner.input-group.input-group-lg .input-group-addon .spin-down .fa { - margin-top: -16px; -} -.spinner.input-group.input-group-lg .input-group-addon .spin-up .glyphicon, -.spinner.input-group.input-group-lg .input-group-addon .spin-down .glyphicon { - font-size: 12px; - top: -6px; -} -/*# sourceMappingURL=bootstrap-spinner.css.map */ \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.css.map b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.css.map deleted file mode 100644 index d2c567d02..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["less/bootstrap-spinner.less"],"names":[],"mappings":"AAAA,QAAQ,YACN,mBACE;AAFJ,QAAQ,YACN,mBAEE;EACE,YAAA;EACA,WAAA;EACA,gBAAA;EACA,cAAA;EACA,kBAAA;EACA,WAAA;;AAEA,QAXE,YACN,mBACE,SASG;AAAD,QAXE,YACN,mBAEE,WAQG;EACC,WAAA;;AAZR,QAAQ,YACN,mBACE,SAaE;AAfN,QAAQ,YACN,mBAEE,WAYE;EACE,gBAAA;EACA,sBAAA;;AAjBR,QAAQ,YACN,mBACE,SAkBE;AApBN,QAAQ,YACN,mBAEE,WAiBE;EACE,eAAA;EACA,SAAA;;AAtBR,QAAQ,YACN,mBAyBE,EAAC;AA1BL,QAAQ,YACN,mBA0BE,EAAC;EACC,qBAAA;;AA5BN,QAAQ,YACN,mBA8BE,OAAM;AA/BV,QAAQ,YACN,mBA+BE,OAAM;EACJ,gBAAA;EACA,YAAA;EACA,UAAA;;AAIJ,QAvCM,YAuCL,eAAgB,mBACf;AADF,QAvCM,YAuCL,eAAgB,mBAEf;EACE,WAAA;;AAHJ,QAvCM,YAuCL,eAAgB,mBACf,SAIE;AALJ,QAvCM,YAuCL,eAAgB,mBAEf,WAGE;EACE,iBAAA;;AANN,QAvCM,YAuCL,eAAgB,mBACf,SAQE;AATJ,QAvCM,YAuCL,eAAgB,mBAEf,WAOE;EACE,cAAA;EACA,SAAA;;AAKN,QAvDM,YAuDL,eAAgB,mBACf;AADF,QAvDM,YAuDL,eAAgB,mBAEf;EACE,YAAA;EACA,WAAA;;AAJJ,QAvDM,YAuDL,eAAgB,mBACf,SAKE;AANJ,QAvDM,YAuDL,eAAgB,mBAEf,WAIE;EACE,iBAAA;;AAPN,QAvDM,YAuDL,eAAgB,mBACf,SASE;AAVJ,QAvDM,YAuDL,eAAgB,mBAEf,WAQE;EACE,eAAA;EACA,SAAA","sourcesContent":[".spinner.input-group {\n .input-group-addon {\n .spin-up,\n .spin-down {\n height: 10px;\n width: 10px;\n overflow: hidden;\n display: block;\n text-align: center;\n color: #999;\n\n &:hover {\n color: #555;\n }\n\n .fa {\n margin-top: -8px;\n vertical-align: middle;\n }\n\n .glyphicon {\n font-size: 10px;\n top: -2px;\n }\n }\n\n a.spin-up,\n a.spin-down {\n text-decoration: none;\n }\n\n button.spin-up,\n button.spin-down {\n background: none;\n border: none;\n padding: 0;\n }\n }\n\n &.input-group-sm .input-group-addon {\n .spin-up,\n .spin-down {\n height: 8px;\n\n .fa {\n margin-top: -12px;\n }\n\n .glyphicon {\n font-size: 8px;\n top: -5px;\n }\n }\n }\n\n &.input-group-lg .input-group-addon {\n .spin-up,\n .spin-down {\n height: 12px;\n width: 12px;\n\n .fa {\n margin-top: -16px;\n }\n\n .glyphicon {\n font-size: 12px;\n top: -6px;\n }\n }\n }\n}\n"]} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.min.css b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.min.css deleted file mode 100644 index 943e1cfc7..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/css/bootstrap-spinner.min.css +++ /dev/null @@ -1 +0,0 @@ -.spinner.input-group .input-group-addon .spin-down,.spinner.input-group .input-group-addon .spin-up{height:10px;width:10px;overflow:hidden;display:block;text-align:center;color:#999}.spinner.input-group .input-group-addon .spin-down:hover,.spinner.input-group .input-group-addon .spin-up:hover{color:#555}.spinner.input-group .input-group-addon .spin-down .fa,.spinner.input-group .input-group-addon .spin-up .fa{margin-top:-8px;vertical-align:middle}.spinner.input-group .input-group-addon .spin-down .glyphicon,.spinner.input-group .input-group-addon .spin-up .glyphicon{font-size:10px;top:-2px}.spinner.input-group .input-group-addon a.spin-down,.spinner.input-group .input-group-addon a.spin-up{text-decoration:none}.spinner.input-group .input-group-addon button.spin-down,.spinner.input-group .input-group-addon button.spin-up{background:0 0;border:none;padding:0}.spinner.input-group.input-group-sm .input-group-addon .spin-down,.spinner.input-group.input-group-sm .input-group-addon .spin-up{height:8px}.spinner.input-group.input-group-sm .input-group-addon .spin-down .fa,.spinner.input-group.input-group-sm .input-group-addon .spin-up .fa{margin-top:-12px}.spinner.input-group.input-group-sm .input-group-addon .spin-down .glyphicon,.spinner.input-group.input-group-sm .input-group-addon .spin-up .glyphicon{font-size:8px;top:-5px}.spinner.input-group.input-group-lg .input-group-addon .spin-down,.spinner.input-group.input-group-lg .input-group-addon .spin-up{height:12px;width:12px}.spinner.input-group.input-group-lg .input-group-addon .spin-down .fa,.spinner.input-group.input-group-lg .input-group-addon .spin-up .fa{margin-top:-16px}.spinner.input-group.input-group-lg .input-group-addon .spin-down .glyphicon,.spinner.input-group.input-group-lg .input-group-addon .spin-up .glyphicon{font-size:12px;top:-6px} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/js/jquery.spinner.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/js/jquery.spinner.js deleted file mode 100644 index ddd037c3e..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/js/jquery.spinner.js +++ /dev/null @@ -1,255 +0,0 @@ -/*! - * jquery.spinner v0.2.1 (https://vsn4ik.github.io/jquery.spinner/) - * Copyright 2013-2016 xixilive - * Licensed under the MIT license - */ -'use strict'; - -(function(factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module - define(['jquery'], factory); - } - else if (typeof exports === 'object') { - // Node/CommonJS - module.exports = factory(require('jquery')); - } - else { - // Browser globals - factory(jQuery); - } -})(function($) { - var spinningTimer; - var Spinner; - var Spinning = function($element, options) { - this.$el = $element; - this.options = $.extend({}, Spinning.rules.defaults, Spinning.rules[options.rule] || {}, options); - this.min = Number(this.options.min) || 0; - this.max = Number(this.options.max) || 0; - - this.$el.on({ - 'focus.spinner': $.proxy(function(e) { - e.preventDefault(); - $(document).trigger('mouseup.spinner'); - this.oldValue = this.value(); - }, this), - 'change.spinner': $.proxy(function(e) { - e.preventDefault(); - this.value(this.$el.val()); - }, this), - 'keydown.spinner': $.proxy(function(e) { - var dir = { - 38: 'up', - 40: 'down' - }[e.which]; - - if (dir) { - e.preventDefault(); - this.spin(dir); - } - }, this) - }); - - //init input value - this.oldValue = this.value(); - this.value(this.$el.val()); - return this; - }; - - Spinning.rules = { - defaults: { min: null, max: null, step: 1, precision: 0 }, - currency: { min: 0.00, max: null, step: 0.01, precision: 2 }, - quantity: { min: 1, max: 999, step: 1, precision: 0 }, - percent: { min: 1, max: 100, step: 1, precision: 0 }, - month: { min: 1, max: 12, step: 1, precision: 0 }, - day: { min: 1, max: 31, step: 1, precision: 0 }, - hour: { min: 0, max: 23, step: 1, precision: 0 }, - minute: { min: 1, max: 59, step: 1, precision: 0 }, - second: { min: 1, max: 59, step: 1, precision: 0 } - }; - - Spinning.prototype = { - spin: function(dir) { - if (this.$el.prop('disabled')) { - return; - } - - this.oldValue = this.value(); - var step = $.isFunction(this.options.step) ? this.options.step.call(this, dir) : this.options.step; - var multipler = dir === 'up' ? 1 : -1; - - this.value(this.oldValue + Number(step) * multipler); - }, - - value: function(v) { - if (v === null || v === undefined) { - return this.numeric(this.$el.val()); - } - v = this.numeric(v); - - var valid = this.validate(v); - if (valid !== 0) { - v = (valid === -1) ? this.min : this.max; - } - this.$el.val(v.toFixed(this.options.precision)); - - if (this.oldValue !== this.value()) { - // changing.spinner - this.$el.trigger('changing.spinner', [this.value(), this.oldValue]); - - // lazy changed.spinner - clearTimeout(spinningTimer); - spinningTimer = setTimeout($.proxy(function() { - this.$el.trigger('changed.spinner', [this.value(), this.oldValue]); - }, this), Spinner.delay); - } - }, - - numeric: function(v) { - v = this.options.precision > 0 ? parseFloat(v, 10) : parseInt(v, 10); - - // If the variable is a number - if (isFinite(v)) { - return v; - } - - return v || this.options.min || 0; - }, - - validate: function(val) { - if (this.options.min !== null && val < this.min) { - return -1; - } - - if (this.options.max !== null && val > this.max) { - return 1; - } - - return 0; - } - }; - - Spinner = function(element, options) { - this.$el = $(element); - this.$spinning = this.$el.find('[data-spin="spinner"]'); - - if (this.$spinning.length === 0) { - this.$spinning = this.$el.find(':input[type="text"]'); - } - - options = $.extend({}, options, this.$spinning.data()); - - this.spinning = new Spinning(this.$spinning, options); - - this.$el - .on('click.spinner', '[data-spin="up"], [data-spin="down"]', $.proxy(this, 'spin')) - .on('mousedown.spinner', '[data-spin="up"], [data-spin="down"]', $.proxy(this, 'spin')); - - $(document).on('mouseup.spinner', $.proxy(function() { - clearTimeout(this.spinTimeout); - clearInterval(this.spinInterval); - }, this)); - - if (options.delay) { - this.delay(options.delay); - } - - if (options.changed) { - this.changed(options.changed); - } - - if (options.changing) { - this.changing(options.changing); - } - }; - - Spinner.delay = 500; - - Spinner.prototype = { - constructor: Spinner, - - spin: function(e) { - var dir = $(e.currentTarget).data('spin'); - - switch (e.type) { - case 'click': - e.preventDefault(); - this.spinning.spin(dir); - break; - case 'mousedown': - if (e.which === 1) { - this.spinTimeout = setTimeout($.proxy(this, 'beginSpin', dir), 300); - } - break; - } - }, - - delay: function(ms) { - var delay = Number(ms); - - if (delay >= 0) { - this.constructor.delay = delay + 100; - } - }, - - value: function() { - return this.spinning.value(); - }, - - changed: function(fn) { - this.bindHandler('changed.spinner', fn); - }, - - changing: function(fn) { - this.bindHandler('changing.spinner', fn); - }, - - bindHandler: function(t, fn) { - if ($.isFunction(fn)) { - this.$spinning.on(t, fn); - } - else { - this.$spinning.off(t); - } - }, - - beginSpin: function(dir) { - this.spinInterval = setInterval($.proxy(this.spinning, 'spin', dir), 100); - } - }; - - var old = $.fn.spinner; - - $.fn.spinner = function(options, value) { - return this.each(function() { - var data = $.data(this, 'spinner'); - - if (!data) { - data = new Spinner(this, options); - - $.data(this, 'spinner', data); - } - if (options === 'delay' || options === 'changed' || options === 'changing') { - data[options](value); - } - else if (options === 'step' && value) { - data.spinning.step = value; - } - else if (options === 'spin' && value) { - data.spinning.spin(value); - } - }); - }; - - $.fn.spinner.Constructor = Spinner; - $.fn.spinner.noConflict = function() { - $.fn.spinner = old; - return this; - }; - - $(function() { - $('[data-trigger="spinner"]').spinner(); - }); - - return $.fn.spinner; -}); diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/js/jquery.spinner.min.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/js/jquery.spinner.min.js deleted file mode 100644 index b0346c9d7..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-spinner/js/jquery.spinner.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * jquery.spinner v0.2.1 (https://vsn4ik.github.io/jquery.spinner/) - * Copyright 2013-2016 xixilive - * Licensed under the MIT license - */ -"use strict";!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){var b,c,d=function(b,c){return this.$el=b,this.options=a.extend({},d.rules.defaults,d.rules[c.rule]||{},c),this.min=Number(this.options.min)||0,this.max=Number(this.options.max)||0,this.$el.on({"focus.spinner":a.proxy(function(b){b.preventDefault(),a(document).trigger("mouseup.spinner"),this.oldValue=this.value()},this),"change.spinner":a.proxy(function(a){a.preventDefault(),this.value(this.$el.val())},this),"keydown.spinner":a.proxy(function(a){var b={38:"up",40:"down"}[a.which];b&&(a.preventDefault(),this.spin(b))},this)}),this.oldValue=this.value(),this.value(this.$el.val()),this};d.rules={defaults:{min:null,max:null,step:1,precision:0},currency:{min:0,max:null,step:.01,precision:2},quantity:{min:1,max:999,step:1,precision:0},percent:{min:1,max:100,step:1,precision:0},month:{min:1,max:12,step:1,precision:0},day:{min:1,max:31,step:1,precision:0},hour:{min:0,max:23,step:1,precision:0},minute:{min:1,max:59,step:1,precision:0},second:{min:1,max:59,step:1,precision:0}},d.prototype={spin:function(b){if(!this.$el.prop("disabled")){this.oldValue=this.value();var c=a.isFunction(this.options.step)?this.options.step.call(this,b):this.options.step,d="up"===b?1:-1;this.value(this.oldValue+Number(c)*d)}},value:function(d){if(null===d||void 0===d)return this.numeric(this.$el.val());d=this.numeric(d);var e=this.validate(d);0!==e&&(d=e===-1?this.min:this.max),this.$el.val(d.toFixed(this.options.precision)),this.oldValue!==this.value()&&(this.$el.trigger("changing.spinner",[this.value(),this.oldValue]),clearTimeout(b),b=setTimeout(a.proxy(function(){this.$el.trigger("changed.spinner",[this.value(),this.oldValue])},this),c.delay))},numeric:function(a){return a=this.options.precision>0?parseFloat(a,10):parseInt(a,10),isFinite(a)?a:a||this.options.min||0},validate:function(a){return null!==this.options.min&&athis.max?1:0}},c=function(b,c){this.$el=a(b),this.$spinning=this.$el.find('[data-spin="spinner"]'),0===this.$spinning.length&&(this.$spinning=this.$el.find(':input[type="text"]')),c=a.extend({},c,this.$spinning.data()),this.spinning=new d(this.$spinning,c),this.$el.on("click.spinner",'[data-spin="up"], [data-spin="down"]',a.proxy(this,"spin")).on("mousedown.spinner",'[data-spin="up"], [data-spin="down"]',a.proxy(this,"spin")),a(document).on("mouseup.spinner",a.proxy(function(){clearTimeout(this.spinTimeout),clearInterval(this.spinInterval)},this)),c.delay&&this.delay(c.delay),c.changed&&this.changed(c.changed),c.changing&&this.changing(c.changing)},c.delay=500,c.prototype={constructor:c,spin:function(b){var c=a(b.currentTarget).data("spin");switch(b.type){case"click":b.preventDefault(),this.spinning.spin(c);break;case"mousedown":1===b.which&&(this.spinTimeout=setTimeout(a.proxy(this,"beginSpin",c),300))}},delay:function(a){var b=Number(a);b>=0&&(this.constructor.delay=b+100)},value:function(){return this.spinning.value()},changed:function(a){this.bindHandler("changed.spinner",a)},changing:function(a){this.bindHandler("changing.spinner",a)},bindHandler:function(b,c){a.isFunction(c)?this.$spinning.on(b,c):this.$spinning.off(b)},beginSpin:function(b){this.spinInterval=setInterval(a.proxy(this.spinning,"spin",b),100)}};var e=a.fn.spinner;return a.fn.spinner=function(b,d){return this.each(function(){var e=a.data(this,"spinner");e||(e=new c(this,b),a.data(this,"spinner",e)),"delay"===b||"changed"===b||"changing"===b?e[b](d):"step"===b&&d?e.spinning.step=d:"spin"===b&&d&&e.spinning.spin(d)})},a.fn.spinner.Constructor=c,a.fn.spinner.noConflict=function(){return a.fn.spinner=e,this},a(function(){a('[data-trigger="spinner"]').spinner()}),a.fn.spinner}); \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-steps/jquery.steps.css b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-steps/jquery.steps.css deleted file mode 100644 index 2b59b5880..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-steps/jquery.steps.css +++ /dev/null @@ -1,382 +0,0 @@ -/* - Common -*/ - -.wizard, -.tabcontrol -{ - display: block; - width: 100%; - overflow: hidden; -} - -.wizard a, -.tabcontrol a -{ - outline: 0; -} - -.wizard ul, -.tabcontrol ul -{ - list-style: none !important; - padding: 0; - margin: 0; -} - -.wizard ul > li, -.tabcontrol ul > li -{ - display: block; - padding: 0; -} - -/* Accessibility */ -.wizard > .steps .current-info, -.tabcontrol > .steps .current-info -{ - position: absolute; - left: -999em; -} - -.wizard > .content > .title, -.tabcontrol > .content > .title -{ - position: absolute; - left: -999em; -} - - - -/* - Wizard -*/ - -.wizard > .steps -{ - position: relative; - display: block; - width: 100%; -} - -.wizard.vertical > .steps -{ - display: inline; - float: left; - width: 30%; -} - -.wizard > .steps .number -{ - font-size: 1.429em; -} - -.wizard > .steps > ul > li -{ - width: 25%; -} - -.wizard > .steps > ul > li, -.wizard > .actions > ul > li -{ - float: left; -} - -.wizard.vertical > .steps > ul > li -{ - float: none; - width: 100%; -} - -.wizard > .steps a, -.wizard > .steps a:hover, -.wizard > .steps a:active -{ - display: block; - width: auto; - margin: 0 0.5em 0.5em; - padding: 1em 1em; - text-decoration: none; - - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - -.wizard > .steps .disabled a, -.wizard > .steps .disabled a:hover, -.wizard > .steps .disabled a:active -{ - background: #eee; - color: #aaa; - cursor: default; -} - -.wizard > .steps .current a, -.wizard > .steps .current a:hover, -.wizard > .steps .current a:active -{ - background: #2184be; - color: #fff; - cursor: default; -} - -.wizard > .steps .done a, -.wizard > .steps .done a:hover, -.wizard > .steps .done a:active -{ - background: #9dc8e2; - color: #fff; -} - -.wizard > .steps .error a, -.wizard > .steps .error a:hover, -.wizard > .steps .error a:active -{ - background: #ff3111; - color: #fff; -} - -.wizard > .content -{ - background: #eee; - display: block; - margin: 0.5em; - min-height: 35em; - overflow: hidden; - position: relative; - width: auto; - - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - -.wizard.vertical > .content -{ - display: inline; - float: left; - margin: 0 2.5% 0.5em 2.5%; - width: 65%; -} - -.wizard > .content > .body -{ - float: left; - position: absolute; - width: 95%; - height: 95%; - padding: 2.5%; -} - -.wizard > .content > .body ul -{ - list-style: disc !important; -} - -.wizard > .content > .body ul > li -{ - display: list-item; -} - -.wizard > .content > .body > iframe -{ - border: 0 none; - width: 100%; - height: 100%; -} - -.wizard > .content > .body input -{ - display: block; - border: 1px solid #ccc; -} - -.wizard > .content > .body input[type="checkbox"] -{ - display: inline-block; -} - -.wizard > .content > .body input.error -{ - background: rgb(251, 227, 228); - border: 1px solid #fbc2c4; - color: #8a1f11; -} - -.wizard > .content > .body label -{ - display: inline-block; - margin-bottom: 0.5em; -} - -.wizard > .content > .body label.error -{ - color: #8a1f11; - display: inline-block; - margin-left: 1.5em; -} - -.wizard > .actions -{ - position: relative; - display: block; - text-align: right; - width: 100%; -} - -.wizard.vertical > .actions -{ - display: inline; - float: right; - margin: 0 2.5%; - width: 95%; -} - -.wizard > .actions > ul -{ - display: inline-block; - text-align: right; -} - -.wizard > .actions > ul > li -{ - margin: 0 0.5em; -} - -.wizard.vertical > .actions > ul > li -{ - margin: 0 0 0 1em; -} - -.wizard > .actions a, -.wizard > .actions a:hover, -.wizard > .actions a:active -{ - background: #2184be; - color: #fff; - display: block; - padding: 0.5em 1em; - text-decoration: none; - - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - -.wizard > .actions .disabled a, -.wizard > .actions .disabled a:hover, -.wizard > .actions .disabled a:active -{ - background: #eee; - color: #aaa; -} - -.wizard > .loading -{ -} - -.wizard > .loading .spinner -{ -} - - - -/* - Tabcontrol -*/ - -.tabcontrol > .steps -{ - position: relative; - display: block; - width: 100%; -} - -.tabcontrol > .steps > ul -{ - position: relative; - margin: 6px 0 0 0; - top: 1px; - z-index: 1; -} - -.tabcontrol > .steps > ul > li -{ - float: left; - margin: 5px 2px 0 0; - padding: 1px; - - -webkit-border-top-left-radius: 5px; - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topleft: 5px; - -moz-border-radius-topright: 5px; - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} - -.tabcontrol > .steps > ul > li:hover -{ - background: #edecec; - border: 1px solid #bbb; - padding: 0; -} - -.tabcontrol > .steps > ul > li.current -{ - background: #fff; - border: 1px solid #bbb; - border-bottom: 0 none; - padding: 0 0 1px 0; - margin-top: 0; -} - -.tabcontrol > .steps > ul > li > a -{ - color: #5f5f5f; - display: inline-block; - border: 0 none; - margin: 0; - padding: 10px 30px; - text-decoration: none; -} - -.tabcontrol > .steps > ul > li > a:hover -{ - text-decoration: none; -} - -.tabcontrol > .steps > ul > li.current > a -{ - padding: 15px 30px 10px 30px; -} - -.tabcontrol > .content -{ - position: relative; - display: inline-block; - width: 100%; - height: 35em; - overflow: hidden; - border-top: 1px solid #bbb; - padding-top: 20px; -} - -.tabcontrol > .content > .body -{ - float: left; - position: absolute; - width: 95%; - height: 95%; - padding: 2.5%; -} - -.tabcontrol > .content > .body ul -{ - list-style: disc !important; -} - -.tabcontrol > .content > .body ul > li -{ - display: list-item; -} \ No newline at end of file diff --git a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-steps/jquery.steps.js b/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-steps/jquery.steps.js deleted file mode 100644 index 3550b113c..000000000 --- a/Plan/common/src/main/resources/assets/plan/web/plugins/jquery-steps/jquery.steps.js +++ /dev/null @@ -1,2040 +0,0 @@ -/*! - * jQuery Steps v1.1.0 - 09/04/2014 - * Copyright (c) 2014 Rafael Staib (http://www.jquery-steps.com) - * Licensed under MIT http://www.opensource.org/licenses/MIT - */ -;(function ($, undefined) -{ -$.fn.extend({ - _aria: function (name, value) - { - return this.attr("aria-" + name, value); - }, - - _removeAria: function (name) - { - return this.removeAttr("aria-" + name); - }, - - _enableAria: function (enable) - { - return (enable == null || enable) ? - this.removeClass("disabled")._aria("disabled", "false") : - this.addClass("disabled")._aria("disabled", "true"); - }, - - _showAria: function (show) - { - return (show == null || show) ? - this.show()._aria("hidden", "false") : - this.hide()._aria("hidden", "true"); - }, - - _selectAria: function (select) - { - return (select == null || select) ? - this.addClass("current")._aria("selected", "true") : - this.removeClass("current")._aria("selected", "false"); - }, - - _id: function (id) - { - return (id) ? this.attr("id", id) : this.attr("id"); - } -}); - -if (!String.prototype.format) -{ - String.prototype.format = function() - { - var args = (arguments.length === 1 && $.isArray(arguments[0])) ? arguments[0] : arguments; - var formattedString = this; - for (var i = 0; i < args.length; i++) - { - var pattern = new RegExp("\\{" + i + "\\}", "gm"); - formattedString = formattedString.replace(pattern, args[i]); - } - return formattedString; - }; -} - -/** - * A global unique id count. - * - * @static - * @private - * @property _uniqueId - * @type Integer - **/ -var _uniqueId = 0; - -/** - * The plugin prefix for cookies. - * - * @final - * @private - * @property _cookiePrefix - * @type String - **/ -var _cookiePrefix = "jQu3ry_5teps_St@te_"; - -/** - * Suffix for the unique tab id. - * - * @final - * @private - * @property _tabSuffix - * @type String - * @since 0.9.7 - **/ -var _tabSuffix = "-t-"; - -/** - * Suffix for the unique tabpanel id. - * - * @final - * @private - * @property _tabpanelSuffix - * @type String - * @since 0.9.7 - **/ -var _tabpanelSuffix = "-p-"; - -/** - * Suffix for the unique title id. - * - * @final - * @private - * @property _titleSuffix - * @type String - * @since 0.9.7 - **/ -var _titleSuffix = "-h-"; - -/** - * An error message for an "index out of range" error. - * - * @final - * @private - * @property _indexOutOfRangeErrorMessage - * @type String - **/ -var _indexOutOfRangeErrorMessage = "Index out of range."; - -/** - * An error message for an "missing corresponding element" error. - * - * @final - * @private - * @property _missingCorrespondingElementErrorMessage - * @type String - **/ -var _missingCorrespondingElementErrorMessage = "One or more corresponding step {0} are missing."; - -/** - * Adds a step to the cache. - * - * @static - * @private - * @method addStepToCache - * @param wizard {Object} A jQuery wizard object - * @param step {Object} The step object to add - **/ -function addStepToCache(wizard, step) -{ - getSteps(wizard).push(step); -} - -function analyzeData(wizard, options, state) -{ - var stepTitles = wizard.children(options.headerTag), - stepContents = wizard.children(options.bodyTag); - - // Validate content - if (stepTitles.length > stepContents.length) - { - throwError(_missingCorrespondingElementErrorMessage, "contents"); - } - else if (stepTitles.length < stepContents.length) - { - throwError(_missingCorrespondingElementErrorMessage, "titles"); - } - - var startIndex = options.startIndex; - - state.stepCount = stepTitles.length; - - // Tries to load the saved state (step position) - if (options.saveState && $.cookie) - { - var savedState = $.cookie(_cookiePrefix + getUniqueId(wizard)); - // Sets the saved position to the start index if not undefined or out of range - var savedIndex = parseInt(savedState, 0); - if (!isNaN(savedIndex) && savedIndex < state.stepCount) - { - startIndex = savedIndex; - } - } - - state.currentIndex = startIndex; - - stepTitles.each(function (index) - { - var item = $(this), // item == header - content = stepContents.eq(index), - modeData = content.data("mode"), - mode = (modeData == null) ? contentMode.html : getValidEnumValue(contentMode, - (/^\s*$/.test(modeData) || isNaN(modeData)) ? modeData : parseInt(modeData, 0)), - contentUrl = (mode === contentMode.html || content.data("url") === undefined) ? - "" : content.data("url"), - contentLoaded = (mode !== contentMode.html && content.data("loaded") === "1"), - step = $.extend({}, stepModel, { - title: item.html(), - content: (mode === contentMode.html) ? content.html() : "", - contentUrl: contentUrl, - contentMode: mode, - contentLoaded: contentLoaded - }); - - addStepToCache(wizard, step); - }); -} - -/** - * Triggers the onCanceled event. - * - * @static - * @private - * @method cancel - * @param wizard {Object} The jQuery wizard object - **/ -function cancel(wizard) -{ - wizard.triggerHandler("canceled"); -} - -function decreaseCurrentIndexBy(state, decreaseBy) -{ - return state.currentIndex - decreaseBy; -} - -/** - * Removes the control functionality completely and transforms the current state to the initial HTML structure. - * - * @static - * @private - * @method destroy - * @param wizard {Object} A jQuery wizard object - **/ -function destroy(wizard, options) -{ - var eventNamespace = getEventNamespace(wizard); - - // Remove virtual data objects from the wizard - wizard.unbind(eventNamespace).removeData("uid").removeData("options") - .removeData("state").removeData("steps").removeData("eventNamespace") - .find(".actions a").unbind(eventNamespace); - - // Remove attributes and CSS classes from the wizard - wizard.removeClass(options.clearFixCssClass + " vertical"); - - var contents = wizard.find(".content > *"); - - // Remove virtual data objects from panels and their titles - contents.removeData("loaded").removeData("mode").removeData("url"); - - // Remove attributes, CSS classes and reset inline styles on all panels and their titles - contents.removeAttr("id").removeAttr("role").removeAttr("tabindex") - .removeAttr("class").removeAttr("style")._removeAria("labelledby") - ._removeAria("hidden"); - - // Empty panels if the mode is set to 'async' or 'iframe' - wizard.find(".content > [data-mode='async'],.content > [data-mode='iframe']").empty(); - - var wizardSubstitute = $("<{0} class=\"{1}\">".format(wizard.get(0).tagName, wizard.attr("class"))); - - var wizardId = wizard._id(); - if (wizardId != null && wizardId !== "") - { - wizardSubstitute._id(wizardId); - } - - wizardSubstitute.html(wizard.find(".content").html()); - wizard.after(wizardSubstitute); - wizard.remove(); - - return wizardSubstitute; -} - -/** - * Triggers the onFinishing and onFinished event. - * - * @static - * @private - * @method finishStep - * @param wizard {Object} The jQuery wizard object - * @param state {Object} The state container of the current wizard - **/ -function finishStep(wizard, state) -{ - var currentStep = wizard.find(".steps li").eq(state.currentIndex); - - if (wizard.triggerHandler("finishing", [state.currentIndex])) - { - currentStep.addClass("done").removeClass("error"); - wizard.triggerHandler("finished", [state.currentIndex]); - } - else - { - currentStep.addClass("error"); - } -} - -/** - * Gets or creates if not exist an unique event namespace for the given wizard instance. - * - * @static - * @private - * @method getEventNamespace - * @param wizard {Object} A jQuery wizard object - * @return {String} Returns the unique event namespace for the given wizard - */ -function getEventNamespace(wizard) -{ - var eventNamespace = wizard.data("eventNamespace"); - - if (eventNamespace == null) - { - eventNamespace = "." + getUniqueId(wizard); - wizard.data("eventNamespace", eventNamespace); - } - - return eventNamespace; -} - -function getStepAnchor(wizard, index) -{ - var uniqueId = getUniqueId(wizard); - - return wizard.find("#" + uniqueId + _tabSuffix + index); -} - -function getStepPanel(wizard, index) -{ - var uniqueId = getUniqueId(wizard); - - return wizard.find("#" + uniqueId + _tabpanelSuffix + index); -} - -function getStepTitle(wizard, index) -{ - var uniqueId = getUniqueId(wizard); - - return wizard.find("#" + uniqueId + _titleSuffix + index); -} - -function getOptions(wizard) -{ - return wizard.data("options"); -} - -function getState(wizard) -{ - return wizard.data("state"); -} - -function getSteps(wizard) -{ - return wizard.data("steps"); -} - -/** - * Gets a specific step object by index. - * - * @static - * @private - * @method getStep - * @param index {Integer} An integer that belongs to the position of a step - * @return {Object} A specific step object - **/ -function getStep(wizard, index) -{ - var steps = getSteps(wizard); - - if (index < 0 || index >= steps.length) - { - throwError(_indexOutOfRangeErrorMessage); - } - - return steps[index]; -} - -/** - * Gets or creates if not exist an unique id from the given wizard instance. - * - * @static - * @private - * @method getUniqueId - * @param wizard {Object} A jQuery wizard object - * @return {String} Returns the unique id for the given wizard - */ -function getUniqueId(wizard) -{ - var uniqueId = wizard.data("uid"); - - if (uniqueId == null) - { - uniqueId = wizard._id(); - if (uniqueId == null) - { - uniqueId = "steps-uid-".concat(_uniqueId); - wizard._id(uniqueId); - } - - _uniqueId++; - wizard.data("uid", uniqueId); - } - - return uniqueId; -} - -/** - * Gets a valid enum value by checking a specific enum key or value. - * - * @static - * @private - * @method getValidEnumValue - * @param enumType {Object} Type of enum - * @param keyOrValue {Object} Key as `String` or value as `Integer` to check for - */ -function getValidEnumValue(enumType, keyOrValue) -{ - validateArgument("enumType", enumType); - validateArgument("keyOrValue", keyOrValue); - - // Is key - if (typeof keyOrValue === "string") - { - var value = enumType[keyOrValue]; - if (value === undefined) - { - throwError("The enum key '{0}' does not exist.", keyOrValue); - } - - return value; - } - // Is value - else if (typeof keyOrValue === "number") - { - for (var key in enumType) - { - if (enumType[key] === keyOrValue) - { - return keyOrValue; - } - } - - throwError("Invalid enum value '{0}'.", keyOrValue); - } - // Type is not supported - else - { - throwError("Invalid key or value type."); - } -} - -/** - * Routes to the next step. - * - * @static - * @private - * @method goToNextStep - * @param wizard {Object} The jQuery wizard object - * @param options {Object} Settings of the current wizard - * @param state {Object} The state container of the current wizard - * @return {Boolean} Indicates whether the action executed - **/ -function goToNextStep(wizard, options, state) -{ - return paginationClick(wizard, options, state, increaseCurrentIndexBy(state, 1)); -} - -/** - * Routes to the previous step. - * - * @static - * @private - * @method goToPreviousStep - * @param wizard {Object} The jQuery wizard object - * @param options {Object} Settings of the current wizard - * @param state {Object} The state container of the current wizard - * @return {Boolean} Indicates whether the action executed - **/ -function goToPreviousStep(wizard, options, state) -{ - return paginationClick(wizard, options, state, decreaseCurrentIndexBy(state, 1)); -} - -/** - * Routes to a specific step by a given index. - * - * @static - * @private - * @method goToStep - * @param wizard {Object} The jQuery wizard object - * @param options {Object} Settings of the current wizard - * @param state {Object} The state container of the current wizard - * @param index {Integer} The position (zero-based) to route to - * @return {Boolean} Indicates whether the action succeeded or failed - **/ -function goToStep(wizard, options, state, index) -{ - if (index < 0 || index >= state.stepCount) - { - throwError(_indexOutOfRangeErrorMessage); - } - - if (options.forceMoveForward && index < state.currentIndex) - { - return; - } - - var oldIndex = state.currentIndex; - if (wizard.triggerHandler("stepChanging", [state.currentIndex, index])) - { - // Save new state - state.currentIndex = index; - saveCurrentStateToCookie(wizard, options, state); - - // Change visualisation - refreshStepNavigation(wizard, options, state, oldIndex); - refreshPagination(wizard, options, state); - loadAsyncContent(wizard, options, state); - startTransitionEffect(wizard, options, state, index, oldIndex, function() - { - wizard.triggerHandler("stepChanged", [index, oldIndex]); - }); - } - else - { - wizard.find(".steps li").eq(oldIndex).addClass("error"); - } - - return true; -} - -function increaseCurrentIndexBy(state, increaseBy) -{ - return state.currentIndex + increaseBy; -} - -/** - * Initializes the component. - * - * @static - * @private - * @method initialize - * @param options {Object} The component settings - **/ -function initialize(options) -{ - /*jshint -W040 */ - var opts = $.extend(true, {}, defaults, options); - - return this.each(function () - { - var wizard = $(this); - var state = { - currentIndex: opts.startIndex, - currentStep: null, - stepCount: 0, - transitionElement: null - }; - - // Create data container - wizard.data("options", opts); - wizard.data("state", state); - wizard.data("steps", []); - - analyzeData(wizard, opts, state); - render(wizard, opts, state); - registerEvents(wizard, opts); - - // Trigger focus - if (opts.autoFocus && _uniqueId === 0) - { - getStepAnchor(wizard, opts.startIndex).focus(); - } - - wizard.triggerHandler("init", [opts.startIndex]); - }); -} - -/** - * Inserts a new step to a specific position. - * - * @static - * @private - * @method insertStep - * @param wizard {Object} The jQuery wizard object - * @param options {Object} Settings of the current wizard - * @param state {Object} The state container of the current wizard - * @param index {Integer} The position (zero-based) to add - * @param step {Object} The step object to add - * @example - * $("#wizard").steps().insert(0, { - * title: "Title", - * content: "", // optional - * contentMode: "async", // optional - * contentUrl: "/Content/Step/1" // optional - * }); - * @chainable - **/ -function insertStep(wizard, options, state, index, step) -{ - if (index < 0 || index > state.stepCount) - { - throwError(_indexOutOfRangeErrorMessage); - } - - // Change data - step = $.extend({}, stepModel, step); - insertStepToCache(wizard, index, step); - if (state.currentIndex !== state.stepCount && state.currentIndex >= index) - { - state.currentIndex++; - saveCurrentStateToCookie(wizard, options, state); - } - state.stepCount++; - - var contentContainer = wizard.find(".content"), - header = $("<{0}>{1}".format(options.headerTag, step.title)), - body = $("<{0}>".format(options.bodyTag)); - - if (step.contentMode == null || step.contentMode === contentMode.html) - { - body.html(step.content); - } - - if (index === 0) - { - contentContainer.prepend(body).prepend(header); - } - else - { - getStepPanel(wizard, (index - 1)).after(body).after(header); - } - - renderBody(wizard, state, body, index); - renderTitle(wizard, options, state, header, index); - refreshSteps(wizard, options, state, index); - if (index === state.currentIndex) - { - refreshStepNavigation(wizard, options, state); - } - refreshPagination(wizard, options, state); - - return wizard; -} - -/** - * Inserts a step object to the cache at a specific position. - * - * @static - * @private - * @method insertStepToCache - * @param wizard {Object} A jQuery wizard object - * @param index {Integer} The position (zero-based) to add - * @param step {Object} The step object to add - **/ -function insertStepToCache(wizard, index, step) -{ - getSteps(wizard).splice(index, 0, step); -} - -/** - * Handles the keyup DOM event for pagination. - * - * @static - * @private - * @event keyup - * @param event {Object} An event object - */ -function keyUpHandler(event) -{ - var wizard = $(this), - options = getOptions(wizard), - state = getState(wizard); - - if (options.suppressPaginationOnFocus && wizard.find(":focus").is(":input")) - { - event.preventDefault(); - return false; - } - - var keyCodes = { left: 37, right: 39 }; - if (event.keyCode === keyCodes.left) - { - event.preventDefault(); - goToPreviousStep(wizard, options, state); - } - else if (event.keyCode === keyCodes.right) - { - event.preventDefault(); - goToNextStep(wizard, options, state); - } -} - -/** - * Loads and includes async content. - * - * @static - * @private - * @method loadAsyncContent - * @param wizard {Object} A jQuery wizard object - * @param options {Object} Settings of the current wizard - * @param state {Object} The state container of the current wizard - */ -function loadAsyncContent(wizard, options, state) -{ - if (state.stepCount > 0) - { - var currentIndex = state.currentIndex, - currentStep = getStep(wizard, currentIndex); - - if (!options.enableContentCache || !currentStep.contentLoaded) - { - switch (getValidEnumValue(contentMode, currentStep.contentMode)) - { - case contentMode.iframe: - wizard.find(".content > .body").eq(state.currentIndex).empty() - .html("